| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
ipv6: Fix null-ptr-deref in fib6_nh_mtu_change().
fib6_nh_mtu_change() re-fetches idev via __in6_dev_get(arg->dev) and
dereferences idev->cnf.mtu6 without a NULL check. addrconf_ifdown()
clears dev->ip6_ptr with RCU_INIT_POINTER() after rt6_disable_ip() has
released tb6_lock, so the RA-driven MTU walk can observe a NULL idev and
oops. The caller rt6_mtu_change_route() guards its own __in6_dev_get(),
but this re-fetch is unguarded; nexthop-backed routes survive
addrconf_ifdown()'s flush, so the walk still reaches it after ip6_ptr is
nulled.
Return 0 when idev is NULL, matching rt6_mtu_change_route() and the
fib6_mtu() fix in commit 5ad509c1fdad ("ipv6: Fix null-ptr-deref in
fib6_mtu().").
Oops: general protection fault, ... KASAN: null-ptr-deref in range
[0x00000000000002a8-0x00000000000002af]
RIP: 0010:fib6_nh_mtu_change+0x203/0x990
rt6_mtu_change_route+0x141/0x1d0
__fib6_clean_all+0xd0/0x160
rt6_mtu_change+0xb4/0x100
ndisc_router_discovery+0x24b5/0x2cb0
icmpv6_rcv+0x12e9/0x1710
ipv6_rcv+0x39b/0x410 |
| In the Linux kernel, the following vulnerability has been resolved:
bpf: Support for hardening against JIT spraying
The BPF JIT allocator packs many small programs into larger executable
allocations and reuses space within those allocations as programs are
loaded and freed. When fresh code is written into space that a previous
program occupied, an indirect jump into the new program can reuse a branch
prediction left behind by the old one.
Flush the indirect branch predictors before reusing JIT memory so that
indirect jumps into a newly written program don't reuse predictions from an
old program that occupied the same space.
Introduce bpf_arch_pred_flush_enabled static key and bpf_arch_pred_flush
static call for flushing the branch predictors on JIT memory reuse.
Architectures that need a flush, can update it to a predictor flush
function. By default, its a NOP and does not emit any CALL.
Allocations larger than a pack are not covered by this flush. That is safe
because cBPF programs (the unprivileged attack surface) are bounded well
below a pack size. Issue a warning if this assumption is ever violated
while the flush is active. |
| In the Linux kernel, the following vulnerability has been resolved:
ALSA: firewire: isight: bound the sample count to the packet payload
isight_packet() takes the frame count from the device iso packet and
checks it only against the device claimed iso length.
count = be32_to_cpu(payload->sample_count);
if (likely(count <= (length - 16) / 4))
isight_samples(isight, payload->samples, count);
length is the iso header data_length. It can be up to 0xffff. So the
gate allows a count up to about 16379. isight_samples() then copies
count frames out of payload->samples into the PCM DMA buffer.
payload->samples holds only 2 * MAX_FRAMES_PER_PACKET values. The
device multiplexes two samples per frame. A count past
MAX_FRAMES_PER_PACKET reads past the payload. A count past the buffer
size writes past runtime->dma_area. The smallest PCM buffer is larger
than MAX_FRAMES_PER_PACKET. Bounding the count to MAX_FRAMES_PER_PACKET
keeps both the read and the write in range.
A malicious or faulty Apple iSight on the FireWire bus reaches this
during a normal capture.
Add the MAX_FRAMES_PER_PACKET bound to the gate. |
| In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: btusb: fix use-after-free on registration failure
Make sure to release the sibling interfaces in case controller
registration fails to avoid use-after-free and double-free when they are
eventually disconnected.
This issue was reported by Sashiko while reviewing a fix for a wakeup
source leak in the btusb probe errors paths. |
| In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: btusb: fix use-after-free on marvell probe failure
Make sure to stop any TX URBs submitted during Marvell OOB wakeup
configuration on later probe failures to avoid use-after-free in the
completion callback.
This issue was reported by Sashiko while reviewing a fix for a wakeup
source leak in the btusb probe errors paths. |
| In the Linux kernel, the following vulnerability has been resolved:
staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()
supplicant_ie is a 256-byte array in struct security_priv. The WPA and
WPA2 IE copy paths use:
memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
where wpa_ielen is the raw IE length field (u8, 0-255). When a local user
supplies a connect request via nl80211 with a crafted WPA IE of length 255,
wpa_ielen + 2 equals 257, overflowing the 256-byte buffer by one byte into
the adjacent last_mic_err_time field.
rtw_parse_wpa_ie() does not prevent this: its length consistency check
compares *(wpa_ie+1) against (u8)(wpa_ie_len-2), which is (u8)(255) == 255
when wpa_ie_len = 257, so the check passes silently.
Add explicit bounds checks for both the WPA and WPA2 paths before the
memcpy, rejecting any IE whose total size (wpa_ielen + 2) exceeds the
supplicant_ie buffer. |
| In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: MGMT: Fix UAF of hci_conn_params in add_device_complete
add_device_complete() runs from the hci_cmd_sync_work kworker, which
holds only hci_req_sync_lock and *not* hci_dev_lock. It calls
hci_conn_params_lookup() and then dereferences the returned object
(params->flags) without taking hci_dev_lock:
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
le_addr_type(cp->addr.type));
...
device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
cp->addr.type, hdev->conn_flags,
params ? params->flags : 0);
hci_conn_params_lookup() walks hdev->le_conn_params and is documented to
require hdev->lock. A concurrent MGMT_OP_REMOVE_DEVICE
(remove_device()), which does run under hci_dev_lock, can call
hci_conn_params_free() to list_del() and kfree() the very object the
lookup returned, so the subsequent params->flags read touches freed
memory [0].
Hold hci_dev_lock() across the hci_conn_params_lookup() and the read of
params->flags (and the matching event emission) so the lookup result
cannot be freed by a concurrent remove_device() before it is used,
honouring the locking contract of hci_conn_params_lookup().
[0]: (trailing page/memory-state dump trimmed)
BUG: KASAN: slab-use-after-free in add_device_complete+0x358/0x3d8 net/bluetooth/mgmt.c:7671
Read of size 1 at addr ffff000017ab26c1 by task kworker/u9:8/388
CPU: 1 UID: 0 PID: 388 Comm: kworker/u9:8 Not tainted 7.0.11 #20 PREEMPT
Hardware name: linux,dummy-virt (DT)
Workqueue: hci0 hci_cmd_sync_work
Call trace:
show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:499 (C)
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0xb4/0xd4 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0x118/0x5d8 mm/kasan/report.c:482
kasan_report+0xb0/0xf4 mm/kasan/report.c:595
__asan_report_load1_noabort+0x20/0x2c mm/kasan/report_generic.c:378
add_device_complete+0x358/0x3d8 net/bluetooth/mgmt.c:7671
hci_cmd_sync_work+0x14c/0x240 net/bluetooth/hci_sync.c:334
process_one_work+0x628/0xd38 kernel/workqueue.c:3289
process_scheduled_works kernel/workqueue.c:3372 [inline]
worker_thread+0x7a8/0xac0 kernel/workqueue.c:3453
kthread+0x39c/0x444 kernel/kthread.c:436
ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860
Allocated by task 3401:
kasan_save_stack+0x3c/0x64 mm/kasan/common.c:57
kasan_save_track+0x20/0x3c mm/kasan/common.c:78
kasan_save_alloc_info+0x40/0x54 mm/kasan/generic.c:570
poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
__kasan_kmalloc+0xd4/0xd8 mm/kasan/common.c:415
kasan_kmalloc include/linux/kasan.h:263 [inline]
__kmalloc_cache_noprof+0x1b0/0x458 mm/slub.c:5385
kmalloc_noprof include/linux/slab.h:950 [inline]
kzalloc_noprof include/linux/slab.h:1188 [inline]
hci_conn_params_add+0x10c/0x4b0 net/bluetooth/hci_core.c:2279
hci_conn_params_set net/bluetooth/mgmt.c:5162 [inline]
add_device+0x5b4/0xa54 net/bluetooth/mgmt.c:7755
hci_mgmt_cmd net/bluetooth/hci_sock.c:1721 [inline]
hci_sock_sendmsg+0x10b4/0x1dd0 net/bluetooth/hci_sock.c:1841
sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg+0xe0/0x128 net/socket.c:742
sock_write_iter+0x250/0x390 net/socket.c:1195
new_sync_write fs/read_write.c:595 [inline]
vfs_write+0x66c/0xab0 fs/read_write.c:688
ksys_write+0x1fc/0x24c fs/read_write.c:740
__do_sys_write fs/read_write.c:751 [inline]
__se_sys_write fs/read_write.c:748 [inline]
__arm64_sys_write+0x70/0xa4 fs/read_write.c:748
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x84/0x2a8 arch/arm64/kernel/syscall.c:49
el0_svc_common.constprop.0+0xe4/0x294 arch/arm64/kernel/syscall.c:132
do_el0_svc+0x44/0x5c arch/arm64/kernel/syscall.c:151
el0_svc+0x38/0xac arch/arm64/kernel/entry-common.c:724
el0t_64_sync_handler+0xa0/0xe4 arch/arm64/kernel/entry-common.c:743
el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596
Freed by task 3740:
kasan_save_stack+0x3c/0x64
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
netpoll: fix a use-after-free on shutdown path
There is a use-after-free error on netpoll, which is clearly detected by
KASAN.
BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0x3b/0x80
Read of size 1 at addr ... by task kworker/9:1
Workqueue: events queue_process
Call Trace:
skb_dequeue+0x1e/0xb0
queue_process+0x2c/0x600
process_scheduled_works+0x4b6/0x850
worker_thread+0x414/0x5a0
Allocated by task 242:
__netpoll_setup+0x201/0x4a0
netpoll_setup+0x249/0x550
enabled_store+0x32f/0x380
Freed by task 0:
kfree+0x1b7/0x540
rcu_core+0x3f8/0x7a0
The problem happens when there is a pending TX worker running in
parallel with the cleanup path.
This is what happens on netpoll shutdown path:
1) __netpoll_cleanup() is called
2) set dev->npinfo to NULL
3) call_rcu() with rcu_cleanup_netpoll_info()
3.1) rcu_cleanup_netpoll_info() tries to cancel all workers with
cancel_delayed_work(), but doesn't wait for the worker to finish
4) and kfree(npinfo);
Because 3.1) doesn't really cancel the work, as the comment says "we
can't call cancel_delayed_work_sync here, as we are in softirq", the TX
worker can run after 4).
Tl;DR: queue_process() is not an RCU reader, it reaches npinfo through
the work item via container_of().
Use disable_delayed_work_sync() to ensure the worker is completely
stopped and prevent any future re-arming attempts. Once npinfo is set
to NULL, senders will bail out and not queue new work. The disable flag
ensures any in-flight re-arming attempts also fail silently.
In the future, we can do the cleanup inline here without needing the
npinfo->rcu rcu_head, but that is net-next material. |
| In the Linux kernel, the following vulnerability has been resolved:
smb: client: Fix next buffer leak in receive_encrypted_standard()
receive_encrypted_standard() allocates next_buffer before checking
whether the number of compound PDUs already reached MAX_COMPOUND. If
the limit check fails, the function returns immediately and the newly
allocated next_buffer is not assigned to server->smallbuf/server->bigbuf,
making it leaked.
Move the MAX_COMPOUND check before allocating next_buffer. |
| In the Linux kernel, the following vulnerability has been resolved:
HID: letsketch: fix UAF on inrange_timer at driver unbind
letsketch_driver does not provide a .remove callback, but
letsketch_probe() arms a per-device timer:
timer_setup(&data->inrange_timer, letsketch_inrange_timeout, 0);
The timer is re-armed from letsketch_raw_event() with a 100 ms
timeout on every pen-in-range report, and its callback dereferences
data->input_tablet to deliver a synthetic BTN_TOOL_PEN release.
letsketch_data is allocated with devm_kzalloc(), and its input_dev
fields are devm-allocated via letsketch_setup_input_tablet(). On
device unbind (USB unplug or rmmod), the HID core runs its default
teardown and devm cleanup frees both letsketch_data and the input
devices. Because no .remove callback exists, nothing drains the
timer first: if raw_event armed it within ~100 ms of the unbind,
the pending timer fires on freed memory. This is a UAF read of
data and of data->input_tablet, followed by input_report_key() /
input_sync() into the freed input_dev.
The same problem can occur on the probe error path: if
hid_hw_start() enabled I/O on an always-poll-quirk device and then
failed, raw_event may have armed the timer before devm releases
data.
Fix by adding a .remove callback that calls hid_hw_stop() first.
hid_hw_stop() synchronously kills the URBs that deliver raw_event(),
so once it returns no path can re-arm the timer. timer_shutdown_sync()
then drains any in-flight callback and permanently disables further
mod_timer() calls. Apply the same timer_shutdown_sync() in the probe
error path so the timer is guaranteed not to outlive data. |
| In the Linux kernel, the following vulnerability has been resolved:
HID: appleir: fix UAF on pending key_up_timer in remove()
appleir_remove() runs hid_hw_stop() before timer_delete_sync().
hid_hw_stop() synchronously unregisters the HID input device via
hid_disconnect() -> hidinput_disconnect() -> input_unregister_device(),
which drops the last reference and frees the underlying input_dev when
no userspace handle holds it open.
key_up_tick() reads appleir->input_dev and calls input_report_key() /
input_sync() on it. The timer is armed from appleir_raw_event() with
a HZ/8 (~125 ms) timeout on every keydown and key-repeat report. If a
key was pressed shortly before the device is disconnected, the timer
can fire after hid_hw_stop() has freed input_dev but before the
teardown drains it.
A simple reorder is not sufficient. Putting the timer drain first
still leaves a window where a USB URB completion (raw_event) running
during hid_hw_stop() can call mod_timer() and re-arm the timer, which
then fires after hidinput_disconnect() has freed input_dev. The same
URB-completion window also lets raw_event() reach key_up(), key_down()
and battery_flat() directly, all of which dereference
appleir->input_dev.
Introduce a 'removing' flag on struct appleir, gated by the existing
spinlock. appleir_remove() sets the flag under the lock and then
shuts down the timer with timer_shutdown_sync(), which both drains any
in-flight callback and permanently disables further mod_timer() calls.
appleir_raw_event() and key_up_tick() bail out early if the flag is
set, so no path can arm or run the timer, or dereference
appleir->input_dev, after remove() has started tearing down.
The keyrepeat and flatbattery branches of appleir_raw_event()
previously called into the input layer without holding the spinlock;
take it now so the flag check is well-defined. This incidentally
closes a pre-existing read-side race on appleir->current_key in the
keyrepeat branch.
This bug is structurally a sibling of commit 4db2af929279 ("HID:
appletb-kbd: fix UAF in inactivity-timer cleanup path") and has been
present since the driver was introduced. |
| In the Linux kernel, the following vulnerability has been resolved:
HID: lg-g15: cancel pending work on remove to fix a use-after-free
lg_g15_data is allocated with devm and holds a work item. The report
handlers schedule that work straight from device input.
lg_g15_event() and lg_g15_v2_event() do it on the backlight cycle key,
and lg_g510_leds_event() does it too. The worker dereferences the
lg_g15_data back through container_of.
The driver had no remove callback and never cancelled the work. So if a
report scheduled the work and the keyboard was then unplugged, devres
freed lg_g15_data while the work was still pending or running, and the
worker touched freed memory. This is a use-after-free. It is reachable
as a race on device unplug.
Add a remove callback that cancels the work before devres frees the
state. g15->work is only initialized for the models that schedule it
(G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so guard the
cancel on g15->work.func to avoid cancelling a work that was never set
up. The g15 NULL test mirrors the one already in lg_g15_raw_event(). |
| In the Linux kernel, the following vulnerability has been resolved:
bpf: Allow LPM map access from sleepable BPF programs
trie_lookup_elem() annotates its rcu_dereference_check() walks with
only rcu_read_lock_bh_held(). Because rcu_dereference_check(p, c)
resolves to "c || rcu_read_lock_held()", this passes for XDP/NAPI and
classic RCU readers but fails for sleepable BPF programs, which enter
via __bpf_prog_enter_sleepable() and hold only rcu_read_lock_trace().
trie_update_elem() and trie_delete_elem() have the same problem in a
different form: they walk the trie with plain rcu_dereference(), which
asserts rcu_read_lock_held() unconditionally. Both are reachable from
sleepable BPF programs via the bpf_map_update_elem / bpf_map_delete_elem
helpers, and from the syscall path under classic rcu_read_lock(). In
the writer paths the trie is actually protected by trie->lock (an
rqspinlock taken across the walk); we never relied on the RCU read-side
lock to keep nodes alive there.
A sleepable LSM hook that ends up touching an LPM trie therefore
triggers lockdep on debug kernels:
=============================
WARNING: suspicious RCU usage
7.1.0-... Tainted: G E
-----------------------------
kernel/bpf/lpm_trie.c:249 suspicious rcu_dereference_check() usage!
1 lock held by net_tests/540:
#0: (rcu_tasks_trace_srcu_struct){....}-{0:0},
at: __bpf_prog_enter_sleepable+0x26/0x280
Call Trace:
dump_stack_lvl
lockdep_rcu_suspicious
trie_lookup_elem
bpf_prog_..._enforce_security_socket_connect
bpf_trampoline_...
security_socket_connect
__sys_connect
do_syscall_64
This is lockdep-only -- no UAF, since Tasks Trace RCU does serialize
against the trie's reclaim path -- but it spams the console once per
distinct callsite on every debug kernel running a sleepable BPF LSM
that touches an LPM trie, which is increasingly common.
For the lookup path, switch the rcu_dereference_check() annotation
from rcu_read_lock_bh_held() to bpf_rcu_lock_held(), which accepts all
three contexts (classic, BH, Tasks Trace). Other map types already
follow this convention.
For trie_update_elem() and trie_delete_elem(), annotate the walks as
rcu_dereference_protected(*p, 1) -- matching trie_free() in the same
file -- since trie->lock is held across the walk. rqspinlock has no
lockdep_map, so the predicate degenerates to '1' rather than
lockdep_is_held(&trie->lock); the protection is real but not
machine-verifiable. trie_get_next_key() also uses bare
rcu_dereference() but is reachable only from the BPF syscall, which
holds classic rcu_read_lock() before dispatching, so it is left
untouched. |
| In the Linux kernel, the following vulnerability has been resolved:
usb: free iso schedules on failed submit
EHCI and FOTG210 isochronous submits build an ehci_iso_sched before
linking the URB to the endpoint queue, and keep the staged schedule in
urb->hcpriv until iso_stream_schedule() and the link helpers consume it.
If the controller is no longer accessible, or usb_hcd_link_urb_to_ep()
fails, submit jumps to done_not_linked before that handoff happens and
leaks the staged schedule still attached to urb->hcpriv.
Free the staged schedule from done_not_linked when submit fails before
the URB is linked and clear urb->hcpriv after the free.
The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing
v6.13-rc1. The tool is still under development and is not yet publicly
available. Manual inspection confirms that the bug is still
present in v7.1.1.
An x86_64 allyesconfig build showed no new warnings. As we do not have an
EHCI host controller with a USB isochronous device to test with, no
runtime testing was able to be performed. |
| In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: udc: Fix use-after-free in gadget_match_driver
The udc structure acts as the management structure for the gadget,
but their lifecycles are decoupled. A race condition exists where
usb_del_gadget() frees the udc memory (e.g., via mode-switch work)
while gadget_match_driver() concurrently accesses the freed udc memory
(e.g., via configfs), causing a Use-After-Free (UAF) that triggers a
NULL pointer dereference when the freed memory is zeroed:
[39430.908615][ T1171] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
[39430.911397][ T1171] pc : __pi_strcmp+0x20/0x140
[39430.911441][ T1171] lr : gadget_match_driver+0x34/0x60
...
[39430.911890][ T1171] usb_gadget_register_driver_owner+0x50/0xf8
[39430.911910][ T1171] gadget_dev_desc_UDC_store+0xf4/0x140
[39430.931308][ T1171] configfs_write_iter+0xec/0x134
[39430.957058][ T1171] Workqueue: events_freezable __dwc3_set_mode
[39430.957287][ T1171] dwc3_gadget_exit+0x34/0x8c
[39430.957304][ T1171] __dwc3_set_mode+0xc0/0x664
Fix this by ensuring the udc structure remains allocated until the
gadget is released. To achieve this, introduce a new
usb_gadget_release() routine to the core. When the gadget is added,
usb_add_gadget() stores the gadget's release routine in the udc
structure and takes a reference to the udc. When the gadget is
released, usb_gadget_release() drops the reference to the udc and
then calls the gadget's release routine. |
| In the Linux kernel, the following vulnerability has been resolved:
USB: idmouse: fix use-after-free on disconnect race
mutex_unlock() may access the mutex structure after releasing the lock
and therefore cannot be used to manage lifetime of objects directly
(unlike spinlocks and refcounts). [1][2]
Use a kref to release the driver data to avoid use-after-free in
mutex_unlock() when release() races with disconnect().
[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is
non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
other sleeping locks, can still use the lock object
after it's unlocked") |
| In the Linux kernel, the following vulnerability has been resolved:
USB: ldusb: fix use-after-free on disconnect race
mutex_unlock() may access the mutex structure after releasing the lock
and therefore cannot be used to manage lifetime of objects directly
(unlike spinlocks and refcounts). [1][2]
Use a kref to release the driver data to avoid use-after-free in
mutex_unlock() when release() races with disconnect().
[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is
non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
other sleeping locks, can still use the lock object
after it's unlocked") |
| In the Linux kernel, the following vulnerability has been resolved:
USB: iowarrior: fix use-after-free on disconnect
Submitted write URBs are not stopped on close() and therefore need to be
stopped unconditionally on disconnect() to avoid use-after-free in the
completion handler. |
| In the Linux kernel, the following vulnerability has been resolved:
USB: iowarrior: fix use-after-free on disconnect race
mutex_unlock() may access the mutex structure after releasing the lock
and therefore cannot be used to manage lifetime of objects directly
(unlike spinlocks and refcounts). [1][2]
Use a kref to release the driver data to avoid use-after-free in
mutex_unlock() when release() races with disconnect().
[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
other sleeping locks, can still use the lock object
after it's unlocked") |
| In the Linux kernel, the following vulnerability has been resolved:
USB: legousbtower: fix use-after-free on disconnect race
mutex_unlock() may access the mutex structure after releasing the lock
and therefore cannot be used to manage lifetime of objects directly
(unlike spinlocks and refcounts). [1][2]
Use a kref to release the driver data to avoid use-after-free in
mutex_unlock() when release() races with disconnect().
[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is
non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
other sleeping locks, can still use the lock object
after it's unlocked") |