In the Linux kernel, the following vulnerability has been resolved:
x86/mm: Eliminate window where TLB flushes may be inadvertently skipped
tl;dr: There is a window in the mm switching code where the new CR3 is set and the CPU should be getting TLB flushes for the new mm. But shouldflushtlb() has a bug and suppresses the flush. Fix it by widening the window where shouldflushtlb() sends an IPI.
Long Version:
=== History ===
There were a few things leading up to this.
First, updating mmcpumask() was observed to be too expensive, so it was made lazier. But being lazy caused too many unnecessary IPIs to CPUs due to the now-lazy mmcpumask(). So code was added to cull mmcpumask() periodically[2]. But that culling was a bit too aggressive and skipped sending TLB flushes to CPUs that need them. So here we are again.
=== Problem ===
The too-aggressive code in shouldflushtlb() strikes in this window:
// Turn on IPIs for this CPU/mm combination, but only // if shouldflushtlb() agrees: cpumasksetcpu(cpu, mmcpumask(next));
nexttlbgen = atomic64read(&next->context.tlbgen); choosenewasid(next, nexttlbgen, &newasid, &needflush); loadnewmmcr3(needflush); // ^ After 'needflush' is set to false, IPIs MUST // be sent to this CPU and not be ignored.
thiscpuwrite(cputlbstate.loadedmm, next); // ^ Not until this point does shouldflushtlb() // become true!
shouldflushtlb() will suppress TLB flushes between loadnewmmcr3() and writing to 'loadedmm', which is a window where they should not be suppressed. Whoops.
=== Solution ===
Thankfully, the fuzzy "just about to write CR3" window is already marked with loadedmm==LOADEDMMSWITCHING. Simply checking for that state in shouldflushtlb() is sufficient to ensure that the CPU is targeted with an IPI.
This will cause more TLB flush IPIs. But the window is relatively small and I do not expect this to cause any kind of measurable performance impact.
Update the comment where LOADEDMMSWITCHING is written since it grew yet another user.
Peter Z also raised a concern that shouldflushtlb() might not observe 'loadedmm' and 'islazy' in the same order that switchmmirqsoff() writes them. Add a barrier to ensure that they are observed in the order they are written.
In the Linux kernel, the following vulnerability has been resolved:
net: ethernet: mtk-star-emac: fix spinlock recursion issues on rx/tx poll
Use spinlockirqsave and spinunlockirqrestore instead of spinlock and spinunlock in mtkstaremac driver to avoid spinlock recursion occurrence that can happen when enabling the DMA interrupts again in rx/tx poll.
BUG: spinlock recursion on CPU#0, swapper/0/0 lock: 0xffff00000db9cf20, .magic: dead4ead, .owner: swapper/0/0, .ownercpu: 0 CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.15.0-rc2-next-20250417-00001-gf6a27738686c-dirty #28 PREEMPT Hardware name: MediaTek MT8365 Open Platform EVK (DT) Call trace: showstack+0x18/0x24 (C) dumpstacklvl+0x60/0x80 dumpstack+0x18/0x24 spindump+0x78/0x88 dorawspinlock+0x11c/0x120 rawspinlock+0x20/0x2c mtkstarhandleirq+0xc0/0x22c [mtkstaremac] handleirqeventpercpu+0x48/0x140 handleirqevent+0x4c/0xb0 handlefasteoiirq+0xa0/0x1bc handleirqdesc+0x34/0x58 generichandledomainirq+0x1c/0x28 gichandleirq+0x4c/0x120 dointerrupthandler+0x50/0x84 el1interrupt+0x34/0x68 el1h64irqhandler+0x18/0x24 el1h64irq+0x6c/0x70 regmapmmioread32le+0xc/0x20 (P) regmapbusregread+0x6c/0xac regmapread+0x60/0xdc regmapread+0x4c/0x80 mtkstarrxpoll+0x2f4/0x39c [mtkstaremac] napipoll+0x38/0x188 netrxaction+0x164/0x2c0 handlesoftirqs+0x100/0x244 dosoftirq+0x14/0x20 dosoftirq+0x10/0x20 callonirqstack+0x24/0x64 dosoftirqownstack+0x1c/0x40 irqexitrcu+0xd4/0x10c irqexitrcu+0x10/0x1c el1interrupt+0x38/0x68 el1h64irqhandler+0x18/0x24 el1h64irq+0x6c/0x70 cpuidleenterstate+0xac/0x320 (P) cpuidleenter+0x38/0x50 doidle+0x1e4/0x260 cpustartupentry+0x34/0x3c restinit+0xdc/0xe0 consoleonrootfs+0x0/0x6c primaryswitched+0x88/0x90
drm/amd/display: Fix slab-use-after-free in hdcp
In the Linux kernel, the following vulnerability has been resolved:
RDMA/core: Fix "KASAN: slab-use-after-free Read in ibregisterdevice" problem
Call Trace:
dumpstack lib/dumpstack.c:94 [inline] dumpstacklvl+0x116/0x1f0 lib/dumpstack.c:120 printaddressdescription mm/kasan/report.c:408 [inline] printreport+0xc3/0x670 mm/kasan/report.c:521 kasanreport+0xe0/0x110 mm/kasan/report.c:634 strlen+0x93/0xa0 lib/string.c:420 fortifystrlen include/linux/fortify-string.h:268 [inline] getkobjpathlength lib/kobject.c:118 [inline] kobjectgetpath+0x3f/0x2a0 lib/kobject.c:158 kobjectueventenv+0x289/0x1870 lib/kobjectuevent.c:545 ibregisterdevice drivers/infiniband/core/device.c:1472 [inline] ibregisterdevice+0x8cf/0xe00 drivers/infiniband/core/device.c:1393 rxeregisterdevice+0x275/0x320 drivers/infiniband/sw/rxe/rxeverbs.c:1552 rxenetadd+0x8e/0xe0 drivers/infiniband/sw/rxe/rxenet.c:550 rxenewlink+0x70/0x190 drivers/infiniband/sw/rxe/rxe.c:225 nldevnewlink+0x3a3/0x680 drivers/infiniband/core/nldev.c:1796 rdmanlrcvmsg+0x387/0x6e0 drivers/infiniband/core/netlink.c:195 rdmanlrcvskb.constprop.0.isra.0+0x2e5/0x450 netlinkunicastkernel net/netlink/afnetlink.c:1313 [inline] netlinkunicast+0x53a/0x7f0 net/netlink/afnetlink.c:1339 netlinksendmsg+0x8d1/0xdd0 net/netlink/afnetlink.c:1883 socksendmsgnosec net/socket.c:712 [inline] socksendmsg net/socket.c:727 [inline] syssendmsg+0xa95/0xc70 net/socket.c:2566 syssendmsg+0x134/0x1d0 net/socket.c:2620 syssendmsg+0x16d/0x220 net/socket.c:2652 dosyscallx64 arch/x86/entry/syscall64.c:63 [inline] dosyscall64+0xcd/0x260 arch/x86/entry/syscall64.c:94 entrySYSCALL64afterhwframe+0x77/0x7f
This problem is similar to the problem that the commit 1d6a9e7449e2 ("RDMA/core: Fix use-after-free when rename device name") fixes.
The root cause is: the function ibdevicerename() renames the name with lock. But in the function kobjectuevent(), this name is accessed without lock protection at the same time.
The solution is to add the lock protection when this name is accessed in the function kobjectuevent().
In the Linux kernel, the following vulnerability has been resolved:
net: dsa: free routing table on probe failure
If complete = true in dsatreesetup(), it means that we are the last switch of the tree which is successfully probing, and we should be setting up all switches from our probe path.
After "complete" becomes true, dsatreesetupcpuports() or any subsequent function may fail. If that happens, the entire tree setup is in limbo: the first N-1 switches have successfully finished probing (doing nothing but having allocated persistent memory in the tree's dst->ports, and maybe dst->rtable), and switch N failed to probe, ending the tree setup process before anything is tangible from the user's PoV.
If switch N fails to probe, its memory (ports) will be freed and removed from dst->ports. However, the dst->rtable elements pointing to its ports, as created by dsalinktouch(), will remain there, and will lead to use-after-free if dereferenced.
If dsatreesetupswitches() returns -EPROBEDEFER, which is entirely possible because that is where ds->ops->setup() is, we get a kasan report like this:
================================================================== BUG: KASAN: slab-use-after-free in mv88e6xxxsetupupstreamport+0x240/0x568 Read of size 8 at addr ffff000004f56020 by task kworker/u8:3/42
Call trace: asanreportload8noabort+0x20/0x30 mv88e6xxxsetupupstreamport+0x240/0x568 mv88e6xxxsetup+0xebc/0x1eb0 dsaregisterswitch+0x1af4/0x2ae0 mv88e6xxxregisterswitch+0x1b8/0x2a8 mv88e6xxxprobe+0xc4c/0xf60 mdioprobe+0x78/0xb8 reallyprobe+0x2b8/0x5a8 driverprobedevice+0x164/0x298 driverprobedevice+0x78/0x258 deviceattachdriver+0x274/0x350
Allocated by task 42: kasankmalloc+0x84/0xa0 kmalloccachenoprof+0x298/0x490 dsaswitchtouchports+0x174/0x3d8 dsaregisterswitch+0x800/0x2ae0 mv88e6xxxregisterswitch+0x1b8/0x2a8 mv88e6xxxprobe+0xc4c/0xf60 mdioprobe+0x78/0xb8 reallyprobe+0x2b8/0x5a8 driverprobedevice+0x164/0x298 driverprobedevice+0x78/0x258 deviceattachdriver+0x274/0x350
Freed by task 42: kasanslabfree+0x48/0x68 kfree+0x138/0x418 dsaregisterswitch+0x2694/0x2ae0 mv88e6xxxregisterswitch+0x1b8/0x2a8 mv88e6xxxprobe+0xc4c/0xf60 mdioprobe+0x78/0xb8 reallyprobe+0x2b8/0x5a8 driverprobedevice+0x164/0x298 driverprobedevice+0x78/0x258 deviceattachdriver+0x274/0x350
The simplest way to fix the bug is to delete the routing table in its entirety. dsatreesetuproutingtable() has no problem in regenerating it even if we deleted links between ports other than those of switch N, because dsalinktouch() first checks whether the port pair already exists in dst->rtable, allocating if not.
The deletion of the routing table in its entirety already exists in dsatreeteardown(), so refactor that into a function that can also be called from the tree setup error path.
In my analysis of the commit to blame, it is the one which added dsalink elements to dst->rtable. Prior to that, each switch had its own ds->rtable which is freed when the switch fails to probe. But the tree is potentially persistent memory.
In the Linux kernel, the following vulnerability has been resolved:
RDMA/rxe: Fix slab-use-after-free Read in rxequeuecleanup bug
Call Trace: <TASK> dumpstack lib/dumpstack.c:94 [inline] dumpstacklvl+0x7d/0xa0 lib/dumpstack.c:120 printaddressdescription mm/kasan/report.c:378 [inline] printreport+0xcf/0x610 mm/kasan/report.c:489 kasanreport+0xb5/0xe0 mm/kasan/report.c:602 rxequeuecleanup+0xd0/0xe0 drivers/infiniband/sw/rxe/rxequeue.c:195 rxecqcleanup+0x3f/0x50 drivers/infiniband/sw/rxe/rxecq.c:132 rxecleanup+0x168/0x300 drivers/infiniband/sw/rxe/rxepool.c:232 rxecreatecq+0x22e/0x3a0 drivers/infiniband/sw/rxe/rxeverbs.c:1109 createcq+0x658/0xb90 drivers/infiniband/core/uverbscmd.c:1052 ibuverbscreatecq+0xc7/0x120 drivers/infiniband/core/uverbscmd.c:1095 ibuverbswrite+0x969/0xc90 drivers/infiniband/core/uverbsmain.c:679 vfswrite fs/readwrite.c:677 [inline] vfswrite+0x26a/0xcc0 fs/readwrite.c:659 ksyswrite+0x1b8/0x200 fs/readwrite.c:731 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0xaa/0x1b0 arch/x86/entry/common.c:83 entrySYSCALL64afterhwframe+0x77/0x7f
In the function rxecreatecq, when rxecqfrominit fails, the function rxecleanup will be called to handle the allocated resources. In fact, some memory resources have already been freed in the function rxecqfrominit. Thus, this problem will occur.
The solution is to let rxecleanup do all the work.
In the Linux kernel, the following vulnerability has been resolved:
riscv: uprobes: Add missing fence.i after building the XOL buffer
The XOL (execute out-of-line) buffer is used to single-step the replaced instruction(s) for uprobes. The RISC-V port was missing a proper fence.i (i$ flushing) after constructing the XOL buffer, which can result in incorrect execution of stale/broken instructions.
This was found running the BPF selftests "testprogs: uprobeautoattach, attachprobe" on the Spacemit K1/X60, where the uprobes tests randomly blew up.
In the Linux kernel, the following vulnerability has been resolved:
xsk: Fix race condition in AFXDP generic RX path
Move rxlock from xsksocket to xskbuffpool. Fix synchronization for shared umem mode in generic RX path where multiple sockets share single xskbuffpool.
RX queue is exclusive to xsksocket, while FILL queue can be shared between multiple sockets. This could result in race condition where two CPU cores access RX path of two different sockets sharing the same umem.
Protect both queues by acquiring spinlock in shared xskbuffpool.
Lock contention may be minimized in the future by some per-thread FQ buffering.
It's safe and necessary to move spinlockbh(rxlock) after xskrcvcheck(): xs->pool and spinlockinit is synchronized by xskbind() -> xskisbound() memory barriers. xskrcvcheck() may return true at the moment of xskrelease() or xskunbinddev(), however this will not cause any data races or race conditions. xskunbinddev() removes xdp socket from all maps and waits for completion of all outstanding rx operations. Packets in RX path will either complete safely or drop.
btrfs: adjust subpage bit start based on sectorsize
In the Linux kernel, the following vulnerability has been resolved:
KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception
Previously, commit ed129ec9057f ("KVM: x86: forcibly leave nested mode on vCPU reset") addressed an issue where a triple fault occurring in nested mode could lead to use-after-free scenarios. However, the commit did not handle the analogous situation for System Management Mode (SMM).
This omission results in triggering a WARN when KVM forces a vCPU INIT after SHUTDOWN interception while the vCPU is in SMM. This situation was reprodused using Syzkaller by:
1) Creating a KVM VM and vCPU 2) Sending a KVMSMI ioctl to explicitly enter SMM 3) Executing invalid instructions causing consecutive exceptions and eventually a triple fault
The issue manifests as follows:
WARNING: CPU: 0 PID: 25506 at arch/x86/kvm/x86.c:12112 kvmvcpureset+0x1d2/0x1530 arch/x86/kvm/x86.c:12112 Modules linked in: CPU: 0 PID: 25506 Comm: syz-executor.0 Not tainted 6.1.130-syzkaller-00157-g164fe5dde9b6 #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:kvmvcpureset+0x1d2/0x1530 arch/x86/kvm/x86.c:12112 Call Trace: <TASK> shutdowninterception+0x66/0xb0 arch/x86/kvm/svm/svm.c:2136 svminvokeexithandler+0x110/0x530 arch/x86/kvm/svm/svm.c:3395 svmhandleexit+0x424/0x920 arch/x86/kvm/svm/svm.c:3457 vcpuenterguest arch/x86/kvm/x86.c:10959 [inline] vcpurun+0x2c43/0x5a90 arch/x86/kvm/x86.c:11062 kvmarchvcpuioctlrun+0x50f/0x1cf0 arch/x86/kvm/x86.c:11283 kvmvcpuioctl+0x570/0xf00 arch/x86/kvm/../../../virt/kvm/kvmmain.c:4122 vfsioctl fs/ioctl.c:51 [inline] dosysioctl fs/ioctl.c:870 [inline] sesysioctl fs/ioctl.c:856 [inline] x64sysioctl+0x19a/0x210 fs/ioctl.c:856 dosyscallx64 arch/x86/entry/common.c:51 [inline] dosyscall64+0x35/0x80 arch/x86/entry/common.c:81 entrySYSCALL64afterhwframe+0x6e/0xd8
Architecturally, INIT is blocked when the CPU is in SMM, hence KVM's WARN() in kvmvcpureset() to guard against KVM bugs, e.g. to detect improper emulation of INIT. SHUTDOWN on SVM is a weird edge case where KVM needs to do something sane with the VMCB, since it's technically undefined, and INIT is the least awful choice given KVM's ABI.
So, double down on stuffing INIT on SHUTDOWN, and force the vCPU out of SMM to avoid any weirdness (and the WARN).
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
[sean: massage changelog, make it clear this isn't architectural behavior]
In the Linux kernel, the following vulnerability has been resolved:
spi: spi-imx: Add check for spiimxsetupxfer()
Add check for the return value of spiimxsetupxfer(). spiimx->rx and spiimx->tx function pointer can be NULL when spiimxsetupxfer() return error, and make NULL pointer dereference.
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 Call trace: 0x0 spiimxpiotransfer+0x50/0xd8 spiimxtransferone+0x18c/0x858 spitransferonemessage+0x43c/0x790 spipumptransfermessage+0x238/0x5d4 spisync+0x2b0/0x454 spiwritethenread+0x11c/0x200
driver core: fix potential NULL pointer dereference in devuevent()
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: l2cap: Check encryption key size on incoming connection
This is required for passing GAP/SEC/SEM/BI-04-C PTS test case: Security Mode 4 Level 4, Responder - Invalid Encryption Key Size - 128 bit
This tests the security key with size from 1 to 15 bytes while the Security Mode 4 Level 4 requests 16 bytes key size.
Currently PTS fails with the following logs: - expected:Connection Response: Code: [3 (0x03)] Code Identifier: (lt)WildCard: Exists(gt) Length: [8 (0x0008)] Destination CID: (lt)WildCard: Exists(gt) Source CID: [64 (0x0040)] Result: [3 (0x0003)] Connection refused - Security block Status: (lt)WildCard: Exists(gt), but received:Connection Response: Code: [3 (0x03)] Code Identifier: [1 (0x01)] Length: [8 (0x0008)] Destination CID: [64 (0x0040)] Source CID: [64 (0x0040)] Result: [0 (0x0000)] Connection Successful Status: [0 (0x0000)] No further information available
And HCI logs: < HCI Command: Read Encrypti.. (0x05|0x0008) plen 2 Handle: 14 Address: 00:1B:DC:F2:24:10 (Vencer Co., Ltd.) HCI Event: Command Complete (0x0e) plen 7 Read Encryption Key Size (0x05|0x0008) ncmd 1 Status: Success (0x00) Handle: 14 Address: 00:1B:DC:F2:24:10 (Vencer Co., Ltd.) Key size: 7 ACL Data RX: Handle 14 flags 0x02 dlen 12 L2CAP: Connection Request (0x02) ident 1 len 4 PSM: 4097 (0x1001) Source CID: 64 < ACL Data TX: Handle 14 flags 0x00 dlen 16 L2CAP: Connection Response (0x03) ident 1 len 8 Destination CID: 64 Source CID: 64 Result: Connection successful (0x0000) Status: No further information available (0x0000)
In the Linux kernel, the following vulnerability has been resolved:
schhfsc: make hfscqlennotify() idempotent
hfscqlennotify() is not idempotent either and not friendly to its callers, like fqcodeldequeue(). Let's make it idempotent to ease qdisctreereducebacklog() callers' life:
1. updatevf() decreases cl->clnactive, so we can check whether it is non-zero before calling it.
2. eltreeremove() always removes RB node cl->elnode, but we can use RBEMPTYNODE() + RBCLEARNODE() to make it safe.
In the Linux kernel, the following vulnerability has been resolved:
espintcp: remove encap socket caching to avoid reference leak
The current scheme for caching the encap socket can lead to reference leaks when we try to delete the netns.
The reference chain is: xfrmstate -> enacpsk -> netns
Since the encap socket is a userspace socket, it holds a reference on the netns. If we delete the espintcp state (through flush or individual delete) before removing the netns, the reference on the socket is dropped and the netns is correctly deleted. Otherwise, the netns may not be reachable anymore (if all processes within the ns have terminated), so we cannot delete the xfrm state to drop its reference on the socket.
This patch results in a small (~2% in my tests) performance regression.
A GC-type mechanism could be added for the socket cache, to clear references if the state hasn't been used "recently", but it's a lot more complex than just not caching the socket.
In the Linux kernel, the following vulnerability has been resolved:
dma-buf: insert memory barrier before updating numfences
smpstoremb() inserts memory barrier after storing operation. It is different with what the comment is originally aiming so Null pointer dereference can be happened if memory update is reordered.
In the Linux kernel, the following vulnerability has been resolved:
gpio: virtuser: fix potential out-of-bound write
If the caller wrote more characters, count is truncated to the max available space in "simplewritetobuffer". Check that the input size does not exceed the buffer size. Write a zero termination afterwards.
In the Linux kernel, the following vulnerability has been resolved:
crypto: algifhash - fix double free in hashaccept
If accept(2) is called on socket type algifhash with MSGMORE flag set and cryptoahashimport fails, sk2 is freed. However, it is also freed in afalgrelease, leading to slab-use-after-free error.
In the Linux kernel, the following vulnerability has been resolved:
ALSA: pcm: Fix race of buffer access at PCM OSS layer
The PCM OSS layer tries to clear the buffer with the silence data at initialization (or reconfiguration) of a stream with the explicit call of sndpcmformatsetsilence() with runtime->dmaarea. But this may lead to a UAF because the accessed runtime->dmaarea might be freed concurrently, as it's performed outside the PCM ops.
For avoiding it, move the code into the PCM core and perform it inside the buffer access lock, so that it won't be changed during the operation.
In the Linux kernel, the following vulnerability has been resolved:
vhost-scsi: protect vq->logused with vq->mutex
The vhost-scsi completion path may access vq->logbase when vq->logused is already set to false.
vhost-thread QEMU-thread
vhostscsicompletecmdwork() -> vhostaddused() -> vhostaddusedn() if (unlikely(vq->logused)) QEMU disables vq->logused via VHOSTSETVRINGADDR. mutexlock(&vq->mutex); vq->logused = false now! mutexunlock(&vq->mutex);
QEMU gfree(vq->logbase) logused() -> logwrite(vq->logbase)
Assuming the VMM is QEMU. The vq->logbase is from QEMU userpace and can be reclaimed via gfree(). As a result, this causes invalid memory writes to QEMU userspace.
The control queue path has the same issue.
In the Linux kernel, the following vulnerability has been resolved:
legitimizemnt(): check for MNTSYNCUMOUNT should be under mountlock
... or we risk stealing final mntput from sync umount - raising mntcount after umount(2) has verified that victim is not busy, but before it has set MNTSYNCUMOUNT; in that case legitimizemnt() doesn't see that it's safe to quietly undo mntcount increment and leaves dropping the reference to caller, where it'll be a full-blown mntput().
Check under mountlock is needed; leaving the current one done before taking that makes no sense - it's nowhere near common enough to bother with.
espintcp: fix skb leaks
In the Linux kernel, the following vulnerability has been resolved:
net/tipc: fix slab-use-after-free Read in tipcaeadencryptdone
Syzbot reported a slab-use-after-free with the following call trace:
================================================================== BUG: KASAN: slab-use-after-free in tipcaeadencryptdone+0x4bd/0x510 net/tipc/crypto.c:840 Read of size 8 at addr ffff88807a733000 by task kworker/1:0/25
Call Trace: kasanreport+0xd9/0x110 mm/kasan/report.c:601 tipcaeadencryptdone+0x4bd/0x510 net/tipc/crypto.c:840 cryptorequestcomplete include/crypto/algapi.h:266 aeadrequestcomplete include/crypto/internal/aead.h:85 cryptdaeadcrypt+0x3b8/0x750 crypto/cryptd.c:772 cryptorequestcomplete include/crypto/algapi.h:266 cryptdqueueworker+0x131/0x200 crypto/cryptd.c:181 processonework+0x9fb/0x1b60 kernel/workqueue.c:3231
Allocated by task 8355: kzallocnoprof include/linux/slab.h:778 tipccryptostart+0xcc/0x9e0 net/tipc/crypto.c:1466 tipcinitnet+0x2dd/0x430 net/tipc/core.c:72 opsinit+0xb9/0x650 net/core/netnamespace.c:139 setupnet+0x435/0xb40 net/core/netnamespace.c:343 copynetns+0x2f0/0x670 net/core/netnamespace.c:508 createnewnamespaces+0x3ea/0xb10 kernel/nsproxy.c:110 unsharensproxynamespaces+0xc0/0x1f0 kernel/nsproxy.c:228 ksysunshare+0x419/0x970 kernel/fork.c:3323 dosysunshare kernel/fork.c:3394
Freed by task 63: kfree+0x12a/0x3b0 mm/slub.c:4557 tipccryptostop+0x23c/0x500 net/tipc/crypto.c:1539 tipcexitnet+0x8c/0x110 net/tipc/core.c:119 opsexitlist+0xb0/0x180 net/core/netnamespace.c:173 cleanupnet+0x5b7/0xbf0 net/core/netnamespace.c:640 processonework+0x9fb/0x1b60 kernel/workqueue.c:3231
After freed the tipccrypto tx by delete namespace, tipcaeadencryptdone may still visit it in cryptdqueueworker workqueue.
I reproduce this issue by: ip netns add ns1 ip link add veth1 type veth peer name veth2 ip link set veth1 netns ns1 ip netns exec ns1 tipc bearer enable media eth dev veth1 ip netns exec ns1 tipc node set key thisisamasterkey master ip netns exec ns1 tipc bearer disable media eth dev veth1 ip netns del ns1
The key of reproduction is that, simdaeadencrypt is interrupted, leading to cryptosimdusable() return false. Thus, the cryptdqueueworker is triggered, and the tipccrypto tx will be visited.
tipcdisctimeout tipcbearerxmitskb tipccryptoxmit tipcaeadencrypt cryptoaeadencrypt // encrypt() simdaeadencrypt // cryptosimdusable() is false child = &ctx->cryptdtfm->base;
simdaeadencrypt cryptoaeadencrypt // encrypt() cryptdaeadencryptenqueue cryptdaeadenqueue cryptdenqueuerequest // trigger cryptdqueueworker queueworkon(smpprocessorid(), cryptdwq, &cpuqueue->work)
Fix this by holding net reference count before encrypt.
In the Linux kernel, the following vulnerability has been resolved:
smb: client: Fix use-after-free in cifsfilldirent
There is a race condition in the readdir concurrency process, which may access the rsp buffer after it has been released, triggering the following KASAN warning.
================================================================== BUG: KASAN: slab-use-after-free in cifsfilldirent+0xb03/0xb60 [cifs] Read of size 4 at addr ffff8880099b819c by task a.out/342975
CPU: 2 UID: 0 PID: 342975 Comm: a.out Not tainted 6.15.0-rc6+ #240 PREEMPT(full) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 Call Trace: <TASK> dumpstacklvl+0x53/0x70 printreport+0xce/0x640 kasanreport+0xb8/0xf0 cifsfilldirent+0xb03/0xb60 [cifs] cifsreaddir+0x12cb/0x3190 [cifs] iteratedir+0x1a1/0x520 x64sysgetdents+0x134/0x220 dosyscall64+0x4b/0x110 entrySYSCALL64afterhwframe+0x76/0x7e RIP: 0033:0x7f996f64b9f9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0d f7 c3 0c 00 f7 d8 64 89 8 RSP: 002b:00007f996f53de78 EFLAGS: 00000207 ORIGRAX: 000000000000004e RAX: ffffffffffffffda RBX: 00007f996f53ecdc RCX: 00007f996f64b9f9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003 RBP: 00007f996f53dea0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000207 R12: ffffffffffffff88 R13: 0000000000000000 R14: 00007ffc8cd9a500 R15: 00007f996f51e000 </TASK>
Allocated by task 408: kasansavestack+0x20/0x40 kasansavetrack+0x14/0x30 kasanslaballoc+0x6e/0x70 kmemcacheallocnoprof+0x117/0x3d0 mempoolallocnoprof+0xf2/0x2c0 cifsbufget+0x36/0x80 [cifs] allocatebuffers+0x1d2/0x330 [cifs] cifsdemultiplexthread+0x22b/0x2690 [cifs] kthread+0x394/0x720 retfromfork+0x34/0x70 retfromforkasm+0x1a/0x30
Freed by task 342979: kasansavestack+0x20/0x40 kasansavetrack+0x14/0x30 kasansavefreeinfo+0x3b/0x60 kasanslabfree+0x37/0x50 kmemcachefree+0x2b8/0x500 cifsbufrelease+0x3c/0x70 [cifs] cifsreaddir+0x1c97/0x3190 [cifs] iteratedir+0x1a1/0x520 x64sysgetdents64+0x134/0x220 dosyscall64+0x4b/0x110 entrySYSCALL64afterhwframe+0x76/0x7e
The buggy address belongs to the object at ffff8880099b8000 which belongs to the cache cifsrequest of size 16588 The buggy address is located 412 bytes inside of freed 16588-byte region [ffff8880099b8000, ffff8880099bc0cc)
The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x99b8 head: order:3 mapcount:0 entiremapcount:0 nrpagesmapped:0 pincount:0 anon flags: 0x80000000000040(head|node=0|zone=1) pagetype: f5(slab) raw: 0080000000000040 ffff888001e03400 0000000000000000 dead000000000001 raw: 0000000000000000 0000000000010001 00000000f5000000 0000000000000000 head: 0080000000000040 ffff888001e03400 0000000000000000 dead000000000001 head: 0000000000000000 0000000000010001 00000000f5000000 0000000000000000 head: 0080000000000003 ffffea0000266e01 00000000ffffffff 00000000ffffffff head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff8880099b8080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8880099b8100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff8880099b8180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff8880099b8200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8880099b8280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ==================================================================
POC is available in the link [1].
The problem triggering process is as follows:
Process 1 Process 2 ----------------------------------- ---truncated---
In the Linux kernel, the following vulnerability has been resolved:
nvmet-tcp: don't restore null skstatechange
queue->statechange is set as part of nvmettcpsetqueuesock(), but if the TCP connection isn't established when nvmettcpsetqueuesock() is called then queue->statechange isn't set and sock->sk->skstatechange isn't replaced.
As such we don't need to restore sock->sk->skstatechange if queue->statechange is NULL.
This avoids NULL pointer dereferences such as this:
[ 286.462026][ C0] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 286.462814][ C0] #PF: supervisor instruction fetch in kernel mode [ 286.463796][ C0] #PF: errorcode(0x0010) - not-present page [ 286.464392][ C0] PGD 8000000140620067 P4D 8000000140620067 PUD 114201067 PMD 0 [ 286.465086][ C0] Oops: Oops: 0010 [#1] SMP KASAN PTI [ 286.465559][ C0] CPU: 0 UID: 0 PID: 1628 Comm: nvme Not tainted 6.15.0-rc2+ #11 PREEMPT(voluntary) [ 286.466393][ C0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014 [ 286.467147][ C0] RIP: 0010:0x0 [ 286.467420][ C0] Code: Unable to access opcode bytes at 0xffffffffffffffd6. [ 286.467977][ C0] RSP: 0018:ffff8883ae008580 EFLAGS: 00010246 [ 286.468425][ C0] RAX: 0000000000000000 RBX: ffff88813fd34100 RCX: ffffffffa386cc43 [ 286.469019][ C0] RDX: 1ffff11027fa68b6 RSI: 0000000000000008 RDI: ffff88813fd34100 [ 286.469545][ C0] RBP: ffff88813fd34160 R08: 0000000000000000 R09: ffffed1027fa682c [ 286.470072][ C0] R10: ffff88813fd34167 R11: 0000000000000000 R12: ffff88813fd344c3 [ 286.470585][ C0] R13: ffff88813fd34112 R14: ffff88813fd34aec R15: ffff888132cdd268 [ 286.471070][ C0] FS: 00007fe3c04c7d80(0000) GS:ffff88840743f000(0000) knlGS:0000000000000000 [ 286.471644][ C0] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 286.472543][ C0] CR2: ffffffffffffffd6 CR3: 000000012daca000 CR4: 00000000000006f0 [ 286.473500][ C0] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 286.474467][ C0] DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400 [ 286.475453][ C0] Call Trace: [ 286.476102][ C0] <IRQ> [ 286.476719][ C0] tcpfin+0x2bb/0x440 [ 286.477429][ C0] tcpdataqueue+0x190f/0x4e60 [ 286.478174][ C0] ? buildskbaround+0x234/0x330 [ 286.478940][ C0] ? rcuiswatching+0x11/0xb0 [ 286.479659][ C0] ? pfxtcpdataqueue+0x10/0x10 [ 286.480431][ C0] ? tcptryundoloss+0x640/0x6c0 [ 286.481196][ C0] ? seqcountlockdepreaderaccess.constprop.0+0x82/0x90 [ 286.482046][ C0] ? kvmclockgetcycles+0x14/0x30 [ 286.482769][ C0] ? ktimeget+0x66/0x150 [ 286.483433][ C0] ? rcuiswatching+0x11/0xb0 [ 286.484146][ C0] tcprcvestablished+0x6e4/0x2050 [ 286.484857][ C0] ? rcuiswatching+0x11/0xb0 [ 286.485523][ C0] ? ipv4dstcheck+0x160/0x2b0 [ 286.486203][ C0] ? pfxtcprcvestablished+0x10/0x10 [ 286.486917][ C0] ? lockrelease+0x217/0x2c0 [ 286.487595][ C0] tcpv4dorcv+0x4d6/0x9b0 [ 286.488279][ C0] tcpv4rcv+0x2af8/0x3e30 [ 286.488904][ C0] ? rawlocaldeliver+0x51b/0xad0 [ 286.489551][ C0] ? rcuiswatching+0x11/0xb0 [ 286.490198][ C0] ? pfxtcpv4rcv+0x10/0x10 [ 286.490813][ C0] ? pfxrawlocaldeliver+0x10/0x10 [ 286.491487][ C0] ? pfxnfconfirm+0x10/0x10 [nfconntrack] [ 286.492275][ C0] ? rcuiswatching+0x11/0xb0 [ 286.492900][ C0] ipprotocoldeliverrcu+0x8f/0x370 [ 286.493579][ C0] iplocaldeliverfinish+0x297/0x420 [ 286.494268][ C0] iplocaldeliver+0x168/0x430 [ 286.494867][ C0] ? pfxiplocaldeliver+0x10/0x10 [ 286.495498][ C0] ? pfxiplocaldeliverfinish+0x10/0x10 [ 286.496204][ C0] ? iprcvfinishcore+0x19a/0x1f20 [ 286.496806][ C0] ? lockrelease+0x217/0x2c0 [ 286.497414][ C0] iprcv+0x455/0x6e0 [ 286.497945][ C0] ? pfxiprcv+0x10/0x10 [ ---truncated---
In the Linux kernel, the following vulnerability has been resolved:
NFS/localio: Fix a race in nfslocalopenfh()
Once the clp->cluuid.lock has been dropped, another CPU could come in and free the struct nfsdfile that was just added. To prevent that from happening, take the RCU read lock before dropping the spin lock.
In the Linux kernel, the following vulnerability has been resolved:
net/tls: fix kernel panic when allocpage failed
We cannot set fraglist to NULL pointer when allocpage failed. It will be used in tlsstrpcheckqueueok when the next time tlsstrpreadsock is called.
This is because we don't reset fulllen in tlsstrpflushanchorcopy() so the recv path will try to continue handling the partial record on the next call but we dettached the rcvq from the frag list. Alternative fix would be to reset fulllen.
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028 Call trace: tlsstrpcheckrcv+0x128/0x27c tlsstrpdataready+0x34/0x44 tlsdataready+0x3c/0x1f0 tcpdataready+0x9c/0xe4 tcpdataqueue+0xf6c/0x12d0 tcprcvestablished+0x52c/0x798
In the Linux kernel, the following vulnerability has been resolved:
HID: bpf: abort dispatch if device destroyed
The current HID bpf implementation assumes no output report/request will go through it after hidbpfdestroydevice() has been called. This leads to a bug that unplugging certain types of HID devices causes a cleaned- up SRCU to be accessed. The bug was previously a hidden failure until a recent x86 percpu change [1] made it access not-present pages.
The bug will be triggered if the conditions below are met:
A) a device under the driver has some LEDs on B) hidlldriver->request() is uninplemented (e.g., logitech-djreceiver)
If condition A is met, hidinputledworker() is always scheduled after hidbpfdestroydevice().
hiddestroydevice hidbpfdestroydevice cleanupsrcustruct(&hdev->bpf.srcu) hidremovedevice ... ledclassdevunregister ledtriggerset(ledcdev, NULL) ledsetbrightness(ledcdev, LEDOFF) ... inputinjectevent inputeventdispose hidinputinputevent schedulework(&hid->ledwork) [hidinputledworker]
This is fine when condition B is not met, where hidinputledworker() calls hidlldriver->request(). This is the case for most HID drivers, which implement it or use the generic one from usbhid. The driver itself or an underlying driver will then abort processing the request.
Otherwise, hidinputledworker() tries hidhwoutputreport() and leads to the bug.
hidinputledworker hidhwoutputreport dispatchhidbpfoutputreport srcureadlock(&hdev->bpf.srcu) srcureadunlock(&hdev->bpf.srcu, idx)
The bug has existed since the introduction [2] of dispatchhidbpfoutputreport(). However, the same bug also exists in dispatchhidbpfrawrequests(), and I've reproduced (no visible effect because of the lack of [1], but confirmed bpf.destroyed == 1) the bug against the commit (i.e., the Fixes:) introducing the function. This is because hidinputledworker() falls back to hidhwrawrequest() when hidlldriver->outputreport() is uninplemented (e.g., logitech- djreceiver).
hidinputledworker hidhwoutputreport: -ENOSYS hidhwrawrequest dispatchhidbpfrawrequests srcureadlock(&hdev->bpf.srcu) srcureadunlock(&hdev->bpf.srcu, idx)
Fix the issue by returning early in the two mentioned functions if hidbpf has been marked as destroyed. Though dispatchhidbpfdeviceevent() handles input events, and there is no evidence that it may be called after the destruction, the same check, as a safety net, is also added to it to maintain the consistency among all dispatch functions.
The impact of the bug on other architectures is unclear. Even if it acts as a hidden failure, this is still dangerous because it corrupts whatever is on the address calculated by SRCU. Thus, CC'ing the stable list.
[1]: commit 9d7de2aa8b41 ("x86/percpu/64: Use relative percpu offsets") [2]: commit 9286675a2aed ("HID: bpf: add HID-BPF hooks for hidhwoutputreport")
In the Linux kernel, the following vulnerability has been resolved:
schedext: bpfiterscxdsqnew() should always initialize iterator
BPF programs may call next() and destroy() on BPF iterators even after new() returns an error value (e.g. bpfforeach() macro ignores error returns from new()). bpfiterscxdsqnew() could leave the iterator in an uninitialized state after an error return causing bpfiterscxdsqnext() to dereference garbage data. Make bpfiterscxdsqnew() always clear $kit->dsq so that next() and destroy() become noops.
In the Linux kernel, the following vulnerability has been resolved:
dmaengine: ti: k3-udma: Add missing locking
Recent kernels complain about a missing lock in k3-udma.c when the lock validator is enabled:
[ 4.128073] WARNING: CPU: 0 PID: 746 at drivers/dma/ti/../virt-dma.h:169 udmastart.isra.0+0x34/0x238 [ 4.137352] CPU: 0 UID: 0 PID: 746 Comm: kworker/0:3 Not tainted 6.12.9-arm64 #28 [ 4.144867] Hardware name: pp-v12 (DT) [ 4.148648] Workqueue: events udmachecktxcompletion [ 4.153841] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 4.160834] pc : udmastart.isra.0+0x34/0x238 [ 4.165227] lr : udmastart.isra.0+0x30/0x238 [ 4.169618] sp : ffffffc083cabcf0 [ 4.172963] x29: ffffffc083cabcf0 x28: 0000000000000000 x27: ffffff800001b005 [ 4.180167] x26: ffffffc0812f0000 x25: 0000000000000000 x24: 0000000000000000 [ 4.187370] x23: 0000000000000001 x22: 00000000e21eabe9 x21: ffffff8000fa0670 [ 4.194571] x20: ffffff8001b6bf00 x19: ffffff8000fa0430 x18: ffffffc083b95030 [ 4.201773] x17: 0000000000000000 x16: 00000000f0000000 x15: 0000000000000048 [ 4.208976] x14: 0000000000000048 x13: 0000000000000000 x12: 0000000000000001 [ 4.216179] x11: ffffffc08151a240 x10: 0000000000003ea1 x9 : ffffffc08046ab68 [ 4.223381] x8 : ffffffc083cabac0 x7 : ffffffc081df3718 x6 : 0000000000029fc8 [ 4.230583] x5 : ffffffc0817ee6d8 x4 : 0000000000000bc0 x3 : 0000000000000000 [ 4.237784] x2 : 0000000000000000 x1 : 00000000001fffff x0 : 0000000000000000 [ 4.244986] Call trace: [ 4.247463] udmastart.isra.0+0x34/0x238 [ 4.251509] udmachecktxcompletion+0xd0/0xdc [ 4.256076] processonework+0x244/0x3fc [ 4.260129] processscheduledworks+0x6c/0x74 [ 4.264610] workerthread+0x150/0x1dc [ 4.268398] kthread+0xd8/0xe8 [ 4.271492] retfromfork+0x10/0x20 [ 4.275107] irq event stamp: 220 [ 4.278363] hardirqs last enabled at (219): [<ffffffc080a27c7c>] rawspinunlockirq+0x38/0x50 [ 4.287183] hardirqs last disabled at (220): [<ffffffc080a1c154>] el1dbg+0x24/0x50 [ 4.294879] softirqs last enabled at (182): [<ffffffc080037e68>] handlesoftirqs+0x1c0/0x3cc [ 4.303437] softirqs last disabled at (177): [<ffffffc080010170>] dosoftirq+0x1c/0x28 [ 4.311559] ---[ end trace 0000000000000000 ]---
This commit adds the missing locking.