From 1f2cf6771722f14a93227d3316e991742d982916 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 19 Mar 2014 21:25:19 -0700 Subject: [PATCH] 3.10-stable patches added patches: firewire-don-t-use-prepare_delayed_work.patch firewire-net-fix-use-after-free.patch tracing-do-not-add-event-files-for-modules-that-fail-tracepoints.patch --- ...ewire-don-t-use-prepare_delayed_work.patch | 187 ++++++++++++++++++ .../firewire-net-fix-use-after-free.patch | 45 +++++ queue-3.10/series | 3 + ...es-for-modules-that-fail-tracepoints.patch | 88 +++++++++ 4 files changed, 323 insertions(+) create mode 100644 queue-3.10/firewire-don-t-use-prepare_delayed_work.patch create mode 100644 queue-3.10/firewire-net-fix-use-after-free.patch create mode 100644 queue-3.10/tracing-do-not-add-event-files-for-modules-that-fail-tracepoints.patch diff --git a/queue-3.10/firewire-don-t-use-prepare_delayed_work.patch b/queue-3.10/firewire-don-t-use-prepare_delayed_work.patch new file mode 100644 index 00000000000..b0930fc109b --- /dev/null +++ b/queue-3.10/firewire-don-t-use-prepare_delayed_work.patch @@ -0,0 +1,187 @@ +From 70044d71d31d6973665ced5be04ef39ac1c09a48 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Fri, 7 Mar 2014 10:19:57 -0500 +Subject: firewire: don't use PREPARE_DELAYED_WORK + +From: Tejun Heo + +commit 70044d71d31d6973665ced5be04ef39ac1c09a48 upstream. + +PREPARE_[DELAYED_]WORK() are being phased out. They have few users +and a nasty surprise in terms of reentrancy guarantee as workqueue +considers work items to be different if they don't have the same work +function. + +firewire core-device and sbp2 have been been multiplexing work items +with multiple work functions. Introduce fw_device_workfn() and +sbp2_lu_workfn() which invoke fw_device->workfn and +sbp2_logical_unit->workfn respectively and always use the two +functions as the work functions and update the users to set the +->workfn fields instead of overriding work functions using +PREPARE_DELAYED_WORK(). + +This fixes a variety of possible regressions since a2c1c57be8d9 +"workqueue: consider work function when searching for busy work items" +due to which fw_workqueue lost its required non-reentrancy property. + +Signed-off-by: Tejun Heo +Acked-by: Stefan Richter +Cc: linux1394-devel@lists.sourceforge.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firewire/core-device.c | 22 +++++++++++++++------- + drivers/firewire/sbp2.c | 17 +++++++++++++---- + include/linux/firewire.h | 1 + + 3 files changed, 29 insertions(+), 11 deletions(-) + +--- a/drivers/firewire/core-device.c ++++ b/drivers/firewire/core-device.c +@@ -895,7 +895,7 @@ static int lookup_existing_device(struct + old->config_rom_retries = 0; + fw_notice(card, "rediscovered device %s\n", dev_name(dev)); + +- PREPARE_DELAYED_WORK(&old->work, fw_device_update); ++ old->workfn = fw_device_update; + fw_schedule_device_work(old, 0); + + if (current_node == card->root_node) +@@ -1054,7 +1054,7 @@ static void fw_device_init(struct work_s + if (atomic_cmpxchg(&device->state, + FW_DEVICE_INITIALIZING, + FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); ++ device->workfn = fw_device_shutdown; + fw_schedule_device_work(device, SHUTDOWN_DELAY); + } else { + fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n", +@@ -1175,13 +1175,20 @@ static void fw_device_refresh(struct wor + dev_name(&device->device), fw_rcode_string(ret)); + gone: + atomic_set(&device->state, FW_DEVICE_GONE); +- PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); ++ device->workfn = fw_device_shutdown; + fw_schedule_device_work(device, SHUTDOWN_DELAY); + out: + if (node_id == card->root_node->node_id) + fw_schedule_bm_work(card, 0); + } + ++static void fw_device_workfn(struct work_struct *work) ++{ ++ struct fw_device *device = container_of(to_delayed_work(work), ++ struct fw_device, work); ++ device->workfn(work); ++} ++ + void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + { + struct fw_device *device; +@@ -1231,7 +1238,8 @@ void fw_node_event(struct fw_card *card, + * power-up after getting plugged in. We schedule the + * first config rom scan half a second after bus reset. + */ +- INIT_DELAYED_WORK(&device->work, fw_device_init); ++ device->workfn = fw_device_init; ++ INIT_DELAYED_WORK(&device->work, fw_device_workfn); + fw_schedule_device_work(device, INITIAL_DELAY); + break; + +@@ -1247,7 +1255,7 @@ void fw_node_event(struct fw_card *card, + if (atomic_cmpxchg(&device->state, + FW_DEVICE_RUNNING, + FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); ++ device->workfn = fw_device_refresh; + fw_schedule_device_work(device, + device->is_local ? 0 : INITIAL_DELAY); + } +@@ -1262,7 +1270,7 @@ void fw_node_event(struct fw_card *card, + smp_wmb(); /* update node_id before generation */ + device->generation = card->generation; + if (atomic_read(&device->state) == FW_DEVICE_RUNNING) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_update); ++ device->workfn = fw_device_update; + fw_schedule_device_work(device, 0); + } + break; +@@ -1287,7 +1295,7 @@ void fw_node_event(struct fw_card *card, + device = node->data; + if (atomic_xchg(&device->state, + FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); ++ device->workfn = fw_device_shutdown; + fw_schedule_device_work(device, + list_empty(&card->link) ? 0 : SHUTDOWN_DELAY); + } +--- a/drivers/firewire/sbp2.c ++++ b/drivers/firewire/sbp2.c +@@ -146,6 +146,7 @@ struct sbp2_logical_unit { + */ + int generation; + int retries; ++ work_func_t workfn; + struct delayed_work work; + bool has_sdev; + bool blocked; +@@ -864,7 +865,7 @@ static void sbp2_login(struct work_struc + /* set appropriate retry limit(s) in BUSY_TIMEOUT register */ + sbp2_set_busy_timeout(lu); + +- PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); ++ lu->workfn = sbp2_reconnect; + sbp2_agent_reset(lu); + + /* This was a re-login. */ +@@ -918,7 +919,7 @@ static void sbp2_login(struct work_struc + * If a bus reset happened, sbp2_update will have requeued + * lu->work already. Reset the work from reconnect to login. + */ +- PREPARE_DELAYED_WORK(&lu->work, sbp2_login); ++ lu->workfn = sbp2_login; + } + + static void sbp2_reconnect(struct work_struct *work) +@@ -952,7 +953,7 @@ static void sbp2_reconnect(struct work_s + lu->retries++ >= 5) { + dev_err(tgt_dev(tgt), "failed to reconnect\n"); + lu->retries = 0; +- PREPARE_DELAYED_WORK(&lu->work, sbp2_login); ++ lu->workfn = sbp2_login; + } + sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); + +@@ -972,6 +973,13 @@ static void sbp2_reconnect(struct work_s + sbp2_conditionally_unblock(lu); + } + ++static void sbp2_lu_workfn(struct work_struct *work) ++{ ++ struct sbp2_logical_unit *lu = container_of(to_delayed_work(work), ++ struct sbp2_logical_unit, work); ++ lu->workfn(work); ++} ++ + static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) + { + struct sbp2_logical_unit *lu; +@@ -998,7 +1006,8 @@ static int sbp2_add_logical_unit(struct + lu->blocked = false; + ++tgt->dont_block; + INIT_LIST_HEAD(&lu->orb_list); +- INIT_DELAYED_WORK(&lu->work, sbp2_login); ++ lu->workfn = sbp2_login; ++ INIT_DELAYED_WORK(&lu->work, sbp2_lu_workfn); + + list_add_tail(&lu->link, &tgt->lu_list); + return 0; +--- a/include/linux/firewire.h ++++ b/include/linux/firewire.h +@@ -200,6 +200,7 @@ struct fw_device { + unsigned irmc:1; + unsigned bc_implemented:2; + ++ work_func_t workfn; + struct delayed_work work; + struct fw_attribute_group attribute_group; + }; diff --git a/queue-3.10/firewire-net-fix-use-after-free.patch b/queue-3.10/firewire-net-fix-use-after-free.patch new file mode 100644 index 00000000000..66114f75972 --- /dev/null +++ b/queue-3.10/firewire-net-fix-use-after-free.patch @@ -0,0 +1,45 @@ +From 8987583366ae9e03c306c2b7d73bdb952df1d08d Mon Sep 17 00:00:00 2001 +From: Stefan Richter +Date: Tue, 18 Feb 2014 22:25:15 +0100 +Subject: firewire: net: fix use after free + +From: Stefan Richter + +commit 8987583366ae9e03c306c2b7d73bdb952df1d08d upstream. + +Commit 8408dc1c14c1 "firewire: net: use dev_printk API" introduced a +use-after-free in a failure path. fwnet_transmit_packet_failed(ptask) +may free ptask, then the dev_err() call dereferenced it. The fix is +straightforward; simply reorder the two calls. + +Reported-by: Dan Carpenter +Signed-off-by: Stefan Richter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firewire/net.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/firewire/net.c ++++ b/drivers/firewire/net.c +@@ -929,8 +929,6 @@ static void fwnet_write_complete(struct + if (rcode == RCODE_COMPLETE) { + fwnet_transmit_packet_done(ptask); + } else { +- fwnet_transmit_packet_failed(ptask); +- + if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) { + dev_err(&ptask->dev->netdev->dev, + "fwnet_write_complete failed: %x (skipped %d)\n", +@@ -938,8 +936,10 @@ static void fwnet_write_complete(struct + + errors_skipped = 0; + last_rcode = rcode; +- } else ++ } else { + errors_skipped++; ++ } ++ fwnet_transmit_packet_failed(ptask); + } + } + diff --git a/queue-3.10/series b/queue-3.10/series index bec976a209f..4eaac711914 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -42,3 +42,6 @@ usb-make-delay_init-quirk-wait-100ms-between-get-configuration-requests.patch genirq-remove-racy-waitqueue_active-check.patch cpuset-fix-a-race-condition-in-__cpuset_node_allowed_softwall.patch acpi-resources-ignore-invalid-acpi-device-resources.patch +tracing-do-not-add-event-files-for-modules-that-fail-tracepoints.patch +firewire-net-fix-use-after-free.patch +firewire-don-t-use-prepare_delayed_work.patch diff --git a/queue-3.10/tracing-do-not-add-event-files-for-modules-that-fail-tracepoints.patch b/queue-3.10/tracing-do-not-add-event-files-for-modules-that-fail-tracepoints.patch new file mode 100644 index 00000000000..848e1929770 --- /dev/null +++ b/queue-3.10/tracing-do-not-add-event-files-for-modules-that-fail-tracepoints.patch @@ -0,0 +1,88 @@ +From 45ab2813d40d88fc575e753c38478de242d03f88 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Wed, 26 Feb 2014 13:37:38 -0500 +Subject: tracing: Do not add event files for modules that fail tracepoints + +From: "Steven Rostedt (Red Hat)" + +commit 45ab2813d40d88fc575e753c38478de242d03f88 upstream. + +If a module fails to add its tracepoints due to module tainting, do not +create the module event infrastructure in the debugfs directory. As the events +will not work and worse yet, they will silently fail, making the user wonder +why the events they enable do not display anything. + +Having a warning on module load and the events not visible to the users +will make the cause of the problem much clearer. + +Link: http://lkml.kernel.org/r/20140227154923.265882695@goodmis.org + +Fixes: 6d723736e472 "tracing/events: add support for modules to TRACE_EVENT" +Acked-by: Mathieu Desnoyers +Cc: Rusty Russell +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/tracepoint.h | 6 ++++++ + kernel/trace/trace_events.c | 10 ++++++++++ + kernel/tracepoint.c | 7 ++++++- + 3 files changed, 22 insertions(+), 1 deletion(-) + +--- a/include/linux/tracepoint.h ++++ b/include/linux/tracepoint.h +@@ -60,6 +60,12 @@ struct tp_module { + unsigned int num_tracepoints; + struct tracepoint * const *tracepoints_ptrs; + }; ++bool trace_module_has_bad_taint(struct module *mod); ++#else ++static inline bool trace_module_has_bad_taint(struct module *mod) ++{ ++ return false; ++} + #endif /* CONFIG_MODULES */ + + struct tracepoint_iter { +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -1860,6 +1860,16 @@ static void trace_module_add_events(stru + struct ftrace_module_file_ops *file_ops = NULL; + struct ftrace_event_call **call, **start, **end; + ++ if (!mod->num_trace_events) ++ return; ++ ++ /* Don't add infrastructure for mods without tracepoints */ ++ if (trace_module_has_bad_taint(mod)) { ++ pr_err("%s: module has bad taint, not creating trace events\n", ++ mod->name); ++ return; ++ } ++ + start = mod->trace_events; + end = mod->trace_events + mod->num_trace_events; + +--- a/kernel/tracepoint.c ++++ b/kernel/tracepoint.c +@@ -631,6 +631,11 @@ void tracepoint_iter_reset(struct tracep + EXPORT_SYMBOL_GPL(tracepoint_iter_reset); + + #ifdef CONFIG_MODULES ++bool trace_module_has_bad_taint(struct module *mod) ++{ ++ return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP)); ++} ++ + static int tracepoint_module_coming(struct module *mod) + { + struct tp_module *tp_mod, *iter; +@@ -641,7 +646,7 @@ static int tracepoint_module_coming(stru + * module headers (for forced load), to make sure we don't cause a crash. + * Staging and out-of-tree GPL modules are fine. + */ +- if (mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP))) ++ if (trace_module_has_bad_taint(mod)) + return 0; + mutex_lock(&tracepoints_mutex); + tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL); -- 2.47.3