From b42f33c17e67d643b830bcf177248f53c025d506 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 28 Jan 2023 10:28:25 +0100 Subject: [PATCH] 4.19-stable patches added patches: cifs-fix-oops-due-to-uncleared-server-smbd_conn-in-reconnect.patch module-don-t-wait-for-going-modules.patch trace_events_hist-add-check-for-return-value-of-create_hist_field.patch tracing-make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch --- ...leared-server-smbd_conn-in-reconnect.patch | 37 ++++++ .../module-don-t-wait-for-going-modules.patch | 111 ++++++++++++++++++ queue-4.19/series | 4 + ...or-return-value-of-create_hist_field.patch | 37 ++++++ ...can-output-as-soon-as-it-can-be-used.patch | 80 +++++++++++++ 5 files changed, 269 insertions(+) create mode 100644 queue-4.19/cifs-fix-oops-due-to-uncleared-server-smbd_conn-in-reconnect.patch create mode 100644 queue-4.19/module-don-t-wait-for-going-modules.patch create mode 100644 queue-4.19/trace_events_hist-add-check-for-return-value-of-create_hist_field.patch create mode 100644 queue-4.19/tracing-make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch diff --git a/queue-4.19/cifs-fix-oops-due-to-uncleared-server-smbd_conn-in-reconnect.patch b/queue-4.19/cifs-fix-oops-due-to-uncleared-server-smbd_conn-in-reconnect.patch new file mode 100644 index 00000000000..aa886ee4921 --- /dev/null +++ b/queue-4.19/cifs-fix-oops-due-to-uncleared-server-smbd_conn-in-reconnect.patch @@ -0,0 +1,37 @@ +From b7ab9161cf5ddc42a288edf9d1a61f3bdffe17c7 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 25 Jan 2023 14:02:13 +0000 +Subject: cifs: Fix oops due to uncleared server->smbd_conn in reconnect + +From: David Howells + +commit b7ab9161cf5ddc42a288edf9d1a61f3bdffe17c7 upstream. + +In smbd_destroy(), clear the server->smbd_conn pointer after freeing the +smbd_connection struct that it points to so that reconnection doesn't get +confused. + +Fixes: 8ef130f9ec27 ("CIFS: SMBD: Implement function to destroy a SMB Direct connection") +Cc: stable@vger.kernel.org +Reviewed-by: Paulo Alcantara (SUSE) +Acked-by: Tom Talpey +Signed-off-by: David Howells +Cc: Long Li +Cc: Pavel Shilovsky +Cc: Ronnie Sahlberg +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/smbdirect.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/cifs/smbdirect.c ++++ b/fs/cifs/smbdirect.c +@@ -1493,6 +1493,7 @@ void smbd_destroy(struct smbd_connection + destroy_workqueue(info->workqueue); + log_rdma_event(INFO, "rdma session destroyed\n"); + kfree(info); ++ server->smbd_conn = NULL; + } + + /* diff --git a/queue-4.19/module-don-t-wait-for-going-modules.patch b/queue-4.19/module-don-t-wait-for-going-modules.patch new file mode 100644 index 00000000000..c9355b82106 --- /dev/null +++ b/queue-4.19/module-don-t-wait-for-going-modules.patch @@ -0,0 +1,111 @@ +From 0254127ab977e70798707a7a2b757c9f3c971210 Mon Sep 17 00:00:00 2001 +From: Petr Pavlu +Date: Mon, 5 Dec 2022 11:35:57 +0100 +Subject: module: Don't wait for GOING modules + +From: Petr Pavlu + +commit 0254127ab977e70798707a7a2b757c9f3c971210 upstream. + +During a system boot, it can happen that the kernel receives a burst of +requests to insert the same module but loading it eventually fails +during its init call. For instance, udev can make a request to insert +a frequency module for each individual CPU when another frequency module +is already loaded which causes the init function of the new module to +return an error. + +Since commit 6e6de3dee51a ("kernel/module.c: Only return -EEXIST for +modules that have finished loading"), the kernel waits for modules in +MODULE_STATE_GOING state to finish unloading before making another +attempt to load the same module. + +This creates unnecessary work in the described scenario and delays the +boot. In the worst case, it can prevent udev from loading drivers for +other devices and might cause timeouts of services waiting on them and +subsequently a failed boot. + +This patch attempts a different solution for the problem 6e6de3dee51a +was trying to solve. Rather than waiting for the unloading to complete, +it returns a different error code (-EBUSY) for modules in the GOING +state. This should avoid the error situation that was described in +6e6de3dee51a (user space attempting to load a dependent module because +the -EEXIST error code would suggest to user space that the first module +had been loaded successfully), while avoiding the delay situation too. + +This has been tested on linux-next since December 2022 and passes +all kmod selftests except test 0009 with module compression enabled +but it has been confirmed that this issue has existed and has gone +unnoticed since prior to this commit and can also be reproduced without +module compression with a simple usleep(5000000) on tools/modprobe.c [0]. +These failures are caused by hitting the kernel mod_concurrent_max and can +happen either due to a self inflicted kernel module auto-loead DoS somehow +or on a system with large CPU count and each CPU count incorrectly triggering +many module auto-loads. Both of those issues need to be fixed in-kernel. + +[0] https://lore.kernel.org/all/Y9A4fiobL6IHp%2F%2FP@bombadil.infradead.org/ + +Fixes: 6e6de3dee51a ("kernel/module.c: Only return -EEXIST for modules that have finished loading") +Co-developed-by: Martin Wilck +Signed-off-by: Martin Wilck +Signed-off-by: Petr Pavlu +Cc: stable@vger.kernel.org +Reviewed-by: Petr Mladek +[mcgrof: enhance commit log with testing and kmod test result interpretation ] +Signed-off-by: Luis Chamberlain +Signed-off-by: Greg Kroah-Hartman +--- + kernel/module.c | 26 +++++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -3478,7 +3478,8 @@ static bool finished_loading(const char + sched_annotate_sleep(); + mutex_lock(&module_mutex); + mod = find_module_all(name, strlen(name), true); +- ret = !mod || mod->state == MODULE_STATE_LIVE; ++ ret = !mod || mod->state == MODULE_STATE_LIVE ++ || mod->state == MODULE_STATE_GOING; + mutex_unlock(&module_mutex); + + return ret; +@@ -3632,20 +3633,35 @@ static int add_unformed_module(struct mo + + mod->state = MODULE_STATE_UNFORMED; + +-again: + mutex_lock(&module_mutex); + old = find_module_all(mod->name, strlen(mod->name), true); + if (old != NULL) { +- if (old->state != MODULE_STATE_LIVE) { ++ if (old->state == MODULE_STATE_COMING ++ || old->state == MODULE_STATE_UNFORMED) { + /* Wait in case it fails to load. */ + mutex_unlock(&module_mutex); + err = wait_event_interruptible(module_wq, + finished_loading(mod->name)); + if (err) + goto out_unlocked; +- goto again; ++ ++ /* The module might have gone in the meantime. */ ++ mutex_lock(&module_mutex); ++ old = find_module_all(mod->name, strlen(mod->name), ++ true); + } +- err = -EEXIST; ++ ++ /* ++ * We are here only when the same module was being loaded. Do ++ * not try to load it again right now. It prevents long delays ++ * caused by serialized module load failures. It might happen ++ * when more devices of the same type trigger load of ++ * a particular module. ++ */ ++ if (old && old->state == MODULE_STATE_LIVE) ++ err = -EEXIST; ++ else ++ err = -EBUSY; + goto out; + } + mod_update_bounds(mod); diff --git a/queue-4.19/series b/queue-4.19/series index 18c21d4d16d..5dcd55c1224 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -40,3 +40,7 @@ perf-env-do-not-return-pointers-to-local-variables.patch fs-reiserfs-remove-useless-new_opts-in-reiserfs_remount.patch bluetooth-hci_sync-cancel-cmd_timer-if-hci_open-fail.patch scsi-hpsa-fix-allocation-size-for-scsi_host_alloc.patch +module-don-t-wait-for-going-modules.patch +tracing-make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch +trace_events_hist-add-check-for-return-value-of-create_hist_field.patch +cifs-fix-oops-due-to-uncleared-server-smbd_conn-in-reconnect.patch diff --git a/queue-4.19/trace_events_hist-add-check-for-return-value-of-create_hist_field.patch b/queue-4.19/trace_events_hist-add-check-for-return-value-of-create_hist_field.patch new file mode 100644 index 00000000000..b8cf1326a16 --- /dev/null +++ b/queue-4.19/trace_events_hist-add-check-for-return-value-of-create_hist_field.patch @@ -0,0 +1,37 @@ +From 8b152e9150d07a885f95e1fd401fc81af202d9a4 Mon Sep 17 00:00:00 2001 +From: Natalia Petrova +Date: Wed, 11 Jan 2023 15:04:09 +0300 +Subject: trace_events_hist: add check for return value of 'create_hist_field' + +From: Natalia Petrova + +commit 8b152e9150d07a885f95e1fd401fc81af202d9a4 upstream. + +Function 'create_hist_field' is called recursively at +trace_events_hist.c:1954 and can return NULL-value that's why we have +to check it to avoid null pointer dereference. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Link: https://lkml.kernel.org/r/20230111120409.4111-1-n.petrova@fintech.ru + +Cc: stable@vger.kernel.org +Fixes: 30350d65ac56 ("tracing: Add variable support to hist triggers") +Signed-off-by: Natalia Petrova +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace_events_hist.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/trace/trace_events_hist.c ++++ b/kernel/trace/trace_events_hist.c +@@ -2314,6 +2314,8 @@ static struct hist_field *create_hist_fi + unsigned long fl = flags & ~HIST_FIELD_FL_LOG2; + hist_field->fn = hist_field_log2; + hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL); ++ if (!hist_field->operands[0]) ++ goto free; + hist_field->size = hist_field->operands[0]->size; + hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL); + if (!hist_field->type) diff --git a/queue-4.19/tracing-make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch b/queue-4.19/tracing-make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch new file mode 100644 index 00000000000..5a443e12ac0 --- /dev/null +++ b/queue-4.19/tracing-make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch @@ -0,0 +1,80 @@ +From 3bb06eb6e9acf7c4a3e1b5bc87aed398ff8e2253 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Google)" +Date: Wed, 4 Jan 2023 16:14:12 -0500 +Subject: tracing: Make sure trace_printk() can output as soon as it can be used + +From: Steven Rostedt (Google) + +commit 3bb06eb6e9acf7c4a3e1b5bc87aed398ff8e2253 upstream. + +Currently trace_printk() can be used as soon as early_trace_init() is +called from start_kernel(). But if a crash happens, and +"ftrace_dump_on_oops" is set on the kernel command line, all you get will +be: + + [ 0.456075] -0 0dN.2. 347519us : Unknown type 6 + [ 0.456075] -0 0dN.2. 353141us : Unknown type 6 + [ 0.456075] -0 0dN.2. 358684us : Unknown type 6 + +This is because the trace_printk() event (type 6) hasn't been registered +yet. That gets done via an early_initcall(), which may be early, but not +early enough. + +Instead of registering the trace_printk() event (and other ftrace events, +which are not trace events) via an early_initcall(), have them registered at +the same time that trace_printk() can be used. This way, if there is a +crash before early_initcall(), then the trace_printk()s will actually be +useful. + +Link: https://lkml.kernel.org/r/20230104161412.019f6c55@gandalf.local.home + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Fixes: e725c731e3bb1 ("tracing: Split tracing initialization into two for early initialization") +Reported-by: "Joel Fernandes (Google)" +Tested-by: Joel Fernandes (Google) +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 2 ++ + kernel/trace/trace.h | 1 + + kernel/trace/trace_output.c | 3 +-- + 3 files changed, 4 insertions(+), 2 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -8674,6 +8674,8 @@ void __init early_trace_init(void) + static_key_enable(&tracepoint_printk_key.key); + } + tracer_alloc_buffers(); ++ ++ init_events(); + } + + void __init trace_init(void) +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -1530,6 +1530,7 @@ extern void trace_event_enable_cmd_recor + extern void trace_event_enable_tgid_record(bool enable); + + extern int event_trace_init(void); ++extern int init_events(void); + extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr); + extern int event_trace_del_tracer(struct trace_array *tr); + +--- a/kernel/trace/trace_output.c ++++ b/kernel/trace/trace_output.c +@@ -1395,7 +1395,7 @@ static struct trace_event *events[] __in + NULL + }; + +-__init static int init_events(void) ++__init int init_events(void) + { + struct trace_event *event; + int i, ret; +@@ -1413,4 +1413,3 @@ __init static int init_events(void) + + return 0; + } +-early_initcall(init_events); -- 2.47.2