See how linux kernel compares to other vendors in security performance
In the Linux kernel, the following vulnerability has been resolved:
i2c: imx: Fix slave registration race and error handling
In i2cimxregslave(), the slave pointer was assigned before pmruntimeresumeandget(). If pmruntimeresumeandget() failed, the error path returned without clearing i2cimx->slave, leaving it non-NULL and causing all subsequent registration attempts to fail with -EBUSY.
Additionally, because this driver uses a shared IRQ, the interrupt handler i2cimxisr() can execute concurrently and, after acquiring slavelock, dereference i2cimx->slave. The previous fix attempt added a lockless i2cimx->slave = NULL on the error path, but that could race with the ISR under the lock and still cause a NULL pointer dereference.
Fix both issues by deferring the assignment of i2cimx->slave and i2cimx->lastslaveevent to after a successful resume, and by performing the assignment inside the slavelock critical section. This guarantees that the slave pointer is never left stale on the error path and is always valid when observed by the interrupt handler.
In the Linux kernel, the following vulnerability has been resolved:
ALSA: FCP: fix OOB write in fcpmeterctlget()
fcpioctlsetmetermap() bounds the user-supplied Level Meter map size by the driver's own limit of 255
if (map.mapsize < 1 || map.mapsize > 255 || map.meterslots < 1 || map.meterslots > 255) return -EINVAL;
and passes it to fcpaddnewctl() as the control's channel count, where it is stored as elem->channels.
Every control read writes into struct sndctlelemvalue, whose integer array is declared long value[128], so the limit is 128, not 255. fcpmeterctlget() stores one 64-bit word per channel into that array with no bound of its own:
for (i = 0; i < elem->channels; i++) { int idx = private->meterlevelmap[i]; int value = idx < 0 ? 0 : le32tocpu(resp[idx]);
ucontrol->value.integer.value[i] = value; }
sndctlelemreaduser() serves that object from memdupuser(control, sizeof(control)), 1224 bytes on LP64 out of kmalloc-2048. offsetof(struct sndctlelemvalue, value) is 72, so element i is written at byte 72 + 8 i and element 144 already lands past the allocation. At mapsize 255 the last store ends at byte 2112, 888 bytes past the object and 64 bytes into the adjacent slab object. The stored words come from the device and meterlevelmap[] selects which word lands in which slot, so extent and contents are both controlled.
The core does not catch this. sndctlcheckeleminfo() is reached only from sndctleleminfo(), which sndctlelemread() calls under CONFIGSNDCTLDEBUG; without that option sndctlskipvalidation() is a compile-time true. sndctladdreplace() validates kcontrol->count and never inspects elem->channels.
Installing an oversized map needs CAPSYSRAWIO, but the control outlives the hwdep descriptor that created it, so the out-of-bounds stores are issued by any process able to read controls on /dev/snd/controlC0.
KASAN on 7.2.0-rc5 (arm64), triggered by an unprivileged control read:
BUG: KASAN: slab-out-of-bounds in fcpmeterctlget Write of size 8 at addr ffff000017af04c8 by task fcptrigger/185 asanstore8 fcpmeterctlget sndctlelemread sndctlioctl Allocated by task 185: memdupuser sndctlioctl The buggy address is located 0 bytes to the right of allocated 1224-byte region [ffff000017af0000, ffff000017af04c8)
Bound the map size by the ABI limit rather than by 255, and bound the store loop at the sink so it cannot run past the value array whatever elem->channels holds.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: ISO: fix leaking sk after socket release
isosockkill() tests !sockflag(sk, SOCKZAPPED) || sk->sksocket || sockflag(sk, SOCKDEAD) for early return, but this is always true since sockorphan(sk) sets SOCKDEAD, so the sk reference released by socket always leaks, isosockdestruct is never called.
The socket reference also leaks when isosockclose() does not set SOCKZAPPED, since isoconndel() does not call isosockkill() after zapping.
Fix by replacing SOCKDEAD by BTSKKILLED flag that is not used for something else, and locksock to ensure isosockkill() puts sk only after socket release only once. Release and isoconndel may run concurrently. Call isosockkill() from isoconndel() to clean sk up after zapping.
Remove call to isosockkill() from isosockclose(), as it's generally no-op there.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: mgmt: fix UAF in pair command cancellation
The pairing completion and authentication failure callbacks look up the pending MGMTOPPAIRDEVICE command by walking hdev->mgmtpending. The lookup returned a command that was still linked on the shared pending list, without keeping mgmtpendinglock held for the later dereference and removal.
A concurrent MGMTOPCANCELPAIRDEVICE request can remove and free the same pending command before the callback uses it. The reverse race is also possible when cancelpairdevice() gets a command from pendingfind() and a callback removes it before the cancel path dereferences it. This can lead to a use-after-free and a second listdel().
Make the pairing lookup helpers transfer ownership of the pending command by removing it from hdev->mgmtpending while holding mgmtpendinglock. The callbacks and cancel path then complete the command and free it directly, so racing paths cannot find or free the same command again. Take a temporary hciconn reference in cancelpairdevice() because the command completion drops the reference stored in the pending command.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: hcisync: Fix advertising data UAFs
hcifindadvinstance() returns an advinfo pointer that is valid only while hdev->lock is held. The advertising command-sync paths perform instance lookups without that lock and, in some cases, retain the pointer while waiting for a controller response.
An advertising termination event can therefore interleave as follows:
hcicmdsyncwork hcirxwork hcifindadvinstance() hcicmdsyncstatus() wait for controller reply hcidevlock() hciremoveadvinstance() kfree(adv) adv->scanrspchanged = false
KASAN reported:
BUG: KASAN: slab-use-after-free in hcisetextscanrspdatasync+0x2e1/0x300 Write of size 1 at addr ffff88810a45d21d by task kworker/u17:0/88 Workqueue: hci0 hcicmdsyncwork Call Trace: hcisetextscanrspdatasync+0x2e1/0x300 hcischeduleadvinstancesync+0x390/0x4c0 hcicmdsyncwork+0x173/0x300 Allocated by task 87: hciaddadvinstance+0x538/0xac0 addadvertising+0x885/0x1160 Freed by task 89: kfree+0x131/0x3c0 hciremoveadvinstance+0x1d8/0x3b0 hcileextadvtermevt+0x17b/0x730
Protect the instance lookup and payload construction in the extended advertising, scan response, and periodic advertising data paths. Snapshot the advertising parameters under hdev->lock, but release the lock before waiting for the controller.
Clear advertising-data dirty bits before issuing their commands and restore them after a failure using a fresh lookup. Likewise, update the reported transmit power through a fresh lookup after the parameter command completes. No advinfo pointer then survives an HCI command wait.
In the Linux kernel, the following vulnerability has been resolved:
ALSA: ump: fix double free of outcvts on rawmidi error
sndumpattachlegacyrawmidi() allocates the legacy conversion array ump->outcvts and, on the sndrawmidinew() error path, frees it with kfree() but leaves ump->outcvts pointing at the freed memory. When the endpoint is later torn down, sndumpendpointfree() frees ump->outcvts a second time, resulting in a double free.
The host snd-usb-audio driver attaches the legacy rawmidi for any USB MIDI 2.0 (UMP) device, so a device that makes sndrawmidinew() fail reaches this path on enumeration.
Clear ump->outcvts after freeing it on the error path so it is not freed again during teardown.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
In the Linux kernel, the following vulnerability has been resolved:
drm/radeon: fix memory leak in radeonringrestore() on lock failure
radeonringrestore() takes ownership of the data buffer allocated by radeonringbackup(). The caller (radeongpureset()) only frees it in the non-restore branch; in the restore branch it relies on radeonringrestore() to free it.
If radeonringlock() fails, the function returned early without calling kvfree(data), leaking the ring backup buffer on every GPU reset that fails at the lock stage. During repeated GPU resets this causes cumulative kernel memory exhaustion.
Free data before returning the error.
In the Linux kernel, the following vulnerability has been resolved:
crypto: atmel-sha204a - fix blocking and non-blocking rng logic
The blocking and non-blocking paths were failing to provide valid entropy due to improper buffer management. Reading the buffer starting from byte 1, only fetch the 32 bytes of random data from the return message.
Tested on an Atmel SHA204A device.
Before (here for blocking), tests showed repeatedly reading reduced bytes. $ head -c 32 /dev/hwrng | hexdump -C 00000000 02 28 85 b3 47 40 f2 ee 00 00 00 00 00 00 00 00 |.(..G@..........| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020
After, the result will be similar to the following: $ head -c 32 /dev/hwrng | hexdump -C 00000000 5a fc 3f 13 14 68 fe 06 68 0a bd 04 83 6e 09 69 |Z.?..h..h....n.i| 00000010 75 ff cf 87 10 84 3b c9 c1 df ae eb 45 53 4c c3 |u.....;.....ESL.| 00000020
In the Linux kernel, the following vulnerability has been resolved:
nvme-pci: fix out-of-bounds access in nvmesetupdescriptorpools
nvmesetupdescriptorpools() indexes dev->descriptorpools[] using the numanode forwarded from hctx->numanode by its single caller, nvmeinithctxcommon(). On a non-NUMA kernel hctx->numanode is NUMANONODE (-1). Because the parameter was declared 'unsigned', the value becomes UINTMAX and the index walks off the array (sized to nrnodeids), faulting during nvmeallocns() and leaving the namespace without a /dev node.
Reproduces on any NVMe controller probed by a CONFIGNUMA=n kernel:
BUG: unable to handle page fault for address: ffff889101603d38 RIP: 0010:nvmeinithctxcommon+0x5a/0x190 [nvme] Call Trace: nvmeinithctx+0x10/0x20 [nvme] nvmeallocns+0x9e/0xa10 [nvmecore] nvmescanns+0x301/0x3b0 [nvmecore] nvmescannsasync+0x23/0x30 [nvmecore]
Switch the parameter to int and fall back to node 0 when it is NUMANONODE; node 0 is always present.
In the Linux kernel, the following vulnerability has been resolved:
crypto: marvell/octeontx - fix DMA cleanup using wrong loop index
The sgcleanup path used list[i] instead of list[j] when unmapping DMA buffers, leaking successfully mapped entries and repeatedly unmapping the failed one.
In the Linux kernel, the following vulnerability has been resolved:
handshake: Require admin permission for DONE command
ACCEPT and DONE are the two downcalls of the handshake genl family, both intended for use by the trusted handshake agent (tlshd). ACCEPT already requires GENLADMINPERM; DONE has no privilege check at all.
The fd-lookup in handshakenldonedoit() only confirms that some pending handshake request exists for the supplied sockfd; it does not authenticate the sender. An unprivileged process that guesses or observes a valid sockfd can therefore submit a DONE with HANDSHAKEADONESTATUS == 0, leaving the kernel consumer to proceed as if the handshake succeeded. A non-zero status on a forged DONE tears down a legitimate in-flight handshake before tlshd can report its real result.
In the Linux kernel, the following vulnerability has been resolved:
ALSA: seq: avoid stale FIFO cells during resize
sndseqfiforesize() still needs to publish the replacement pool before it waits for FIFO users. A blocking sndseqread() holds f->uselock while it sleeps, so concurrent senders must be able to queue to the new pool and wake that reader instead of failing against a closing old pool.
However, sndseqfifoeventin() duplicates an event before it takes f->lock, and sndseqread() can dequeue a cell and later call sndseqfifocellputback() if copytouser() or sndseqexpandvarevent() fails. If resize swaps f->pool and detaches oldhead in between, either path can relink an old-pool cell after the snapshot. That stale cell sits outside the drained oldhead list, keeps oldpool->counter elevated, and can leave sndseqpooldelete() waiting for the retired pool to drain.
Keep the existing swap-before-wait ordering in sndseqfiforesize(), but reject stale cells before any FIFO relink. Revalidate event-in cells under f->lock and retry them against the published replacement pool, and free stale putback cells instead of linking them back into the FIFO.
The buggy scenario involves two paths, with each column showing the order within that path:
resize path: relink path: 1. Allocate newpool. 1. Take f->uselock. 2. Swap f->pool to newpool and 2. Duplicate or dequeue an old-pool detach oldhead. cell before oldpool closes. 3. Mark oldpool closing and 3. Reach a later relink point after wait for FIFO users. resize published newpool. 4. Free oldhead and delete 4. Relink the old-pool cell after oldpool. resize detached oldhead. 5. Drop f->uselock.
The reproducer reports a resize ioctl blocked in the expected pool teardown path:
signal: resize iteration=98 targetpool=4 exceeded 250ms (elapsed=251ms) diagnostic: resizetid=651 wchan=sndseqpooldone diagnostic: resizetid=651 stack= sndseqpooldone+0x5b/0x140 sndseqpooldelete+0x7a/0x90 sndseqfiforesize+0x193/0x1e0 sndseqioctlsetclientpool+0x214/0x260 sndseqioctl+0x119/0x540 x64sysioctl+0xd1/0x120 dosyscall64+0xbb/0x2f0 entrySYSCALL64afterhwframe+0x77/0x7f
A second run with larger pools hit the same target path:
signal: resize iteration=32 targetpool=64 exceeded 250ms (elapsed=251ms) diagnostic: resizetid=663 wchan=sndseqpooldone diagnostic: resizetid=663 stack= sndseqpooldone+0x5b/0x140 sndseqpooldelete+0x7a/0x90 sndseqfiforesize+0x193/0x1e0 sndseqioctlsetclientpool+0x214/0x260 sndseqioctl+0x119/0x540 x64sysioctl+0xd1/0x120 dosyscall64+0xbb/0x2f0 entrySYSCALL64afterhwframe+0x77/0x7f
In the Linux kernel, the following vulnerability has been resolved:
cifs: remove all cifs files before kill super
Cifs files may be put into fileinfoputwq during umounting cifs. After umount done, cifsFileInfoputfinal is called, which cause following BUG:
BUG: kernel NULL pointer dereference, address: 0000000000000000 ... [ 134.222152] listlruadd+0x64/0x1a0 [ 134.222399] ? cifsputtcon+0x171/0x340 [cifs] [ 134.222772] dlruadd+0x44/0x60 [ 134.222997] dput+0x1fc/0x210 [ 134.223213] cifsFileInfoputfinal+0x11a/0x140 [cifs] [ 134.223576] processonework+0x17c/0x320 [ 134.223843] workerthread+0x188/0x280 [ 134.224084] ? pfxworkerthread+0x10/0x10 [ 134.224366] kthread+0xcc/0x100 [ 134.224576] ? pfxkthread+0x10/0x10 [ 134.224827] retfromfork+0x30/0x50 [ 134.225063] ? pfxkthread+0x10/0x10 [ 134.225328] retfromforkasm+0x1b/0x30
This can be reproduce by following: unshare -n bash -c " mkdir -p ${CIFSMNT} ip netns attach root 1 ip link add eth0 type veth peer veth0 netns root ip link set eth0 up ip -n root link set veth0 up ip addr add 192.168.0.2/24 dev eth0 ip -n root addr add 192.168.0.1/24 dev veth0 ip route add default via 192.168.0.1 dev eth0 ip netns exec root sysctl net.ipv4.ipforward=1 ip netns exec root iptables -t nat -A POSTROUTING -s 192.168.0.2 -o ${DEV} -j MASQUERADE mount -t cifs ${CIFSPATH} ${CIFSMNT} -o vers=3.0,sec=ntlmssp,credentials=${CIFSCRED},rsize=65536,wsize=65536,cache=none,echointerval=1 touch ${CIFSMNT}/a.txt ip netns exec root iptables -t nat -D POSTROUTING -s 192.168.0.2 -o ${DEV} -j MASQUERADE " umount ${CIFSMNT}
In the Linux kernel, the following vulnerability has been resolved:
net: serialize netifrunning() check in enqueuetobacklog()
Syzbot reported a KASAN slab-use-after-free in fibruleslookup().
The root cause is a race condition where packets can escape the backlog flushing during device unregistration (e.g., during netns exit).
Commit e9e4dd3267d0 ("net: do not process device backlog during unregistration") introduced a lockless netifrunning() check in enqueuetobacklog() to prevent queuing packets to an unregistering device.
However, this creates a TOCTOU race window.
A lockless transmitter (like vethxmit) can pass the check before devclose() clears IFFUP. If the transmitter is then delayed, flushallbacklogs() can run and finish before the transmitter grabs the backlog lock and queues the packet. The packet then escapes the flush and triggers UAF later when processed.
Fix this by moving the netifrunning() check inside the backlog lock. This serializes the check with the flush work (which also grabs the lock). We then either queue the packet before the flush runs (so it gets flushed), or check netifrunning() after the flush/close completes (so it gets dropped).
In the Linux kernel, the following vulnerability has been resolved:
ALSA: usb-audio: Kill MIDI 2.0 URBs before freeing endpoints
MIDI 2.0 input URBs are started during sndusbmidiv2create(). A later setup failure can still jump to sndusbmidiv2free(), which currently frees each endpoint and its coherent URB buffers without first stopping the submitted URBs. A completion can then dereference the embedded URB context and endpoint state after they have been freed, or try to resubmit from the stale endpoint.
This was observed as a KASAN slab-use-after-free in inputurbcomplete().
The buggy scenario involves two paths, with each column showing the order within that path:
probe error path: USB completion path: 1. startinputstreams() submits 1. The HCD still owns a input URBs. submitted input URB. 2. A later setup helper returns 2. inputurbcomplete() runs an error. with urb->context in ep. 3. sndusbmidiv2free() frees 3. The completion reads ep endpoint storage and URB buffers. state and can requeue URBs.
Make the endpoint destructor follow the same teardown ordering used for disconnect when the endpoint has not already been disconnected: publish ep->disconnected, kill the URBs synchronously, and drain the endpoint before freeing URB buffers and endpoint storage. The guard avoids repeating the stop sequence after the normal sndusbmidiv2disconnectall() path, while still synchronizing the direct MIDI 2.0 create-error free path.
Validation reproduced this kernel report: BUG: KASAN: slab-use-after-free in inputurbcomplete+0x37/0x1b0 Workqueue: usbhubwq hubevent RIP: 0010:rawspinunlockirq+0x2e/0x50 Read of size 8 Call trace: dumpstacklvl+0x77/0xb0 printreport+0xce/0x5f0 inputurbcomplete+0x37/0x1b0 (sound/usb/midi2.c:186) srsoaliasreturnthunk+0x5/0xfbef5 virtaddrvalid+0x19f/0x330 kasanreport+0xe0/0x110 usbhcdgivebackurb+0x112/0x1d0 dummytimer+0xaaa/0x19a0 lockisheldtype+0x9a/0x110 lockacquire+0x467/0x28b0 markheldlocks+0x40/0x70 rawspinunlockirqrestore+0x44/0x60 lockdephardirqsonprepare+0xbb/0x1a0 hrtimerrunqueues+0x101/0x520 hrtimerrunsoftirq+0xd0/0x130 handlesoftirqs+0x15b/0x670 irqexitrcu+0xd0/0x170 irqexitrcu+0xe/0x20 sysvecapictimerinterrupt+0x6c/0x80 asmsysvecapictimerinterrupt+0x1a/0x20
In the Linux kernel, the following vulnerability has been resolved:
tpmcrb: Check ACPICOMPANION() against NULL during probe
Every platform driver can be forced to match a device that doesn't match its list of device IDs because of devicematchdriveroverride(), so platform drivers that rely on the existence of a device's ACPI companion object need to verify its presence.
Accordingly, add a requisite ACPICOMPANION() check against NULL to the tpmcrb driver.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: 6lowpan: avoid untracked enable work
lowpanenableset() allocates a temporary work item and schedules doenableset() on systemwq, then returns to debugfs. The debugfs active operation has ended at that point, but the worker still executes module text and manipulates enable6lowpan and listenchan.
bt6lowpanexit() removes the debugfs files and immediately closes and puts listenchan. It has no pointer to the queued work item, so it cannot cancel or flush it before tearing down the state that the worker uses.
The buggy scenario involves two paths, with each column showing the order within that path:
debugfs enable write module exit 1. lowpanenableset() allocates 1. bt6lowpanexit() removes setenable work the debugfs file 2. schedulework() queues 2. bt6lowpanexit() closes doenableset() and puts listenchan 3. the write operation returns 3. module teardown can continue 4. doenableset() later runs against stale state
Run the enable state transition synchronously in lowpanenableset() instead. The simple debugfs setter can sleep, and this file already handles the 6LoWPAN control write synchronously under the same setlock. Once the setter returns, debugfs removal covers the whole operation and exit can no longer race with an untracked work item.
Validation reproduced this kernel report: BUG: KASAN: slab-use-after-free in doenableset+0x113/0x2e0 Workqueue: events doenableset [bluetooth6lowpan] The buggy address belongs to the object at ffff888109cb8000
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: MGMT: Fix adv monitor add failure cleanup
hciaddadvmonitor() publishes a new advmonitor in hdev->advmonitorsidr before the powered MSFT setup step. The MSFT offload add path can then fail either locally before the controller add command completes, or in the MSFT add callback. In the current queued management add flow, hcicmdsyncwork() still invokes mgmtaddadvpatternsmonitorcomplete() with the original pending command after msftaddmonitorpattern() returns.
The buggy scenario involves two paths, with each column showing the order within that path:
MSFT add handling MGMT completion 1. insert monitor and handle 1. receive sync error 2. send MSFT add command 2. call add-monitor completion 3. callback sees bad response 3. load cmd->userdata 4. callback frees monitor 4. read monitor->handle
Local MSFT setup failures have the other half of the same ownership bug: they return an error after the IDR insertion, but no later code removes the failed monitor from the IDR.
Keep ownership with the pending management command until its completion. For normal management adds, the MSFT add callback now records successful controller state and returns errors to its caller. The management completion frees the monitor on non-success after copying the response handle, while resume/reregister callback-error cleanup remains in the MSFT callback. The success path keeps the existing bookkeeping.
Validation reproduced this kernel report: BUG: KASAN: slab-use-after-free in mgmtaddadvpatternsmonitorcomplete+0xfb/0x260 [bluetooth]
Call Trace: <TASK> dumpstacklvl+0x66/0xa0 printreport+0xce/0x5f0 ? mgmtaddadvpatternsmonitorcomplete+0xfb/0x260 [bluetooth] ? srsoaliasreturnthunk+0x5/0xfbef5 ? virtaddrvalid+0x19f/0x330 ? mgmtaddadvpatternsmonitorcomplete+0xfb/0x260 [bluetooth] kasanreport+0xe0/0x110 ? mgmtaddadvpatternsmonitorcomplete+0xfb/0x260 [bluetooth] mgmtaddadvpatternsmonitorcomplete+0xfb/0x260 [bluetooth] ? srsoaliasreturnthunk+0x5/0xfbef5 ? 0xffffffffc00d00da ? pfxmgmtaddadvpatternsmonitorcomplete+0x10/0x10 [bluetooth] ? pfxmgmtaddadvpatternsmonitorcomplete+0x10/0x10 [bluetooth] ? hcicmdsyncwork+0x1ab/0x210 [bluetooth] hcicmdsyncwork+0x1c0/0x210 [bluetooth] ? pfxmgmtaddadvpatternsmonitorcomplete+0x10/0x10 [bluetooth] processonework+0x4fd/0xbc0 ? pfxprocessonework+0x10/0x10 ? srsoaliasreturnthunk+0x5/0xfbef5 ? srsoaliasreturnthunk+0x5/0xfbef5 ? listaddvalidorreport+0x37/0xf0 ? pfxhcicmdsyncwork+0x10/0x10 [bluetooth] ? srsoaliasreturnthunk+0x5/0xfbef5 workerthread+0x2d8/0x570 ? pfxworkerthread+0x10/0x10 kthread+0x1ad/0x1f0 ? pfxkthread+0x10/0x10 retfromfork+0x3c9/0x540 ? pfxretfromfork+0x10/0x10 ? srsoaliasreturnthunk+0x5/0xfbef5 ? switchto+0x2e9/0x730 ? pfxkthread+0x10/0x10 retfromforkasm+0x1a/0x30 </TASK>
Allocated by task 471 on cpu 3 at 285.205389s: kasansavestack+0x33/0x60 kasansavetrack+0x17/0x60 kasankmalloc+0xaa/0xb0 addadvpatternsmonitorrssi+0xd5/0x230 [bluetooth] hcisocksendmsg+0x96b/0xf80 [bluetooth] syssendto+0x2bc/0x2d0 x64syssendto+0x76/0x90 dosyscall64+0x115/0x6a0 entrySYSCALL64afterhwframe+0x77/0x7f
Freed by task 454 on cpu 2 at 285.217112s: kasansavestack+0x33/0x60 kasansavetrack+0x17/0x60 kasansavefreeinfo+0x3b/0x60 kasanslabfree+0x5f/0x80 kfree+0x313/0x590 msftaddmonitorsync+0x54a/0x570 [bluetooth] hciaddadvmonitor+0x133/0x180 [bluetooth] hcicmdsyncwork+0x187/0x210 [bluetooth] processonework+0x4fd/0xbc0 workerthread+0x2d8/0x570 kthread+0x1ad/0x1f0 retfromfork+0x3c9/0x540 retfromforkasm+0x1a/0x30
In the Linux kernel, the following vulnerability has been resolved:
perf/x86/amd/core: Avoid enabling BRS from the SVM reload path
Branch Sampling (BRS) and Last Branch Record (LBR) are mutually exclusive hardware features, and users of both are tracked via cpuc->lbrusers.
When SVM is toggled on a CPU, the host perf events are reprogrammed to update the HostOnly filter bit (set when virtualization is enabled, cleared when it is disabled). On PerfMonV2-capable processors, this reprogramming is performed by calling amdpmuenableall() to rewrite the event selectors. However, amdpmuenableall() also calls amdbrsenableall(), which enables BRS whenever cpuc->lbrusers > 0. Having active LBR events satisfies this gating on processors that have LBR but not BRS. The kernel then tries to set the BRS enable bit in DebugExtnCfg (MSR 0xc000010f). Since that bit is deprecated on such hardware, the write results in a #GP:
Call Trace: <IRQ> amdpmuenableall+0x1d/0x90 amdpmudisablevirt+0x62/0xb0 kvmarchdisablevirtualizationcpu+0xa/0x40 [kvm] hardwaredisablenolock+0x1a/0x30 [kvm] flushsmpcallfunctionqueue+0x9b/0x410 sysveccallfunction+0x18/0xc0 sysveccallfunction+0x69/0x90 </IRQ> <TASK> asmsysveccallfunction+0x16/0x20 RIP: 0010:cpuidleenterstate+0xc4/0x450 ? cpuidleenterstate+0xb7/0x450 cpuidleenter+0x29/0x40 cpuidleidlecall+0xf5/0x160 doidle+0x7b/0xe0 cpustartupentry+0x26/0x30 startsecondary+0x115/0x140 secondarystartup64noverify+0x194/0x19b </TASK>
Fix this by ensuring that BRS is not enabled from the event selector reprogramming path even when cpuc->lbrusers > 0.
In the Linux kernel, the following vulnerability has been resolved:
gpio: mvebu: free generic chips on unbind
irqallocdomaingenericchips() allocates generic chip data that must be freed via irqdomainremovegenericchips(). The devres action mvebugpioremoveirqdomain() only called irqdomainremove(), which only frees the generic chips if IRQDOMAINFLAGDESTROYGC is set. Call irqdomainremovegenericchips() explicitly before irqdomainremove() instead.
In the Linux kernel, the following vulnerability has been resolved:
batman-adv: frag: free unfragmentable packet
The caller of batadvfragsendpacket() assume that the skb provided to the function are always consumed. But the pre-check for an empty payload or the zero fragment size returned an error without any further actions.
A failed pre-check must use the same error handling code as the rest of the function.
In the Linux kernel, the following vulnerability has been resolved:
mm/damon/core: always put unsuccessfully committed target pids
damoncommittarget() puts and gets the destination and the source target pids. It puts the destination target pid because it will be overwritten by the source target pid. It gets the source pid because the caller is supposed to eventually put the pids. In more detail, the caller will call damondestroyctx() after damoncommitctx() to destroy the entire source context. And in this case, [f]vaddr operation set's cleanuptarget() callback will put the pids.
The commit operation is made at the context level. The operation can fail in multiple places including in the middle and after the targets commit operations. For any such failures, immediately the error is returned to the damoncommitctx() caller. If some or all of the source target pids were committed to the destination during the unsuccessful context commit attempt, those pids should be put twice.
The source context will do the put operations using the above explained routine. However, let's suppose the destination context was not originally using [f]vaddr operation set and the commit failed before the ops of the source context is committed. The destination does not have the cleanuptarget() ops callback, so it cannot put the pids via the damondestroyctx().
As a result, the pids are leaked. The issue in the real world would be not very common. The commit feature is for changing parameters of running DAMON context while inheriting internal status like the monitoring results. The monitoring results of a physical address range ain't have things that are beneficial to be inherited to a virtual address ranges monitoring. So the problem-causing DAMON control would be not very common in the real world. That said, it is a supported feature. And damoncommittarget() failure due to memory allocation is relatively realistic [1] if there are a huge number of target regions.
Fix by putting the pids in the commit operation in case of the failures.
The issue was discovered [2] by Sashiko.
In the Linux kernel, the following vulnerability has been resolved:
9p: skip nlink update in cacheless mode to fix WARNON
v9fsdeccount() unconditionally calls dropnlink() on regular files, even when the inode's nlink is already zero. In cacheless mode the client refetches inode metadata from the server (the source of truth) on every operation, so by the time v9fsremove() returns, the locally cached nlink may already reflect the post-unlink value:
1. Client initiates unlink, server processes it and sets nlink to 0 2. Client refetches inode metadata (nlink=0) before unlink returns 3. Client's v9fsremove() completes successfully 4. Client calls v9fsdeccount() which calls dropnlink() on nlink=0
This race is easily triggered under heavy unlink workloads, such as stress-ng's unlink stressor, producing the following warning:
WARNING: fs/inode.c:417 at dropnlink+0x4c/0xc8 Call trace: dropnlink+0x4c/0xc8 v9fsremove+0x1e0/0x250 [9p] v9fsvfsunlink+0x20/0x38 [9p] vfsunlink+0x13c/0x258 ...
In cacheless mode the server is authoritative and the inode is on its way out, so locally adjusting nlink buys nothing. Skip v9fsdeccount() entirely when neither CACHEMETA nor CACHELOOSE is set, which both avoids the warning and removes a class of nlink races (two concurrent unlinkers observing nlink > 0 and both calling dropnlink()) that an nlink == 0 guard alone would only narrow rather than close.
In the Linux kernel, the following vulnerability has been resolved:
wifi: libertastf: fix use-after-free in lbtffreeadapter()
lbtffreeadapter() calls timerdelete(&priv->commandtimer), which does not wait for a running commandtimerfn() callback. lbtffreeadapter() runs on the teardown path right before ieee80211freehw() frees priv, both in lbtfremovecard() and in the probe error path. commandtimer is armed by modtimer() in lbtfcmd() whenever a firmware command is sent. commandtimerfn() dereferences priv. If a command times out as the device is removed, commandtimerfn() runs concurrently with teardown and dereferences priv after it has been freed.
This is the same use-after-free that commit 03cc8f90d053 ("wifi: libertas: fix use-after-free in lbsfreeadapter()") fixed in the sibling libertas driver. The libertastf variant has the identical pattern and was left unchanged. Use timerdeletesync() so any in-flight callback completes before priv is freed.
In the Linux kernel, the following vulnerability has been resolved:
smp: Make CSD lock acquisition atomic for debug mode
Commit b0473dcd4b1d ("smp: Improve smpcallfunctionsingle() CSD-lock diagnostics") changed smpcallfunctionsingle() so that, when CSD lock debugging is enabled, async !wait calls use the destination CPU csddata. That improves diagnostics, but it also removes the single-writer property that made the old csdlock() safe: multiple CPUs can now prepare the same destination CPU CSD concurrently.
csdlock() currently waits for CSDFLAGLOCK to clear and then sets the bit with a non-atomic read-modify-write. Two senders can both see an unlocked CSD, set the bit, overwrite the callback fields, and enqueue the same llist node. Re-adding a node that is already the queue head can make node->next point to itself, leaving the target CPU stuck walking callsinglequeue. Later synchronous work, such as a TLB shootdown, can then remain queued and trigger soft-lockup warnings or panics.
Keep the single csdlock() implementation, but when CSD lock debugging is enabled, acquire CSDFLAGLOCK with trycmpxchgacquire(). This makes the destination CPU CSD a real atomic lock in the only configuration where it can be shared by multiple remote senders, while preserving the existing non-debug fast path.
In the Linux kernel, the following vulnerability has been resolved:
drm/imagination: Fit paired fragment job in the correct CCCB
For geometry jobs with a paired fragment job, at the moment, the DRM scheduler's preparejob() callback:
- checks for internal (driver) dependencies for the geometry job; - calls into pvrqueuegetpairedfragjobdep() to check for external dependencies for the fragment job (the two jobs are submitted together but the common scheduler code doesn't know about it, so this needs to be done at this point in time); - calls into the preparejob() callback again, but for the fragment job, to check its internal dependencies as well, passing the fragment job's drmschedjob and the geometry job's drmschedentity / pvrqueue.
The problem with the last step is that pvrqueuepreparejob() doesn't always take the mismatched fragment job and geometry queue into account, in particular when checking whether there is space for the fragment command to be submitted, so the code ends up checking for space in the geometry (i.e. wrong) CCCB. The rest of the nested preparejob() callback happens to work fine at the moment as the other internal dependencies are not relevant for a paired fragment job.
Move the initialisation of a paired fragment job's done fence and CCCB fence to pvrqueuegetpairedfragjobdep(), inferring the correct queue from the fragment job itself.
This fixes cases where preparejob() wrongly assumed that there was enough space for a paired fragment job in its own CCCB, unblocking runjob(), which then returned early without writing the full sequence of commands to the CCCB.
The above lead to kernel warnings such as the following and potentially job timeouts (depending on waiters on the missing commands):
[ 552.421075] WARNING: drivers/gpu/drm/imagination/pvrcccb.c:178 at pvrcccbwritecommandwithheader+0x2c4/0x330 [powervr], CPU#2: kworker/u16:5/63 [ 552.421230] Modules linked in: [ 552.421592] CPU: 2 UID: 0 PID: 63 Comm: kworker/u16:5 Tainted: G W 7.0.0-rc2-gc5d053e4dccb #39 PREEMPT [ 552.421625] Tainted: [W]=WARN [ 552.421637] Hardware name: Texas Instruments AM625 SK (DT) [ 552.421655] Workqueue: powervr-sched drmschedrunjobwork [gpusched] [ 552.421744] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 552.421766] pc : pvrcccbwritecommandwithheader+0x2c4/0x330 [powervr] [ 552.421850] lr : pvrqueuesubmitjobtocccb+0x57c/0xa74 [powervr] [ 552.421923] sp : ffff800084c47650 [ 552.421936] x29: ffff800084c47740 x28: 0000000000000df8 x27: ffff800088a77000 [ 552.421979] x26: 0000000000000030 x25: ffff800084c47680 x24: 0000000000001000 [ 552.422017] x23: ffff800084c47820 x22: 1ffff00010988ecc x21: 0000000000000008 [ 552.422055] x20: 0000000000000208 x19: ffff000006ad5a88 x18: 0000000000000000 [ 552.422093] x17: 0000000020020000 x16: 0000000000020000 x15: 0000000000000000 [ 552.422130] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 [ 552.422167] x11: 000000000000f2f2 x10: 00000000f3000000 x9 : 00000000f3f3f3f3 [ 552.422204] x8 : 00000000f2f2f200 x7 : ffff700010988ecc x6 : 0000000000000008 [ 552.422241] x5 : 0000000000000000 x4 : 1ffff0001114ee00 x3 : 0000000000000000 [ 552.422278] x2 : 0000000000000007 x1 : 0000000000000fff x0 : 000000000000002f [ 552.422316] Call trace: [ 552.422330] pvrcccbwritecommandwithheader+0x2c4/0x330 [powervr] (P) [ 552.422411] pvrqueuesubmitjobtocccb+0x57c/0xa74 [powervr] [ 552.422486] pvrqueuerunjob+0x3a4/0x990 [powervr] [ 552.422562] drmschedrunjobwork+0x580/0xd48 [gpusched] [ 552.422623] processonework+0x520/0x1288 [ 552.422657] workerthread+0x3f0/0xb3c [ 552.422679] kthread+0x334/0x3d8 [ 552.422706] retfromfork+0x10/0x20
In the Linux kernel, the following vulnerability has been resolved:
xfrm: clear mode callbacks after failed mode setup
xfrmstategctask can run long after a failed IPTFS state setup. In the reproduced case, xfrminitstate() cached x->modecbs, IPTFS setup returned -ENOMEM before publishing modedata, and the temporary module reference from xfrmgetmodecbs() was dropped immediately. The dead state then kept x->modecbs until deferred GC ran after xfrmiptfs had been unloaded.
Clear x->modecbs when mode init or clone fails before publishing modedata. Those states never installed mode-specific state or the long-term IPTFS module pin, so deferred GC has nothing mode-specific to destroy and must not retain a callback table pointer past the temporary lookup reference.
The buggy scenario involves two paths, with each column showing the order within that path:
failed setup path: 1. cache x->modecbs 2. mode setup fails before modedata 3. drop the temporary module ref 4. dead state keeps x->modecbs cached
GC/unload path: 1. xfrmstateput() queues GC work 2. xfrmiptfs unloads later 3. xfrmstategctask runs 4. GC dereferences stale x->modecbs
This also covers the failed clone path where clonestate() returns before publishing modedata.
Validation reproduced this kernel report: Kernel panic - not syncing: Fatal exception CONFIGFAULTINJECTIONSTACKTRACEFILTER=y failslabstacktracefilter matched xfrmiptfs frames ackerror=-12 FAULTINJECTION: forcing a failure BUG: unable to handle page fault Workqueue: events xfrmstategctask RIP: xfrmstategctask+0x142/0x650 Modules linked in: esp4offload xfrmuser [last unloaded: xfrmiptfs] Kernel panic - not syncing: Fatal exception
In the Linux kernel, the following vulnerability has been resolved:
drm/xe/vf: Add drmdev guards when detaching CCS read/write buffers
CCS read/write buffers are freed during BO destruction. In some cases, BOs may be destroyed after the device is unbound but while the DRM structure remains valid, leading to NULL pointer dereferences when accessing device resources.
BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 0 UID: 0 PID: 9376 Comm: xepat Not tainted 7.2.0-rc2+ #1 PREEMPT(lazy) RIP: 0010:xesriovvfccsrwupdatebbaddr+0x4d/0xa0 [xe] RSP: 0018:ffffcf304110b9c8 EFLAGS: 00010246 RAX: ffff8a85c38a0a00 RBX: 00000000810ef000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff8a85c39c1888 RBP: ffffcf304110b9e8 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff8a85c39c1888 R13: 0000000000000000 R14: ffff8a85c39b4f28 R15: ffff8a85c3885000 FS: 0000000000000000(0000) GS:ffff8a878b809000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000010314a002 CR4: 0000000000772ef0 PKRU: 55555554 Call Trace: <TASK> xemigrateccsrwcopyclear+0x98/0x120 [xe] xesriovvfccsdetachbo+0x2c/0x60 [xe] xettmbodeletememnotify+0xc8/0xe0 [xe] ttmbocleanupmemtypeuse+0x26/0x80 [ttm] ttmborelease+0x29e/0x2d0 [ttm] ttmbofini+0x39/0x70 [ttm] xegemobjectfree+0x1f/0x30 [xe] drmgemobjectfree+0x1d/0x40 ttmbovmclose+0x5f/0x90 [ttm] removevma+0x2c/0x70 teardownvmas+0x63/0xf0 exitmmap+0x20d/0x3f0 mmput+0x45/0x170 mmput+0x31/0x40 doexit+0x2ba/0xac0 dogroupexit+0x2d/0xb0 x64sysexitgroup+0x18/0x20 x64syscall+0x14a0/0x2390 dosyscall64+0xdd/0x640 ? countmemcgevents+0xea/0x240 ? handlemmfault+0x1ec/0x2f0
(cherry picked from commit 1ae415a6eefe5004954a1d352b1718faca8844ef)
In the Linux kernel, the following vulnerability has been resolved:
drm/imagination: Fix double call to drmschedentityfini()
Call sequence of double call: pvrcontextdestroy pvrcontextkillqueues pvrqueuekill drmschedentitydestroy drmschedentityfini // here pvrcontextput krefput(..., pvrcontextrelease) pvrcontextdestroyqueues pvrqueuedestroy drmschedentityfini // here
Call to drmschedentitydestroy() from pvrcontextkillqueues() calls drmschedentityflush() + drmschedentityfini(). drmschedentityflush() ensures all pending jobs are completed and drmschedentityfini() ensures no further submission is allowed as per expectation from pvrcontextkillqueues(). Double call to drmschedentityfini() is misuse of the API so keep call only in pvrcontextcreate() failure path.
Stack trace for issue with addition of refcounting for DRM entity stats in commit fd177135f0e6 ("drm/sched: Account entity GPU time"):
[ 789.490527] ------------[ cut here ]------------ [ 789.490559] refcountt: underflow; use-after-free. [ 789.490657] WARNING: lib/refcount.c:28 at refcountwarnsaturate+0xf4/0x144, CPU#0: kworker/u16:1/440 [ 789.490695] Modules linked in: powervr drmgpuvm drmexec gpusched drmshmemhelper xhciplathcd xhcihcd dwc3 usbcore usbcommon sndsocsimplecard sndsocsimplecardutils sa2ul sha512 sha256 dwc3am62 sha1 authenc rtiwdt libsha512 at24 schfqcodel fuse dmmod ipv6 [ 789.490798] CPU: 0 UID: 0 PID: 440 Comm: kworker/u16:1 Not tainted 7.0.0-rc7-02049-g5e2c0700091b #22 PREEMPT [ 789.490809] Hardware name: Texas Instruments AM625 SK (DT) [ 789.490815] Workqueue: powervr-sched pvrqueuefencereleasework [powervr] [ 789.490868] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 789.490876] pc : refcountwarnsaturate+0xf4/0x144 [ 789.490884] lr : refcountwarnsaturate+0xf4/0x144 [ 789.490892] sp : ffff8000822cbcc0 [ 789.490895] x29: ffff8000822cbcc0 x28: 0000000000000000 x27: 0000000000000000 [ 789.490909] x26: 0000000000000000 x25: ffff800081b1e338 x24: ffff000004541405 [ 789.490922] x23: ffff000004bea950 x22: ffff00000042e400 x21: ffff000007123e30 [ 789.490935] x20: ffff000007123000 x19: ffff000007a80d50 x18: fffffffffffe7768 [ 789.490948] x17: 74736574202c6e6f x16: 697461746e656d65 x15: ffff800081b269f0 [ 789.490962] x14: 0000000000000030 x13: ffff800081b26a70 x12: 0000000000000211 [ 789.490975] x11: 00000000000000c0 x10: 0000000000000b50 x9 : ffff8000822cbb30 [ 789.490988] x8 : ffff0000014e7bb0 x7 : ffff00007725e780 x6 : 0000000372a05f49 [ 789.491001] x5 : 0000000000000000 x4 : 0000000000000001 x3 : 0000000000000010 [ 789.491013] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000014e7000 [ 789.491027] Call trace: [ 789.491032] refcountwarnsaturate+0xf4/0x144 (P) [ 789.491043] drmschedentityfini+0x164/0x18c [gpusched] [ 789.491081] pvrqueuedestroy+0x64/0x134 [powervr] [ 789.491110] pvrcontextdestroyqueues+0x34/0x64 [powervr] [ 789.491138] pvrcontextrelease+0x70/0xac [powervr] [ 789.491166] pvrcontextput.part.0+0x5c/0x7c [powervr] [ 789.491193] pvrcontextput+0x14/0x24 [powervr] [ 789.491221] pvrqueuefencereleasework+0x20/0x38 [powervr] [ 789.491249] processonework+0x160/0x4c4 [ 789.491264] workerthread+0x188/0x310 [ 789.491276] kthread+0x130/0x13c [ 789.491287] retfromfork+0x10/0x20 [ 789.491300] ---[ end trace 0000000000000000 ]---
In the Linux kernel, the following vulnerability has been resolved:
HID: hid-lenovo-go: cancel cfgsetup work in hidgocfgremove()
hidgocfgprobe() initialises drvdata.gocfgsetup and schedules it to run 2 ms later:
INITDELAYEDWORK(&drvdata.gocfgsetup, &cfgsetup); scheduledelayedwork(&drvdata.gocfgsetup, msecstojiffies(2));
cfgsetup() dereferences drvdata.hdev to issue MCU command requests. hidgocfgremove() tears down sysfs and stops the HID device, but never drains the delayed work. If the device is unbound within the 2 ms scheduling delay (a probe failure rolling back via remove, or a fast rmmod after probe), the work fires after hiddestroydevice() has dropped its reference and released the underlying hdev struct, leaving cfgsetup() with a stale drvdata.hdev pointer.
Mirror the sibling driver hid-lenovo-go-s.c, whose hidgoscfgremove() already calls canceldelayedworksync() on its analogous work, and drain gocfgsetup at the top of hidgocfgremove(). The cancel must come before guard(mutex)(&drvdata.cfgmutex) because cfgsetup() acquires that mutex; reversing the order would deadlock.