From: Sasha Levin Date: Tue, 23 Jun 2020 14:07:48 +0000 (-0400) Subject: Fixes for 4.4 X-Git-Tag: v5.7.6~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4b9eee542a6fb4a9e5b5b3a775b7ca0a01082f92;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.4 Signed-off-by: Sasha Levin --- diff --git a/queue-4.4/e1000e-do-not-wake-up-the-system-via-wol-if-device-w.patch b/queue-4.4/e1000e-do-not-wake-up-the-system-via-wol-if-device-w.patch new file mode 100644 index 00000000000..afac8bad08b --- /dev/null +++ b/queue-4.4/e1000e-do-not-wake-up-the-system-via-wol-if-device-w.patch @@ -0,0 +1,70 @@ +From d3abe6f7ff2abf414484592d6f7de2766cac4d8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 May 2020 01:59:00 +0800 +Subject: e1000e: Do not wake up the system via WOL if device wakeup is + disabled + +From: Chen Yu + +[ Upstream commit 6bf6be1127f7e6d4bf39f84d56854e944d045d74 ] + +Currently the system will be woken up via WOL(Wake On LAN) even if the +device wakeup ability has been disabled via sysfs: + cat /sys/devices/pci0000:00/0000:00:1f.6/power/wakeup + disabled + +The system should not be woken up if the user has explicitly +disabled the wake up ability for this device. + +This patch clears the WOL ability of this network device if the +user has disabled the wake up ability in sysfs. + +Fixes: bc7f75fa9788 ("[E1000E]: New pci-express e1000 driver") +Reported-by: "Rafael J. Wysocki" +Reviewed-by: Andy Shevchenko +Cc: +Signed-off-by: Chen Yu +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/e1000e/netdev.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c +index 203f96faf6fbe..3bd0bdbdfa0e1 100644 +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -6270,11 +6270,17 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; +- u32 ctrl, ctrl_ext, rctl, status; +- /* Runtime suspend should only enable wakeup for link changes */ +- u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol; ++ u32 ctrl, ctrl_ext, rctl, status, wufc; + int retval = 0; + ++ /* Runtime suspend should only enable wakeup for link changes */ ++ if (runtime) ++ wufc = E1000_WUFC_LNKC; ++ else if (device_may_wakeup(&pdev->dev)) ++ wufc = adapter->wol; ++ else ++ wufc = 0; ++ + status = er32(STATUS); + if (status & E1000_STATUS_LU) + wufc &= ~E1000_WUFC_LNKC; +@@ -6332,7 +6338,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) + e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); + } else if ((hw->mac.type == e1000_pch_lpt) || + (hw->mac.type == e1000_pch_spt)) { +- if (!(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) ++ if (wufc && !(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) + /* ULP does not support wake from unicast, multicast + * or broadcast. + */ +-- +2.25.1 + diff --git a/queue-4.4/kprobes-fix-to-protect-kick_kprobe_optimizer-by-kpro.patch b/queue-4.4/kprobes-fix-to-protect-kick_kprobe_optimizer-by-kpro.patch new file mode 100644 index 00000000000..cb7bc24b018 --- /dev/null +++ b/queue-4.4/kprobes-fix-to-protect-kick_kprobe_optimizer-by-kpro.patch @@ -0,0 +1,57 @@ +From 5a031cda631854e439c05c3e603df4084593cabb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 May 2020 17:02:56 +0900 +Subject: kprobes: Fix to protect kick_kprobe_optimizer() by kprobe_mutex + +From: Masami Hiramatsu + +[ Upstream commit 1a0aa991a6274161c95a844c58cfb801d681eb59 ] + +In kprobe_optimizer() kick_kprobe_optimizer() is called +without kprobe_mutex, but this can race with other caller +which is protected by kprobe_mutex. + +To fix that, expand kprobe_mutex protected area to protect +kick_kprobe_optimizer() call. + +Link: http://lkml.kernel.org/r/158927057586.27680.5036330063955940456.stgit@devnote2 + +Fixes: cd7ebe2298ff ("kprobes: Use text_poke_smp_batch for optimizing") +Cc: Ingo Molnar +Cc: "Gustavo A . R . Silva" +Cc: Anders Roxell +Cc: "Naveen N . Rao" +Cc: Anil S Keshavamurthy +Cc: David Miller +Cc: Ingo Molnar +Cc: Peter Zijlstra +Cc: Ziqian SUN +Cc: stable@vger.kernel.org +Signed-off-by: Masami Hiramatsu +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Sasha Levin +--- + kernel/kprobes.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index f59f49bc2a5d5..430baa19e48c3 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -561,11 +561,12 @@ static void kprobe_optimizer(struct work_struct *work) + do_free_cleaned_kprobes(); + + mutex_unlock(&module_mutex); +- mutex_unlock(&kprobe_mutex); + + /* Step 5: Kick optimizer again if needed */ + if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) + kick_kprobe_optimizer(); ++ ++ mutex_unlock(&kprobe_mutex); + } + + /* Wait for completing optimization and unoptimization */ +-- +2.25.1 + diff --git a/queue-4.4/kretprobe-prevent-triggering-kretprobe-from-within-k.patch b/queue-4.4/kretprobe-prevent-triggering-kretprobe-from-within-k.patch new file mode 100644 index 00000000000..0d24fb5c88b --- /dev/null +++ b/queue-4.4/kretprobe-prevent-triggering-kretprobe-from-within-k.patch @@ -0,0 +1,246 @@ +From 6915c9865e95861b3b3d0f60265d0ca24d84f31e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 May 2020 17:03:18 +0900 +Subject: kretprobe: Prevent triggering kretprobe from within kprobe_flush_task + +From: Jiri Olsa + +[ Upstream commit 9b38cc704e844e41d9cf74e647bff1d249512cb3 ] + +Ziqian reported lockup when adding retprobe on _raw_spin_lock_irqsave. +My test was also able to trigger lockdep output: + + ============================================ + WARNING: possible recursive locking detected + 5.6.0-rc6+ #6 Not tainted + -------------------------------------------- + sched-messaging/2767 is trying to acquire lock: + ffffffff9a492798 (&(kretprobe_table_locks[i].lock)){-.-.}, at: kretprobe_hash_lock+0x52/0xa0 + + but task is already holding lock: + ffffffff9a491a18 (&(kretprobe_table_locks[i].lock)){-.-.}, at: kretprobe_trampoline+0x0/0x50 + + other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(&(kretprobe_table_locks[i].lock)); + lock(&(kretprobe_table_locks[i].lock)); + + *** DEADLOCK *** + + May be due to missing lock nesting notation + + 1 lock held by sched-messaging/2767: + #0: ffffffff9a491a18 (&(kretprobe_table_locks[i].lock)){-.-.}, at: kretprobe_trampoline+0x0/0x50 + + stack backtrace: + CPU: 3 PID: 2767 Comm: sched-messaging Not tainted 5.6.0-rc6+ #6 + Call Trace: + dump_stack+0x96/0xe0 + __lock_acquire.cold.57+0x173/0x2b7 + ? native_queued_spin_lock_slowpath+0x42b/0x9e0 + ? lockdep_hardirqs_on+0x590/0x590 + ? __lock_acquire+0xf63/0x4030 + lock_acquire+0x15a/0x3d0 + ? kretprobe_hash_lock+0x52/0xa0 + _raw_spin_lock_irqsave+0x36/0x70 + ? kretprobe_hash_lock+0x52/0xa0 + kretprobe_hash_lock+0x52/0xa0 + trampoline_handler+0xf8/0x940 + ? kprobe_fault_handler+0x380/0x380 + ? find_held_lock+0x3a/0x1c0 + kretprobe_trampoline+0x25/0x50 + ? lock_acquired+0x392/0xbc0 + ? _raw_spin_lock_irqsave+0x50/0x70 + ? __get_valid_kprobe+0x1f0/0x1f0 + ? _raw_spin_unlock_irqrestore+0x3b/0x40 + ? finish_task_switch+0x4b9/0x6d0 + ? __switch_to_asm+0x34/0x70 + ? __switch_to_asm+0x40/0x70 + +The code within the kretprobe handler checks for probe reentrancy, +so we won't trigger any _raw_spin_lock_irqsave probe in there. + +The problem is in outside kprobe_flush_task, where we call: + + kprobe_flush_task + kretprobe_table_lock + raw_spin_lock_irqsave + _raw_spin_lock_irqsave + +where _raw_spin_lock_irqsave triggers the kretprobe and installs +kretprobe_trampoline handler on _raw_spin_lock_irqsave return. + +The kretprobe_trampoline handler is then executed with already +locked kretprobe_table_locks, and first thing it does is to +lock kretprobe_table_locks ;-) the whole lockup path like: + + kprobe_flush_task + kretprobe_table_lock + raw_spin_lock_irqsave + _raw_spin_lock_irqsave ---> probe triggered, kretprobe_trampoline installed + + ---> kretprobe_table_locks locked + + kretprobe_trampoline + trampoline_handler + kretprobe_hash_lock(current, &head, &flags); <--- deadlock + +Adding kprobe_busy_begin/end helpers that mark code with fake +probe installed to prevent triggering of another kprobe within +this code. + +Using these helpers in kprobe_flush_task, so the probe recursion +protection check is hit and the probe is never set to prevent +above lockup. + +Link: http://lkml.kernel.org/r/158927059835.27680.7011202830041561604.stgit@devnote2 + +Fixes: ef53d9c5e4da ("kprobes: improve kretprobe scalability with hashed locking") +Cc: Ingo Molnar +Cc: "Gustavo A . R . Silva" +Cc: Anders Roxell +Cc: "Naveen N . Rao" +Cc: Anil S Keshavamurthy +Cc: David Miller +Cc: Ingo Molnar +Cc: Peter Zijlstra +Cc: stable@vger.kernel.org +Reported-by: "Ziqian SUN (Zamir)" +Acked-by: Masami Hiramatsu +Signed-off-by: Jiri Olsa +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/kprobes/core.c | 16 +++------------- + include/linux/kprobes.h | 4 ++++ + kernel/kprobes.c | 24 ++++++++++++++++++++++++ + 3 files changed, 31 insertions(+), 13 deletions(-) + +diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c +index 7d2e2e40bbba3..5a6cb30b1c621 100644 +--- a/arch/x86/kernel/kprobes/core.c ++++ b/arch/x86/kernel/kprobes/core.c +@@ -736,16 +736,11 @@ static void __used kretprobe_trampoline_holder(void) + NOKPROBE_SYMBOL(kretprobe_trampoline_holder); + NOKPROBE_SYMBOL(kretprobe_trampoline); + +-static struct kprobe kretprobe_kprobe = { +- .addr = (void *)kretprobe_trampoline, +-}; +- + /* + * Called from kretprobe_trampoline + */ + __visible __used void *trampoline_handler(struct pt_regs *regs) + { +- struct kprobe_ctlblk *kcb; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head, empty_rp; + struct hlist_node *tmp; +@@ -755,16 +750,12 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) + void *frame_pointer; + bool skipped = false; + +- preempt_disable(); +- + /* + * Set a dummy kprobe for avoiding kretprobe recursion. + * Since kretprobe never run in kprobe handler, kprobe must not + * be running at this point. + */ +- kcb = get_kprobe_ctlblk(); +- __this_cpu_write(current_kprobe, &kretprobe_kprobe); +- kcb->kprobe_status = KPROBE_HIT_ACTIVE; ++ kprobe_busy_begin(); + + INIT_HLIST_HEAD(&empty_rp); + kretprobe_hash_lock(current, &head, &flags); +@@ -843,7 +834,7 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) + __this_cpu_write(current_kprobe, &ri->rp->kp); + ri->ret_addr = correct_ret_addr; + ri->rp->handler(ri, regs); +- __this_cpu_write(current_kprobe, &kretprobe_kprobe); ++ __this_cpu_write(current_kprobe, &kprobe_busy); + } + + recycle_rp_inst(ri, &empty_rp); +@@ -859,8 +850,7 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) + + kretprobe_hash_unlock(current, &flags); + +- __this_cpu_write(current_kprobe, NULL); +- preempt_enable(); ++ kprobe_busy_end(); + + hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); +diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h +index cb527c78de9fd..4db62045f01ae 100644 +--- a/include/linux/kprobes.h ++++ b/include/linux/kprobes.h +@@ -366,6 +366,10 @@ static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void) + return this_cpu_ptr(&kprobe_ctlblk); + } + ++extern struct kprobe kprobe_busy; ++void kprobe_busy_begin(void); ++void kprobe_busy_end(void); ++ + int register_kprobe(struct kprobe *p); + void unregister_kprobe(struct kprobe *p); + int register_kprobes(struct kprobe **kps, int num); +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index 430baa19e48c3..5bda113a3116c 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1150,6 +1150,26 @@ __releases(hlist_lock) + } + NOKPROBE_SYMBOL(kretprobe_table_unlock); + ++struct kprobe kprobe_busy = { ++ .addr = (void *) get_kprobe, ++}; ++ ++void kprobe_busy_begin(void) ++{ ++ struct kprobe_ctlblk *kcb; ++ ++ preempt_disable(); ++ __this_cpu_write(current_kprobe, &kprobe_busy); ++ kcb = get_kprobe_ctlblk(); ++ kcb->kprobe_status = KPROBE_HIT_ACTIVE; ++} ++ ++void kprobe_busy_end(void) ++{ ++ __this_cpu_write(current_kprobe, NULL); ++ preempt_enable(); ++} ++ + /* + * This function is called from finish_task_switch when task tk becomes dead, + * so that we can recycle any function-return probe instances associated +@@ -1167,6 +1187,8 @@ void kprobe_flush_task(struct task_struct *tk) + /* Early boot. kretprobe_table_locks not yet initialized. */ + return; + ++ kprobe_busy_begin(); ++ + INIT_HLIST_HEAD(&empty_rp); + hash = hash_ptr(tk, KPROBE_HASH_BITS); + head = &kretprobe_inst_table[hash]; +@@ -1180,6 +1202,8 @@ void kprobe_flush_task(struct task_struct *tk) + hlist_del(&ri->hlist); + kfree(ri); + } ++ ++ kprobe_busy_end(); + } + NOKPROBE_SYMBOL(kprobe_flush_task); + +-- +2.25.1 + diff --git a/queue-4.4/net-core-device_rename-use-rwsem-instead-of-a-seqcou.patch b/queue-4.4/net-core-device_rename-use-rwsem-instead-of-a-seqcou.patch new file mode 100644 index 00000000000..cf806ccc04a --- /dev/null +++ b/queue-4.4/net-core-device_rename-use-rwsem-instead-of-a-seqcou.patch @@ -0,0 +1,160 @@ +From e1bcdbb5e0bb6521f81f9180e5f2ed800523efac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Jun 2020 16:49:44 +0200 +Subject: net: core: device_rename: Use rwsem instead of a seqcount + +From: Ahmed S. Darwish + +[ Upstream commit 11d6011c2cf29f7c8181ebde6c8bc0c4d83adcd7 ] + +Sequence counters write paths are critical sections that must never be +preempted, and blocking, even for CONFIG_PREEMPTION=n, is not allowed. + +Commit 5dbe7c178d3f ("net: fix kernel deadlock with interface rename and +netdev name retrieval.") handled a deadlock, observed with +CONFIG_PREEMPTION=n, where the devnet_rename seqcount read side was +infinitely spinning: it got scheduled after the seqcount write side +blocked inside its own critical section. + +To fix that deadlock, among other issues, the commit added a +cond_resched() inside the read side section. While this will get the +non-preemptible kernel eventually unstuck, the seqcount reader is fully +exhausting its slice just spinning -- until TIF_NEED_RESCHED is set. + +The fix is also still broken: if the seqcount reader belongs to a +real-time scheduling policy, it can spin forever and the kernel will +livelock. + +Disabling preemption over the seqcount write side critical section will +not work: inside it are a number of GFP_KERNEL allocations and mutex +locking through the drivers/base/ :: device_rename() call chain. + +>From all the above, replace the seqcount with a rwsem. + +Fixes: 5dbe7c178d3f (net: fix kernel deadlock with interface rename and netdev name retrieval.) +Fixes: 30e6c9fa93cf (net: devnet_rename_seq should be a seqcount) +Fixes: c91f6df2db49 (sockopt: Change getsockopt() of SO_BINDTODEVICE to return an interface name) +Cc: +Reported-by: kbuild test robot [ v1 missing up_read() on error exit ] +Reported-by: Dan Carpenter [ v1 missing up_read() on error exit ] +Signed-off-by: Ahmed S. Darwish +Reviewed-by: Sebastian Andrzej Siewior +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 40 ++++++++++++++++++---------------------- + 1 file changed, 18 insertions(+), 22 deletions(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 775c8dfeff848..82f9ec1bd94b6 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -82,6 +82,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -185,7 +186,7 @@ static DEFINE_SPINLOCK(napi_hash_lock); + static unsigned int napi_gen_id = NR_CPUS; + static DEFINE_HASHTABLE(napi_hash, 8); + +-static seqcount_t devnet_rename_seq; ++static DECLARE_RWSEM(devnet_rename_sem); + + static inline void dev_base_seq_inc(struct net *net) + { +@@ -862,33 +863,28 @@ EXPORT_SYMBOL(dev_get_by_index); + * @net: network namespace + * @name: a pointer to the buffer where the name will be stored. + * @ifindex: the ifindex of the interface to get the name from. +- * +- * The use of raw_seqcount_begin() and cond_resched() before +- * retrying is required as we want to give the writers a chance +- * to complete when CONFIG_PREEMPTION is not set. + */ + int netdev_get_name(struct net *net, char *name, int ifindex) + { + struct net_device *dev; +- unsigned int seq; ++ int ret; + +-retry: +- seq = raw_seqcount_begin(&devnet_rename_seq); ++ down_read(&devnet_rename_sem); + rcu_read_lock(); ++ + dev = dev_get_by_index_rcu(net, ifindex); + if (!dev) { +- rcu_read_unlock(); +- return -ENODEV; ++ ret = -ENODEV; ++ goto out; + } + + strcpy(name, dev->name); +- rcu_read_unlock(); +- if (read_seqcount_retry(&devnet_rename_seq, seq)) { +- cond_resched(); +- goto retry; +- } + +- return 0; ++ ret = 0; ++out: ++ rcu_read_unlock(); ++ up_read(&devnet_rename_sem); ++ return ret; + } + + /** +@@ -1153,10 +1149,10 @@ int dev_change_name(struct net_device *dev, const char *newname) + if (dev->flags & IFF_UP) + return -EBUSY; + +- write_seqcount_begin(&devnet_rename_seq); ++ down_write(&devnet_rename_sem); + + if (strncmp(newname, dev->name, IFNAMSIZ) == 0) { +- write_seqcount_end(&devnet_rename_seq); ++ up_write(&devnet_rename_sem); + return 0; + } + +@@ -1164,7 +1160,7 @@ int dev_change_name(struct net_device *dev, const char *newname) + + err = dev_get_valid_name(net, dev, newname); + if (err < 0) { +- write_seqcount_end(&devnet_rename_seq); ++ up_write(&devnet_rename_sem); + return err; + } + +@@ -1179,11 +1175,11 @@ rollback: + if (ret) { + memcpy(dev->name, oldname, IFNAMSIZ); + dev->name_assign_type = old_assign_type; +- write_seqcount_end(&devnet_rename_seq); ++ up_write(&devnet_rename_sem); + return ret; + } + +- write_seqcount_end(&devnet_rename_seq); ++ up_write(&devnet_rename_sem); + + netdev_adjacent_rename_links(dev, oldname); + +@@ -1204,7 +1200,7 @@ rollback: + /* err >= 0 after dev_alloc_name() or stores the first errno */ + if (err >= 0) { + err = ret; +- write_seqcount_begin(&devnet_rename_seq); ++ down_write(&devnet_rename_sem); + memcpy(dev->name, oldname, IFNAMSIZ); + memcpy(oldname, newname, IFNAMSIZ); + dev->name_assign_type = old_assign_type; +-- +2.25.1 + diff --git a/queue-4.4/powerpc-kprobes-fixes-for-kprobe_lookup_name-on-be.patch b/queue-4.4/powerpc-kprobes-fixes-for-kprobe_lookup_name-on-be.patch new file mode 100644 index 00000000000..7c6789e7124 --- /dev/null +++ b/queue-4.4/powerpc-kprobes-fixes-for-kprobe_lookup_name-on-be.patch @@ -0,0 +1,50 @@ +From 4e724c82d78bc4f56dd27f09768cc0189abb69c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Feb 2017 14:27:31 +0530 +Subject: powerpc/kprobes: Fixes for kprobe_lookup_name() on BE + +From: Naveen N. Rao + +[ Upstream commit 30176466e36aadba01e1a630cf42397a3438efa4 ] + +Fix two issues with kprobes.h on BE which were exposed with the +optprobes work: + - one, having to do with a missing include for linux/module.h for + MODULE_NAME_LEN -- this didn't show up previously since the only + users of kprobe_lookup_name were in kprobes.c, which included + linux/module.h through other headers, and + - two, with a missing const qualifier for a local variable which ends + up referring a string literal. Again, this is unique to how + kprobe_lookup_name is being invoked in optprobes.c + +Signed-off-by: Naveen N. Rao +Signed-off-by: Michael Ellerman +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/kprobes.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h +index 039b583db0292..f0717eedf781c 100644 +--- a/arch/powerpc/include/asm/kprobes.h ++++ b/arch/powerpc/include/asm/kprobes.h +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -61,7 +62,7 @@ typedef ppc_opcode_t kprobe_opcode_t; + #define kprobe_lookup_name(name, addr) \ + { \ + char dot_name[MODULE_NAME_LEN + 1 + KSYM_NAME_LEN]; \ +- char *modsym; \ ++ const char *modsym; \ + bool dot_appended = false; \ + if ((modsym = strchr(name, ':')) != NULL) { \ + modsym++; \ +-- +2.25.1 + diff --git a/queue-4.4/sched-rt-net-use-config_preemption.patch.patch b/queue-4.4/sched-rt-net-use-config_preemption.patch.patch new file mode 100644 index 00000000000..5c25001d64b --- /dev/null +++ b/queue-4.4/sched-rt-net-use-config_preemption.patch.patch @@ -0,0 +1,45 @@ +From c9bc61dc41feda4e6497e03216eb2daf9adb424f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Oct 2019 21:18:08 +0200 +Subject: sched/rt, net: Use CONFIG_PREEMPTION.patch + +From: Thomas Gleixner + +[ Upstream commit 2da2b32fd9346009e9acdb68c570ca8d3966aba7 ] + +CONFIG_PREEMPTION is selected by CONFIG_PREEMPT and by CONFIG_PREEMPT_RT. +Both PREEMPT and PREEMPT_RT require the same functionality which today +depends on CONFIG_PREEMPT. + +Update the comment to use CONFIG_PREEMPTION. + +Signed-off-by: Thomas Gleixner +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Thomas Gleixner +Acked-by: David S. Miller +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: netdev@vger.kernel.org +Link: https://lore.kernel.org/r/20191015191821.11479-22-bigeasy@linutronix.de +Signed-off-by: Ingo Molnar +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 38e4977eb09d7..775c8dfeff848 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -865,7 +865,7 @@ EXPORT_SYMBOL(dev_get_by_index); + * + * The use of raw_seqcount_begin() and cond_resched() before + * retrying is required as we want to give the writers a chance +- * to complete when CONFIG_PREEMPT is not set. ++ * to complete when CONFIG_PREEMPTION is not set. + */ + int netdev_get_name(struct net *net, char *name, int ifindex) + { +-- +2.25.1 + diff --git a/queue-4.4/series b/queue-4.4/series index 415316afb8e..aad52fdc1c8 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -69,3 +69,10 @@ drm-dp_mst-increase-act-retry-timeout-to-3s.patch sparc64-fix-misuses-of-access_process_vm-in-genregs3.patch block-nr_sects_write-disable-preemption-on-seqcount-.patch crypto-algboss-don-t-wait-during-notifier-callback.patch +kprobes-fix-to-protect-kick_kprobe_optimizer-by-kpro.patch +powerpc-kprobes-fixes-for-kprobe_lookup_name-on-be.patch +x86-kprobes-avoid-kretprobe-recursion-bug.patch +kretprobe-prevent-triggering-kretprobe-from-within-k.patch +e1000e-do-not-wake-up-the-system-via-wol-if-device-w.patch +sched-rt-net-use-config_preemption.patch.patch +net-core-device_rename-use-rwsem-instead-of-a-seqcou.patch diff --git a/queue-4.4/x86-kprobes-avoid-kretprobe-recursion-bug.patch b/queue-4.4/x86-kprobes-avoid-kretprobe-recursion-bug.patch new file mode 100644 index 00000000000..2e101dbf079 --- /dev/null +++ b/queue-4.4/x86-kprobes-avoid-kretprobe-recursion-bug.patch @@ -0,0 +1,111 @@ +From 7d03b3b2abd233748b8feca5a02fa3968c32e019 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Feb 2019 01:50:49 +0900 +Subject: x86/kprobes: Avoid kretprobe recursion bug + +From: Masami Hiramatsu + +[ Upstream commit b191fa96ea6dc00d331dcc28c1f7db5e075693a0 ] + +Avoid kretprobe recursion loop bg by setting a dummy +kprobes to current_kprobe per-CPU variable. + +This bug has been introduced with the asm-coded trampoline +code, since previously it used another kprobe for hooking +the function return placeholder (which only has a nop) and +trampoline handler was called from that kprobe. + +This revives the old lost kprobe again. + +With this fix, we don't see deadlock anymore. + +And you can see that all inner-called kretprobe are skipped. + + event_1 235 0 + event_2 19375 19612 + +The 1st column is recorded count and the 2nd is missed count. +Above shows (event_1 rec) + (event_2 rec) ~= (event_2 missed) +(some difference are here because the counter is racy) + +Reported-by: Andrea Righi +Tested-by: Andrea Righi +Signed-off-by: Masami Hiramatsu +Acked-by: Steven Rostedt +Cc: Linus Torvalds +Cc: Mathieu Desnoyers +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: stable@vger.kernel.org +Fixes: c9becf58d935 ("[PATCH] kretprobe: kretprobe-booster") +Link: http://lkml.kernel.org/r/155094064889.6137.972160690963039.stgit@devbox +Signed-off-by: Ingo Molnar +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/kprobes/core.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c +index 7c48aa03fe77a..7d2e2e40bbba3 100644 +--- a/arch/x86/kernel/kprobes/core.c ++++ b/arch/x86/kernel/kprobes/core.c +@@ -736,11 +736,16 @@ static void __used kretprobe_trampoline_holder(void) + NOKPROBE_SYMBOL(kretprobe_trampoline_holder); + NOKPROBE_SYMBOL(kretprobe_trampoline); + ++static struct kprobe kretprobe_kprobe = { ++ .addr = (void *)kretprobe_trampoline, ++}; ++ + /* + * Called from kretprobe_trampoline + */ + __visible __used void *trampoline_handler(struct pt_regs *regs) + { ++ struct kprobe_ctlblk *kcb; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head, empty_rp; + struct hlist_node *tmp; +@@ -750,6 +755,17 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) + void *frame_pointer; + bool skipped = false; + ++ preempt_disable(); ++ ++ /* ++ * Set a dummy kprobe for avoiding kretprobe recursion. ++ * Since kretprobe never run in kprobe handler, kprobe must not ++ * be running at this point. ++ */ ++ kcb = get_kprobe_ctlblk(); ++ __this_cpu_write(current_kprobe, &kretprobe_kprobe); ++ kcb->kprobe_status = KPROBE_HIT_ACTIVE; ++ + INIT_HLIST_HEAD(&empty_rp); + kretprobe_hash_lock(current, &head, &flags); + /* fixup registers */ +@@ -825,10 +841,9 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) + orig_ret_address = (unsigned long)ri->ret_addr; + if (ri->rp && ri->rp->handler) { + __this_cpu_write(current_kprobe, &ri->rp->kp); +- get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; + ri->ret_addr = correct_ret_addr; + ri->rp->handler(ri, regs); +- __this_cpu_write(current_kprobe, NULL); ++ __this_cpu_write(current_kprobe, &kretprobe_kprobe); + } + + recycle_rp_inst(ri, &empty_rp); +@@ -844,6 +859,9 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) + + kretprobe_hash_unlock(current, &flags); + ++ __this_cpu_write(current_kprobe, NULL); ++ preempt_enable(); ++ + hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); + kfree(ri); +-- +2.25.1 +