Subject: CVE-2024-39501: drivers: core: synchronize really_probe() and dev_uevent()

From: Greg Kroah-Hartman <[email-masked]>

Description
===========

In the Linux kernel, the following vulnerability has been resolved:

drivers: core: synchronize really_probe() and dev_uevent()

Synchronize the dev->driver usage in really_probe() and dev_uevent().
These can run in different threads, what can result in the following
race condition for dev->driver uninitialization:

Thread #1:
==========

really_probe() {
...
probe_failed:
...
device_unbind_cleanup(dev) {
    ...
    dev->driver = NULL;   // <= Failed probe sets dev->driver to NULL
    ...
    }
...
}

Thread #2:
==========

dev_uevent() {
...
if (dev->driver)
      // If dev->driver is NULLed from really_probe() from here on,
      // after above check, the system crashes
      add_uevent_var(env, "DRIVER=%s", dev->driver->name);
...
}

really_probe() holds the lock, already. So nothing needs to be done
there. dev_uevent() is called with lock held, often, too. But not
always. What implies that we can't add any locking in dev_uevent()
itself. So fix this race by adding the lock to the non-protected
path. This is the path where above race is observed:

 dev_uevent+0x235/0x380
 uevent_show+0x10c/0x1f0  <= Add lock here
 dev_attr_show+0x3a/0xa0
 sysfs_kf_seq_show+0x17c/0x250
 kernfs_seq_show+0x7c/0x90
 seq_read_iter+0x2d7/0x940
 kernfs_fop_read_iter+0xc6/0x310
 vfs_read+0x5bc/0x6b0
 ksys_read+0xeb/0x1b0
 __x64_sys_read+0x42/0x50
 x64_sys_call+0x27ad/0x2d30
 do_syscall_64+0xcd/0x1d0
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

Similar cases are reported by syzkaller in

https://syzkaller.appspot.com/bug?extid=ffa8143439596313a85a

But these are regarding the *initialization* of dev->driver

dev->driver = drv;

As this switches dev->driver to non-NULL these reports can be considered
to be false-positives (which should be "fixed" by this commit, as well,
though).

The same issue was reported and tried to be fixed back in 2015 in

https://lore.kernel.org/lkml/[email-masked]/

already.

The Linux kernel CVE team has assigned CVE-2024-39501 to this issue.

Affected and fixed versions
===========================

	Issue introduced in 2.6.21 with commit 239378f16aa1 and fixed in 4.19.317 with commit bb3641a58317
	Issue introduced in 2.6.21 with commit 239378f16aa1 and fixed in 5.4.279 with commit 13d25e82b6d0
	Issue introduced in 2.6.21 with commit 239378f16aa1 and fixed in 5.10.221 with commit 760603e30bf1
	Issue introduced in 2.6.21 with commit 239378f16aa1 and fixed in 5.15.162 with commit ec772ed7cb21
	Issue introduced in 2.6.21 with commit 239378f16aa1 and fixed in 6.1.95 with commit 08891eeaa97c
	Issue introduced in 2.6.21 with commit 239378f16aa1 and fixed in 6.6.35 with commit a42b0060d6ff
	Issue introduced in 2.6.21 with commit 239378f16aa1 and fixed in 6.9.6 with commit 95d03d369ea6
	Issue introduced in 2.6.21 with commit 239378f16aa1 and fixed in 6.10 with commit c0a40097f0bc

Please see https://www.kernel.org for a full list of currently supported
kernel versions by the kernel community.

Unaffected versions might change over time as fixes are backported to
older supported kernel versions.  The official CVE entry at
	https://cve.org/CVERecord/?id=CVE-2024-39501
will be updated if fixes are backported, please check that for the most
up to date information about this issue.

Affected files
==============

The file(s) affected by this issue are:
	drivers/base/core.c

Mitigation
==========

The Linux kernel CVE team recommends that you update to the latest
stable kernel version for this, and many other bugfixes.  Individual
changes are never tested alone, but rather are part of a larger kernel
release.  Cherry-picking individual commits is not recommended or
supported by the Linux kernel community at all.  If however, updating to
the latest release is impossible, the individual changes to resolve this
issue can be found at these commits:
	https://git.kernel.org/stable/c/bb3641a5831789d83a58a39ed4a928bcbece7080
	https://git.kernel.org/stable/c/13d25e82b6d00d743c7961dcb260329f86bedf7c
	https://git.kernel.org/stable/c/760603e30bf19d7b4c28e9d81f18b54fa3b745ad
	https://git.kernel.org/stable/c/ec772ed7cb21b46fb132f89241682553efd0b721
	https://git.kernel.org/stable/c/08891eeaa97c079b7f95d60b62dcf0e3ce034b69
	https://git.kernel.org/stable/c/a42b0060d6ff2f7e59290a26d5f162a3c6329b90
	https://git.kernel.org/stable/c/95d03d369ea647b89e950667f1c3363ea6f564e6
	https://git.kernel.org/stable/c/c0a40097f0bc81deafc15f9195d1fb54595cd6d0