From: Greg Kroah-Hartman Date: Mon, 12 Aug 2024 11:31:26 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v6.1.105~79 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a8ead094a90d6dcca352bbbf065b4cdb75f47980;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: driver-core-fix-uevent_show-vs-driver-detach-race.patch ntp-safeguard-against-time_constant-overflow.patch --- diff --git a/queue-6.1/driver-core-fix-uevent_show-vs-driver-detach-race.patch b/queue-6.1/driver-core-fix-uevent_show-vs-driver-detach-race.patch new file mode 100644 index 00000000000..207db03fc91 --- /dev/null +++ b/queue-6.1/driver-core-fix-uevent_show-vs-driver-detach-race.patch @@ -0,0 +1,157 @@ +From 15fffc6a5624b13b428bb1c6e9088e32a55eb82c Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Fri, 12 Jul 2024 12:42:09 -0700 +Subject: driver core: Fix uevent_show() vs driver detach race + +From: Dan Williams + +commit 15fffc6a5624b13b428bb1c6e9088e32a55eb82c upstream. + +uevent_show() wants to de-reference dev->driver->name. There is no clean +way for a device attribute to de-reference dev->driver unless that +attribute is defined via (struct device_driver).dev_groups. Instead, the +anti-pattern of taking the device_lock() in the attribute handler risks +deadlocks with code paths that remove device attributes while holding +the lock. + +This deadlock is typically invisible to lockdep given the device_lock() +is marked lockdep_set_novalidate_class(), but some subsystems allocate a +local lockdep key for @dev->mutex to reveal reports of the form: + + ====================================================== + WARNING: possible circular locking dependency detected + 6.10.0-rc7+ #275 Tainted: G OE N + ------------------------------------------------------ + modprobe/2374 is trying to acquire lock: + ffff8c2270070de0 (kn->active#6){++++}-{0:0}, at: __kernfs_remove+0xde/0x220 + + but task is already holding lock: + ffff8c22016e88f8 (&cxl_root_key){+.+.}-{3:3}, at: device_release_driver_internal+0x39/0x210 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #1 (&cxl_root_key){+.+.}-{3:3}: + __mutex_lock+0x99/0xc30 + uevent_show+0xac/0x130 + dev_attr_show+0x18/0x40 + sysfs_kf_seq_show+0xac/0xf0 + seq_read_iter+0x110/0x450 + vfs_read+0x25b/0x340 + ksys_read+0x67/0xf0 + do_syscall_64+0x75/0x190 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + + -> #0 (kn->active#6){++++}-{0:0}: + __lock_acquire+0x121a/0x1fa0 + lock_acquire+0xd6/0x2e0 + kernfs_drain+0x1e9/0x200 + __kernfs_remove+0xde/0x220 + kernfs_remove_by_name_ns+0x5e/0xa0 + device_del+0x168/0x410 + device_unregister+0x13/0x60 + devres_release_all+0xb8/0x110 + device_unbind_cleanup+0xe/0x70 + device_release_driver_internal+0x1c7/0x210 + driver_detach+0x47/0x90 + bus_remove_driver+0x6c/0xf0 + cxl_acpi_exit+0xc/0x11 [cxl_acpi] + __do_sys_delete_module.isra.0+0x181/0x260 + do_syscall_64+0x75/0x190 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +The observation though is that driver objects are typically much longer +lived than device objects. It is reasonable to perform lockless +de-reference of a @driver pointer even if it is racing detach from a +device. Given the infrequency of driver unregistration, use +synchronize_rcu() in module_remove_driver() to close any potential +races. It is potentially overkill to suffer synchronize_rcu() just to +handle the rare module removal racing uevent_show() event. + +Thanks to Tetsuo Handa for the debug analysis of the syzbot report [1]. + +Fixes: c0a40097f0bc ("drivers: core: synchronize really_probe() and dev_uevent()") +Reported-by: syzbot+4762dd74e32532cda5ff@syzkaller.appspotmail.com +Reported-by: Tetsuo Handa +Closes: http://lore.kernel.org/5aa5558f-90a4-4864-b1b1-5d6784c5607d@I-love.SAKURA.ne.jp [1] +Link: http://lore.kernel.org/669073b8ea479_5fffa294c1@dwillia2-xfh.jf.intel.com.notmuch +Cc: stable@vger.kernel.org +Cc: Ashish Sangwan +Cc: Namjae Jeon +Cc: Dirk Behme +Cc: Greg Kroah-Hartman +Cc: Rafael J. Wysocki +Signed-off-by: Dan Williams +Link: https://lore.kernel.org/r/172081332794.577428.9738802016494057132.stgit@dwillia2-xfh.jf.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/core.c | 13 ++++++++----- + drivers/base/module.c | 4 ++++ + 2 files changed, 12 insertions(+), 5 deletions(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2558,6 +2559,7 @@ static const char *dev_uevent_name(struc + static int dev_uevent(struct kobject *kobj, struct kobj_uevent_env *env) + { + struct device *dev = kobj_to_dev(kobj); ++ struct device_driver *driver; + int retval = 0; + + /* add device node properties if present */ +@@ -2586,8 +2588,12 @@ static int dev_uevent(struct kobject *ko + if (dev->type && dev->type->name) + add_uevent_var(env, "DEVTYPE=%s", dev->type->name); + +- if (dev->driver) +- add_uevent_var(env, "DRIVER=%s", dev->driver->name); ++ /* Synchronize with module_remove_driver() */ ++ rcu_read_lock(); ++ driver = READ_ONCE(dev->driver); ++ if (driver) ++ add_uevent_var(env, "DRIVER=%s", driver->name); ++ rcu_read_unlock(); + + /* Add common DT information about the device */ + of_device_uevent(dev, env); +@@ -2657,11 +2663,8 @@ static ssize_t uevent_show(struct device + if (!env) + return -ENOMEM; + +- /* Synchronize with really_probe() */ +- device_lock(dev); + /* let the kset specific function add its keys */ + retval = kset->uevent_ops->uevent(&dev->kobj, env); +- device_unlock(dev); + if (retval) + goto out; + +--- a/drivers/base/module.c ++++ b/drivers/base/module.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include "base.h" + + static char *make_driver_name(struct device_driver *drv) +@@ -77,6 +78,9 @@ void module_remove_driver(struct device_ + if (!drv) + return; + ++ /* Synchronize with dev_uevent() */ ++ synchronize_rcu(); ++ + sysfs_remove_link(&drv->p->kobj, "module"); + + if (drv->owner) diff --git a/queue-6.1/ntp-safeguard-against-time_constant-overflow.patch b/queue-6.1/ntp-safeguard-against-time_constant-overflow.patch new file mode 100644 index 00000000000..548c04661fe --- /dev/null +++ b/queue-6.1/ntp-safeguard-against-time_constant-overflow.patch @@ -0,0 +1,64 @@ +From 06c03c8edce333b9ad9c6b207d93d3a5ae7c10c0 Mon Sep 17 00:00:00 2001 +From: Justin Stitt +Date: Fri, 17 May 2024 00:47:10 +0000 +Subject: ntp: Safeguard against time_constant overflow + +From: Justin Stitt + +commit 06c03c8edce333b9ad9c6b207d93d3a5ae7c10c0 upstream. + +Using syzkaller with the recently reintroduced signed integer overflow +sanitizer produces this UBSAN report: + +UBSAN: signed-integer-overflow in ../kernel/time/ntp.c:738:18 +9223372036854775806 + 4 cannot be represented in type 'long' +Call Trace: + handle_overflow+0x171/0x1b0 + __do_adjtimex+0x1236/0x1440 + do_adjtimex+0x2be/0x740 + +The user supplied time_constant value is incremented by four and then +clamped to the operating range. + +Before commit eea83d896e31 ("ntp: NTP4 user space bits update") the user +supplied value was sanity checked to be in the operating range. That change +removed the sanity check and relied on clamping after incrementing which +does not work correctly when the user supplied value is in the overflow +zone of the '+ 4' operation. + +The operation requires CAP_SYS_TIME and the side effect of the overflow is +NTP getting out of sync. + +Similar to the fixups for time_maxerror and time_esterror, clamp the user +space supplied value to the operating range. + +[ tglx: Switch to clamping ] + +Fixes: eea83d896e31 ("ntp: NTP4 user space bits update") +Signed-off-by: Justin Stitt +Signed-off-by: Thomas Gleixner +Cc: Miroslav Lichvar +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/all/20240517-b4-sio-ntp-c-v2-1-f3a80096f36f@google.com +Closes: https://github.com/KSPP/linux/issues/352 +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/ntp.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/kernel/time/ntp.c ++++ b/kernel/time/ntp.c +@@ -733,11 +733,10 @@ static inline void process_adjtimex_mode + time_esterror = clamp(txc->esterror, 0, NTP_PHASE_LIMIT); + + if (txc->modes & ADJ_TIMECONST) { +- time_constant = txc->constant; ++ time_constant = clamp(txc->constant, 0, MAXTC); + if (!(time_status & STA_NANO)) + time_constant += 4; +- time_constant = min(time_constant, (long)MAXTC); +- time_constant = max(time_constant, 0l); ++ time_constant = clamp(time_constant, 0, MAXTC); + } + + if (txc->modes & ADJ_TAI && diff --git a/queue-6.1/series b/queue-6.1/series index 39934b37b31..bf096ef72d5 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -103,3 +103,5 @@ ntp-clamp-maxerror-and-esterror-to-operating-range.patch torture-enable-clocksource-watchdog-with-tsc-watchdo.patch clocksource-scale-the-watchdog-read-retries-automati.patch clocksource-fix-brown-bag-boolean-thinko-in-cs_watch.patch +driver-core-fix-uevent_show-vs-driver-detach-race.patch +ntp-safeguard-against-time_constant-overflow.patch