In the Linux kernel, the following vulnerability has been resolved:
linkwatch: use devput() in callers to prevent UAF
After linkwatchdodev() calls devput() to release the linkwatch reference, the device refcount may drop to 1. At this point, netdevruntodo() can proceed (since linkwatchsyncdev() sees an empty list and returns without blocking), wait for the refcount to become 1 via netdevwaitallrefsany(), and then free the device via kobjectput().
This creates a use-after-free when linkwatchrunqueue() tries to call netdevunlockops() on the already-freed device.
Note that adding netdevlockops()/netdevunlockops() pair in netdevruntodo() before kobjectput() would not work, because netdevlockops() is conditional - it only locks when netdevneedopslock() returns true. If the device doesn't require opslock, linkwatch won't hold any lock, and netdevruntodo() acquiring the lock won't provide synchronization.
Fix this by moving devput() from linkwatchdodev() to its callers. The device reference logically pairs with de-listing the device, so it's reasonable for the caller that did the de-listing to release it. This allows placing devput() after all device accesses are complete, preventing UAF.
The bug can be reproduced by adding mdelay(2000) after linkwatchdodev() in linkwatchrunqueue(), then running:
ip tuntap add mode tun name tuntest ip link set tuntest up ip link set tuntest carrier off ip link set tuntest carrier on sleep 0.5 ip tuntap del mode tun name tuntest
KASAN report:
================================================================== BUG: KASAN: use-after-free in netdevneedopslock include/net/netdevlock.h:33 [inline] BUG: KASAN: use-after-free in netdevunlockops include/net/netdevlock.h:47 [inline] BUG: KASAN: use-after-free in linkwatchrunqueue+0x865/0x8a0 net/core/linkwatch.c:245 Read of size 8 at addr ffff88804de5c008 by task kworker/u32:10/8123
CPU: 0 UID: 0 PID: 8123 Comm: kworker/u32:10 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Workqueue: eventsunbound linkwatchevent Call Trace: <TASK> dumpstack lib/dumpstack.c:94 [inline] dumpstacklvl+0x100/0x190 lib/dumpstack.c:120 printaddressdescription mm/kasan/report.c:378 [inline] printreport+0x156/0x4c9 mm/kasan/report.c:482 kasanreport+0xdf/0x1a0 mm/kasan/report.c:595 netdevneedopslock include/net/netdevlock.h:33 [inline] netdevunlockops include/net/netdevlock.h:47 [inline] linkwatchrunqueue+0x865/0x8a0 net/core/linkwatch.c:245 linkwatchevent+0x8f/0xc0 net/core/linkwatch.c:304 processonework+0x9c2/0x1840 kernel/workqueue.c:3257 processscheduledworks kernel/workqueue.c:3340 [inline] workerthread+0x5da/0xe40 kernel/workqueue.c:3421 kthread+0x3b3/0x730 kernel/kthread.c:463 retfromfork+0x754/0xaf0 arch/x86/kernel/process.c:158 retfromforkasm+0x1a/0x30 arch/x86/entry/entry64.S:246 </TASK> ==================================================================
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:
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:
drm/amd/display: check stream id dml21 wrapper to get planeid
[Why & How] Fix a false positive warning which occurs due to lack of correct checks when querying planeid in DML21. This fixes the warning when performing a mode1 reset (cat /sys/kernel/debug/dri/1/amdgpugpurecover):
[ 35.751250] WARNING: CPU: 11 PID: 326 at /tmp/amd.PHpyAl7v/amd/amdgpu/../display/dc/dml2/dml2dcresourcemgmt.c:91 dml2mapdcpipes+0x243d/0x3f40 [amdgpu] [ 35.751434] Modules linked in: amdgpu(OE) amddrmttmhelper(OE) amdttm(OE) amddrmbuddy(OE) amdxcp(OE) amddrmexec(OE) amdsched(OE) amdkcl(OE) drmsuballochelper drmttmhelper ttm drmdisplayhelper cec rccore i2calgobit rfcomm qrtr cmac algifhash algifskcipher afalg bnep amdatl intelraplmsr intelraplcommon sndhdacodechdmi sndhdaintel edacmceamd sndinteldspcfg sndintelsdwacpi sndhdacodec kvmamd sndhdacore sndhwdep sndpcm kvm sndseqmidi sndseqmidievent sndrawmidi crct10difpclmul polyvalclmulni polyvalgeneric btusb ghashclmulniintel sha256ssse3 btrtl sha1ssse3 sndseq btintel aesniintel btbcm btmtk sndseqdevice cryptosimd sunrpc cryptd bluetooth sndtimer ccp binfmtmisc rapl snd i2cpiix4 wmibmof gigabytewmi k10temp i2csmbus soundcore gpioamdpt machid schfqcodel msr parportpc ppdev lp parport efipstore nfnetlink dmisysfs iptables xtables autofs4 hidgeneric usbhid hid crc32pclmul igc ahci xhcipci libahci xhcipcirenesas video wmi [ 35.751501] CPU: 11 UID: 0 PID: 326 Comm: kworker/u64:9 Tainted: G OE 6.11.0-21-generic #21~24.04.1-Ubuntu [ 35.751504] Tainted: [O]=OOTMODULE, [E]=UNSIGNEDMODULE [ 35.751505] Hardware name: Gigabyte Technology Co., Ltd. X670E AORUS PRO X/X670E AORUS PRO X, BIOS F30 05/22/2024 [ 35.751506] Workqueue: amdgpu-reset-dev amdgpudebugfsresetwork [amdgpu] [ 35.751638] RIP: 0010:dml2mapdcpipes+0x243d/0x3f40 [amdgpu] [ 35.751794] Code: 6d 0c 00 00 8b 84 24 88 00 00 00 41 3b 44 9c 20 0f 84 fc 07 00 00 48 83 c3 01 48 83 fb 06 75 b3 4c 8b 64 24 68 4c 8b 6c 24 40 <0f> 0b b8 06 00 00 00 49 8b 94 24 a0 49 00 00 89 c3 83 f8 07 0f 87 [ 35.751796] RSP: 0018:ffffbfa3805d7680 EFLAGS: 00010246 [ 35.751798] RAX: 0000000000010000 RBX: 0000000000000006 RCX: 0000000000000000 [ 35.751799] RDX: 0000000000000000 RSI: 0000000000000005 RDI: 0000000000000000 [ 35.751800] RBP: ffffbfa3805d78f0 R08: 0000000000000000 R09: 0000000000000000 [ 35.751801] R10: 0000000000000000 R11: 0000000000000000 R12: ffffbfa383249000 [ 35.751802] R13: ffffa0e68f280000 R14: ffffbfa383249658 R15: 0000000000000000 [ 35.751803] FS: 0000000000000000(0000) GS:ffffa0edbe580000(0000) knlGS:0000000000000000 [ 35.751804] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 35.751805] CR2: 00005d847ef96c58 CR3: 000000041de3e000 CR4: 0000000000f50ef0 [ 35.751806] PKRU: 55555554 [ 35.751807] Call Trace: [ 35.751810] <TASK> [ 35.751816] ? showregs+0x6c/0x80 [ 35.751820] ? warn+0x88/0x140 [ 35.751822] ? dml2mapdcpipes+0x243d/0x3f40 [amdgpu] [ 35.751964] ? reportbug+0x182/0x1b0 [ 35.751969] ? handlebug+0x6e/0xb0 [ 35.751972] ? excinvalidop+0x18/0x80 [ 35.751974] ? asmexcinvalidop+0x1b/0x20 [ 35.751978] ? dml2mapdcpipes+0x243d/0x3f40 [amdgpu] [ 35.752117] ? mathpow+0x48/0xa0 [amdgpu] [ 35.752256] ? srsoaliasreturnthunk+0x5/0xfbef5 [ 35.752260] ? mathpow+0x48/0xa0 [amdgpu] [ 35.752400] ? srsoaliasreturnthunk+0x5/0xfbef5 [ 35.752403] ? mathpow+0x11/0xa0 [amdgpu] [ 35.752524] ? srsoaliasreturnthunk+0x5/0xfbef5 [ 35.752526] ? coredcn4modeprogramming+0xe4d/0x20d0 [amdgpu] [ 35.752663] ? srsoaliasreturnthunk+0x5/0xfbef5 [ 35.752669] dml21validate+0x3d4/0x980 [amdgpu]
(cherry picked from commit f8ad62c0a93e5dd94243e10f1b742232e4d6411e)
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:
alloctag: allocate percpu counters for module tags dynamically
When a module gets unloaded it checks whether any of its tags are still in use and if so, we keep the memory containing module's allocation tags alive until all tags are unused. However percpu counters referenced by the tags are freed by freemodule(). This will lead to UAF if the memory allocated by a module is accessed after module was unloaded.
To fix this we allocate percpu counters for module allocation tags dynamically and we keep it alive for tags which are still in use after module unloading. This also removes the requirement of a larger PERCPUMODULERESERVE when memory allocation profiling is enabled because percpu memory for counters does not need to be reserved anymore.
In the Linux kernel, the following vulnerability has been resolved:
platform/x86: dell-wmi-sysman: Avoid buffer overflow in currentpasswordstore()
If the 'buf' array received from the user contains an empty string, the 'length' variable will be zero. Accessing the 'buf' array element with index 'length - 1' will result in a buffer overflow.
Add a check for an empty string.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
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:
ASoC: SOF: Intel: hda: Fix UAF when reloading module
hdagenericmachineselect() appends -idisp to the tplg filename by allocating a new string with devmkasprintf(), then stores the string right back into the global variable sndsocacpiintelhdamachines. When the module is unloaded, this memory is freed, resulting in a global variable pointing to freed memory. Reloading the module then triggers a use-after-free:
BUG: KFENCE: use-after-free read in string+0x48/0xe0
Use-after-free read at 0x00000000967e0109 (in kfence-#99): string+0x48/0xe0 vsnprintf+0x329/0x6e0 devmkvasprintf+0x54/0xb0 devmkasprintf+0x58/0x80 hdamachineselect.cold+0x198/0x17a2 [sndsofintelhdageneric] sofprobework+0x7f/0x600 [sndsof] processonework+0x17b/0x330 workerthread+0x2ce/0x3f0 kthread+0xcf/0x100 retfromfork+0x31/0x50 retfromforkasm+0x1a/0x30
kfence-#99: 0x00000000198a940f-0x00000000ace47d9d, size=64, cache=kmalloc-64
allocated by task 333 on cpu 8 at 17.798069s (130.453553s ago): devmkmalloc+0x52/0x120 devmkvasprintf+0x66/0xb0 devmkasprintf+0x58/0x80 hdamachineselect.cold+0x198/0x17a2 [sndsofintelhdageneric] sofprobework+0x7f/0x600 [sndsof] processonework+0x17b/0x330 workerthread+0x2ce/0x3f0 kthread+0xcf/0x100 retfromfork+0x31/0x50 retfromforkasm+0x1a/0x30
freed by task 1543 on cpu 4 at 141.586686s (6.665010s ago): releasenodes+0x43/0xb0 devresreleaseall+0x90/0xf0 deviceunbindcleanup+0xe/0x70 devicereleasedriverinternal+0x1c1/0x200 driverdetach+0x48/0x90 busremovedriver+0x6d/0xf0 pciunregisterdriver+0x42/0xb0 dosysdeletemodule+0x1d1/0x310 dosyscall64+0x82/0x190 entrySYSCALL64afterhwframe+0x76/0x7e
Fix it by copying the match array with devmkmemduparray() before we modify it.
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:
regulator: max20086: fix invalid memory access
max20086parseregulatorsdt() calls ofregulatormatch() using an array of struct ofregulatormatch allocated on the stack for the matches argument.
ofregulatormatch() calls devmofregulatorputmatches(), which calls devresalloc() to allocate a struct devmofregulatormatches which will be de-allocated using devmofregulatorputmatches().
struct devmofregulatormatches is populated with the stack allocated matches array.
If the device fails to probe, devmofregulatorputmatches() will be called and will try to call ofnodeput() on that stack pointer, generating the following dmesg entries:
max20086 6-0028: Failed to read DEVICEID reg: -121 kobject: '\xc0$\xa5\x03' (000000002cebcb7a): is not initialized, yet kobjectput() is being called.
Followed by a stack trace matching the call flow described above.
Switch to allocating the matches array using devmkcalloc() to avoid accessing the stack pointer long after it's out of scope.
This also has the advantage of allowing multiple max20086 to probe without overriding the data stored inside the global ofregulatormatch.
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:
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:
mlxsw: spectrumrouter: Fix use-after-free when deleting GRE net devices
The driver only offloads neighbors that are constructed on top of net devices registered by it or their uppers (which are all Ethernet). The device supports GRE encapsulation and decapsulation of forwarded traffic, but the driver will not offload dummy neighbors constructed on top of GRE net devices as they are not uppers of its net devices:
# ip link add name gre1 up type gre tos inherit local 192.0.2.1 remote 198.51.100.1 # ip neigh add 0.0.0.0 lladdr 0.0.0.0 nud noarp dev gre1 $ ip neigh show dev gre1 nud noarp 0.0.0.0 lladdr 0.0.0.0 NOARP
(Note that the neighbor is not marked with 'offload')
When the driver is reloaded and the existing configuration is replayed, the driver does not perform the same check regarding existing neighbors and offloads the previously added one:
# devlink dev reload pci/0000:01:00.0 $ ip neigh show dev gre1 nud noarp 0.0.0.0 lladdr 0.0.0.0 offload NOARP
If the neighbor is later deleted, the driver will ignore the notification (given the GRE net device is not its upper) and will therefore keep referencing freed memory, resulting in a use-after-free [1] when the net device is deleted:
# ip neigh del 0.0.0.0 lladdr 0.0.0.0 dev gre1 # ip link del dev gre1
Fix by skipping neighbor replay if the net device for which the replay is performed is not our upper.
[1] BUG: KASAN: slab-use-after-free in mlxswspneighentryupdate+0x1ea/0x200 Read of size 8 at addr ffff888155b0e420 by task ip/2282 [...] Call Trace: <TASK> dumpstacklvl+0x6f/0xa0 printaddressdescription.constprop.0+0x6f/0x350 printreport+0x108/0x205 kasanreport+0xdf/0x110 mlxswspneighentryupdate+0x1ea/0x200 mlxswsprouterrifgonesync+0x2a8/0x440 mlxswsprifdestroy+0x1e9/0x750 mlxswspnetdeviceipipolevent+0x3c9/0xdc0 mlxswsprouternetdeviceevent+0x3ac/0x15e0 notifiercallchain+0xca/0x150 callnetdevicenotifiersinfo+0x7f/0x100 unregisternetdevicemanynotify+0xc8c/0x1d90 rtnldellink+0x34e/0xa50 rtnetlinkrcvmsg+0x6fb/0xb70 netlinkrcvskb+0x131/0x360 netlinkunicast+0x426/0x710 netlinksendmsg+0x75a/0xc20 socksendmsg+0xc1/0x150 syssendmsg+0x5aa/0x7b0 syssendmsg+0xfc/0x180 syssendmsg+0x121/0x1b0 dosyscall64+0xbb/0x1d0 entrySYSCALL64afterhwframe+0x4b/0x53
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:
wifi: mac80211: Set nchannels after allocating struct cfg80211scanrequest
Make sure that nchannels is set after allocating the struct cfg80211registereddevice::intscanreq member. Seen with syzkaller:
UBSAN: array-index-out-of-bounds in net/mac80211/scan.c:1208:5 index 0 is out of range for type 'struct ieee80211channel [] countedby(nchannels)' (aka 'struct ieee80211channel []')
This was missed in the initial conversions because I failed to locate the allocation likely due to the "sizeof(void )" not matching the "channels" array type.
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.
In the Linux kernel, the following vulnerability has been resolved:
can: bcm: add locking for bcmop runtime updates
The CAN broadcast manager (CAN BCM) can send a sequence of CAN frames via hrtimer. The content and also the length of the sequence can be changed resp reduced at runtime where the 'currframe' counter is then set to zero.
Although this appeared to be a safe operation the updates of 'currframe' can be triggered from user space and hrtimer context in bcmcantx(). Anderson Nascimento created a proof of concept that triggered a KASAN slab-out-of-bounds read access which can be prevented with a spinlockbh.
At the rework of bcmcantx() the 'count' variable has been moved into the protected section as this variable can be modified from both contexts too.
In the Linux kernel, the following vulnerability has been resolved:
can: bcm: add missing rcu read protection for procfs content
When the procfs content is generated for a bcmop which is in the process to be removed the procfs output might show unreliable data (UAF).
As the removal of bcmop's is already implemented with rcu handling this patch adds the missing rcureadlock() and makes sure the list entries are properly removed under rcu protection.
In the Linux kernel, the following vulnerability has been resolved:
iouring/fdinfo: grab ctx->uringlock around iouringshowfdinfo()
Not everything requires locking in there, which is why the 'haslock' variable exists. But enough does that it's a bit unwieldy to manage. Wrap the whole thing in a ->uringlock trylock, and just return with no output if we fail to grab it. The existing trylock() will already have greatly diminished utility/output for the failure case.
This fixes an issue with reading the SQE fields, if the ring is being actively resized at the same time.