Hi all,
We found a Linux kernel local privilege escalation vulnerability in the RDS zerocopy send path, tracked as CVE-2026-43502. We call the exploit ZcopyReaper.
The vulnerability was introduced in Linux v4.17 and fixed by commit 44b550d88b26. The first mainline release containing the fix was Linux v7.1-rc3.
We successfully demonstrated local privilege escalation on an openSUSE system running Linux kernel 6.4.0-150600.23.100.
An unprivileged local user can trigger the vulnerability. The minimal kernel configuration required to reach the vulnerable path is:
CONFIGINET=y CONFIGAIO=y CONFIGRDS=y or m CONFIGRDSTCP=y or m
When RDS is built as modules, rds.ko and rdstcp.ko must either be loaded or be available for automatic loading.
No Linux capabilities are required. CONFIGUSERNS is not required. Disabling unprivileged user namespace creation does not mitigate the vulnerability.
In addition to CVE-2026-43502, there are 20 other Linux bugs that have been confirmed to be exploitable, with public exploits available:
CVE-2026-80714 CVE-2026-74597 CVE-2026-74581 CVE-2026-74480 CVE-2026-72255 CVE-2026-72137 CVE-2026-68376 CVE-2026-68162 CVE-2026-64560 CVE-2026-63834 CVE-2026-52933 CVE-2026-52929 CVE-2026-52924 CVE-2026-52923 CVE-2026-52912 CVE-2026-43502 CVE-2026-43501 CVE-2026-43074 CVE-2026-43042 CVE-2026-31678 CVE-2026-31659 CVE-2026-23274
These vulnerabilities were identified and exploited by NebuSec's automatic exploit generation pipeline. The exploits are available at: https://github.com/NebuSec/CyberMeowfia/blob/main/security-research
In the Linux kernel, the following vulnerability has been resolved:
selinux: reject an unclaimed class value in securitygetclasses()
securitygetclasses() sizes an array by pclasses.nprim and fills it at value - 1, so a class value the policy never defines leaves a NULL. selmakeclasses() passes every entry to selmakedir(), reaching the same dallocname() dereference as the permission array. The class symbol table is allowed to be sparse (policydbclassisvalid() exists to absorb that), but this getter builds its own array straight from the hash table and has no such predicate.
Fail the lookup when a value went unclaimed instead of handing out the NULL. Conforming policies define every class they declare and are unaffected.
ASoC: codecs: lpass-wsa-macro: Fix enum kcontrol accesses
In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: Reject UVD message with dimensions above 4096
Fixes potential overflow in DPB size calculations.
(cherry picked from commit 05e1387d151f71569fbe122d2c89f9db0c21dc10)
In the Linux kernel, the following vulnerability has been resolved:
net: packet: fix wrong transportheader when sending VLAN-tagged frame
In packetparseheaders(), when processing a VLAN-tagged frame, skbsetnetworkheader() is called to advance networkheader past the VLAN tag to the inner protocol header. skbprobetransportheader() is then called with skb->protocol still set to the outer VLAN EtherType (e.g. ETHP8021Q), while nhoff (derived from skbnetworkoffset()) already points past the VLAN tag to the inner protocol header.
In skbflowdissect(), proto is initialized to ETHP8021Q and nhoff points past the VLAN tag. When the dissector hits case ETHP8021Q, it reads a struct vlanhdr at nhoff via skbheaderpointer(), but that offset contains the inner protocol header (e.g. an IP header). The bytes are misinterpreted as a VLAN header, yielding a garbage encapsulated EtherType that matches no known protocol. The dissector returns false, so skbprobetransportheader() never calls skbsettransportheader(), leaving transportheader at its uninitialized sentinel value (~0U).
Move skbprobetransportheader() to before skbsetnetworkheader(). At the time skbprobetransportheader() is called, networkheader still points to the VLAN header, so nhoff correctly points to the VLAN header. The flow dissector can then parse the VLAN header, extract the inner EtherType, and advance nhoff to the inner protocol header, allowing transportheader to be set correctly.
In the Linux kernel, the following vulnerability has been resolved:
net: tap: fix wrong transportheader when sending VLAN-tagged frame
In tapgetuserxdp(), when processing a VLAN-tagged frame (e.g. ETHP8021Q), skbsetnetworkheader() is called first to advance networkheader past the VLAN tag to the inner protocol header. skbprobetransportheader() is then called with skb->protocol still set to ETHP8021Q, while nhoff (derived from skbnetworkoffset()) already points past the VLAN tag to the inner protocol header.
In skbflowdissect(), proto is initialized to ETHP8021Q and nhoff points past the VLAN tag. When the dissector hits case ETHP8021Q, it reads a struct vlanhdr at the current nhoff via skbheaderpointer(), but that offset contains the inner protocol header (e.g. an IP header). The bytes are misinterpreted as a VLAN header, yielding a garbage encapsulated EtherType that matches no known protocol. The dissector returns false, so skbprobetransportheader() never calls skbsettransportheader(), leaving transportheader at its uninitialized sentinel value (~0U).
Move skbsetnetworkheader() to after skbprobetransportheader(). At the time skbprobetransportheader() is called, networkheader still points to the VLAN header (offset ETHHLEN), so nhoff is correct and the flow dissector can parse the VLAN header, extract the inner EtherType, and advance nhoff to the inner protocol header, allowing transportheader to be set correctly.
In the Linux kernel, the following vulnerability has been resolved:
net/tls: Fail tlsswspliceread() after a failed async decrypt
When an async decrypt fails, tlsdecryptdone() records the error in ctx->asyncwait.err and calls tlserrabort(), which stores it in skerr. tlsswrecvmsg() and tlsswreadsock() each read asyncwait.err once they hold the reader lock and fail the call: a record that did not authenticate breaks the connection.
tlsswspliceread() has no such check, and skerr does not stand in for one. tlsrxrecwait() tests skerr only inside the loop it skips whenever a record is already parsed, and the first reader to reach sockerror() clears it, while asyncwait.err persists. A splice therefore keeps delivering records on a connection that recvmsg() and readsock() refuse to read.
Read asyncwait.err in tlsswspliceread() as the other two readers do.
In the Linux kernel, the following vulnerability has been resolved:
drm/xe/oa: Fix sync entry leak on OA config emit failure
xeoaemitoaconfig() releases the sync entries and the syncs array only on its success path. When it fails before the point of no return (fence allocation, config buffer allocation or batch submission), it returns without touching stream->syncs.
The stream open path handles such failures in the caller, but xeoaconfiglocked() propagates the error without any cleanup, so the syncs array and the fence references held by the parsed entries are leaked. The next config ioctl overwrites stream->syncs, making the memory unreachable for good.
Clean up the parsed syncs when xeoaemitoaconfig() fails, matching the cleanup done by the stream open error path.
(cherry picked from commit 8af97b3da2cfce04e6b457c6eb17ed3c1daf912b)
In the Linux kernel, the following vulnerability has been resolved:
ASoC: SDCA: Make UMP message size check more robust
If message offset was larger than the buffer length the size check will pass incorrectly. Refactor the check such that it is more robust to invalid sizes.
In the Linux kernel, the following vulnerability has been resolved:
netfs: release readahead folios on iterator preparation failure
netfspreparereaditerator() batches readahead folios in putbatch so that the folio references can be dropped after the I/O iterator has been prepared.
If rollingbufferloadfromra() fails after earlier folios have been batched, the function returns immediately and leaves those references held. Release the batch before returning the error.
In the Linux kernel, the following vulnerability has been resolved:
mshv: Fix race in mshvirqfddeassign
mshvirqfddeactivate() and the hlist traversal of ptirqfdslist require pt->ptirqfdslock to be held, but mshvirqfddeassign() omits it. This races with the EPOLLHUP path in mshvirqfdwakeup(), which does take the lock before calling mshvirqfddeactivate().
Additionally, mshvirqfddeactivate() uses hlistdel() which poisons the node pointers rather than resetting them. Since mshvirqfdisactive() relies on hlistunhashed() (checks pprev == NULL), a poisoned node still appears active. If a concurrent path calls mshvirqfddeactivate() again on the same irqfd, the guard fails to prevent a double hlistdel() on poisoned pointers.
Fix both issues: - Add the missing spinlockirq/spinunlockirq around the list traversal in mshvirqfddeassign(), matching mshvirqfdrelease(). - Use hlistdelinit() instead of hlistdel() so the node is properly marked as unhashed after removal, making the isactive guard reliable.
In the Linux kernel, the following vulnerability has been resolved:
KVM: s390: pci: Validate AIBV and AISB before pinning guest pages
The AIBV holds one bit per MSI-X vector for a given function. The size of the bit vector is derived from the NOI and the AIBVO. If the size of the AIBV exceeds a single page boundary, then reject the request as we cannot safely pin the guest AIBV.
Similarly reject the request if the AISB address is not 8-byte aligned as the architecture requires doubleword alignment for the summary bit address. Since the AISBO can address up to 64 bits, the size of the AISB can only be 8 bytes for the function. This also ensures the AISB doesn't exceed a single page boundary.
In the Linux kernel, the following vulnerability has been resolved:
sctp: reject stale cookies with mismatched verification tags
sctpunpackcookie() skips cookie expiration checks whenever an association already exists. This is broader than the exception in RFC 9260 Section 5.2.4.
For an existing association, Section 5.2.4 permits an expired State Cookie only when both Verification Tags in the cookie match the current association. Otherwise, the packet SHOULD be discarded and a Stale Cookie ERROR MUST be sent.
The broad check lets an expired Action A restart cookie reach sctpsfdodupcooka(). In a runtime test with the default 60 second cookie lifetime, replaying such a cookie after 65 seconds returned a COOKIE-ACK and restarted the association.
Check cookie expiration unless both Verification Tags match. This preserves the Action D exception for a lost COOKIE ACK while rejecting expired cookies in all other cases.
drm/vmwgfx: drop dmabuf reference on foreign-fd prime import
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: fix buffer head management in ocfs2readblocks()
In ocfs2readblocks(), caller should't assume that buffer head returned by 'sbgetblk()' is exclusively owned and so 'putbh()' always drops bcount from 1 to 0. If it is not so, buffer head remains on hold and likely to be returned by the next call to 'sbgetblk()' unchanged - that is, with BHUptodate bit set even if it has failed validation previously, thus allowing to insert that buffer head into OCFS2 metadata cache and submit it to upper layers. To avoid such a scenario, BHUptodate should be cleared immediately after 'validate()' callback has detected some data inconsistency.
In the Linux kernel, the following vulnerability has been resolved:
arm64: dts: renesas: ironhide: Describe inline ECC carveouts
The DBSC5 DRAM controller protects DRAM content using inline ECC. The inline ECC utilizes areas of DRAM for its operation, which are in the DRAM address range, but must not be accessed or modified. Describe the inline ECC carveout areas used by the DBSC5 controller on this hardware as reserved-memory, which must not be accessed. Include DRAM areas which are unprotected by ECC as well, those are parts of the DRAM which directly precede the ECC carveout.
In case of high DRAM utilization, unless the inline ECC carveouts are properly reserved, Linux may use and corrupt the memory used by the DBSC5 DRAM controller for inline ECC, which would lead to the system becoming unstable.
In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: nv: Write ESREL2 for injected nested SError exceptions
kvminjectel2exception() writes ESREL2 for synchronous exceptions but not for SError. enterexception64() does not write ESRELx for any exception type, so the constructed syndrome is dropped. A guest L2 hypervisor taking a nested SError observes stale ESREL2.
This affects both kvminjectnestedserror() and the EASE path in kvminjectnestedsea().
Write ESREL2 for excepttypeserror, matching excepttypesync.
In the Linux kernel, the following vulnerability has been resolved:
ntfs: bound the attribute-list entry in ntfsreadinodemount()
The $MFT attribute-list walk in ntfsreadinodemount() validates each entry only with "(u8 )alentry + 6 > alend" and "(u8 )alentry + le16tocpu(alentry->length) > alend", but then reads alentry->lowestvcn (an le64 at offset 8) and alentry->mftreference (offset 16) -- fields beyond the 6 bytes proven in range. alentry->length is attacker-controlled and only required non-zero, so a short entry (e.g. length 8) placed at the tail passes both checks while the lowestvcn / mftreference reads fall past alend.
alend is ni->attrlist + attrlistsize (the on-disk size); the buffer is kvzalloc(roundup(attrlistsize, SECTORSIZE)), so the sector rounding usually absorbs the over-read -- but when attrlistsize is a multiple of SECTORSIZE there is no slack and a crafted $MFT attribute list produces an out-of-bounds read at mount time.
Validate the entry with ntfsattrlistentryisvalid() (added in patch 1/3) before dereferencing it, matching the bound the other attribute-list walks now use. The validator already requires the length to cover the fixed header, which makes the separate "!alentry->length" check redundant, so drop it too.
In the Linux kernel, the following vulnerability has been resolved:
alpha/PCI: Add securitylockeddown() check to pcimmapresource()
Currently, Alpha's pcimmapresource() does not check securitylockeddown(LOCKDOWNPCIACCESS) before allowing userspace to mmap PCI BARs.
The generic version has had this check since commit eb627e17727e ("PCI: Lock down BAR access when the kernel is locked down") to prevent DMA attacks when the kernel is locked down.
Add the same check to Alpha's pcimmapresource().
In the Linux kernel, the following vulnerability has been resolved:
tipc: avoid busy looping in tipcexitnet()
Blamed commit introduced a busy-wait loop in tipcexitnet() to wait for pending UDP bearer cleanup works to complete:
while (atomicread(&tn->wqcount)) condresched();
This loop can busy-wait for a long time if condresched() is a NOP. This typically happens if the netns exit is executed by a high priority task, or under kernels configured without preemption (CONFIGPREEMPTNONE). In such cases, it wastes CPU cycles and can lead to soft lockups.
Fix this by replacing the busy loop with waitvarevent(), allowing the thread to sleep properly until the work queue count reaches zero.
Accordingly, update cleanupbearer() to use atomicdecandtest() and wakeupvar() to wake up the waiter when the count drops to zero.
This uses the global wait queue hash table, avoiding the need to bloat struct tipcnet with a waitqueueheadt. The atomicdecandtest() provides the necessary memory barrier to ensure the wakeup is not missed.
In the Linux kernel, the following vulnerability has been resolved:
RDMA/rxe: Fix OOB in freerdatomicresources()
freerdatomicresources() iterates using qp->attr.maxdestrdatomic. Updating maxdestrdatomic before freeing the old array can make the free path walk past the old allocation and trigger a slab out-of-bounds write catched by KASAN: ================================================================== BUG: KASAN: slab-out-of-bounds in freerdatomicresource drivers/infiniband/sw/rxe/rxeqp.c:180 [inline] BUG: KASAN: slab-out-of-bounds in freerdatomicresources drivers/infiniband/sw/rxe/rxeqp.c:171 [inline] BUG: KASAN: slab-out-of-bounds in freerdatomicresources drivers/infiniband/sw/rxe/rxeqp.c:163 [inline] BUG: KASAN: slab-out-of-bounds in rxeqpfromattr+0x1e88/0x2150 drivers/infiniband/sw/rxe/rxeqp.c:712 Write of size 4 at addr ffff88802b8dddb8 by task syz.3.451/11063
CPU: 0 UID: 0 PID: 11063 Comm: syz.3.451 Not tainted 7.1.0 #2 PREEMPT(full) Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, archcaps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <TASK> dumpstack lib/dumpstack.c:94 [inline] dumpstacklvl+0x10e/0x1f0 lib/dumpstack.c:120 printaddressdescription mm/kasan/report.c:378 [inline] printreport+0xf7/0x600 mm/kasan/report.c:482 kasanreport+0xe4/0x120 mm/kasan/report.c:595 freerdatomicresource drivers/infiniband/sw/rxe/rxeqp.c:180 [inline] freerdatomicresources drivers/infiniband/sw/rxe/rxeqp.c:171 [inline] freerdatomicresources drivers/infiniband/sw/rxe/rxeqp.c:163 [inline] rxeqpfromattr+0x1e88/0x2150 drivers/infiniband/sw/rxe/rxeqp.c:712 rxemodifyqp+0x1e2/0x530 drivers/infiniband/sw/rxe/rxeverbs.c:623 ibsecuritymodifyqp+0x223/0xfa0 drivers/infiniband/core/security.c:625 ibmodifyqp+0x333/0xec0 drivers/infiniband/core/verbs.c:1915 modifyqp+0x13ca/0x1940 drivers/infiniband/core/uverbscmd.c:1932 ibuverbsmodifyqp+0xcb/0x120 drivers/infiniband/core/uverbscmd.c:1958 ibuverbswrite+0xb86/0x1030 drivers/infiniband/core/uverbsmain.c:680 vfswrite+0x2aa/0x1070 fs/readwrite.c:686 ksyswrite+0x1f8/0x250 fs/readwrite.c:740 dosyscallx64 arch/x86/entry/syscall64.c:63 [inline] dosyscall64+0x116/0x800 arch/x86/entry/syscall64.c:94 entrySYSCALL64afterhwframe+0x77/0x7f RIP: 0033:0x7fefc75a70cd Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fefc8495018 EFLAGS: 00000246 ORIGRAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007fefc7835fa0 RCX: 00007fefc75a70cd RDX: 0000000000000078 RSI: 0000200000000240 RDI: 0000000000000007 RBP: 00007fefc764f10f R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007fefc7836038 R14: 00007fefc7835fa0 R15: 00007ffcf0586aa0 </TASK>
Allocated by task 11063: kasansavestack+0x33/0x60 mm/kasan/common.c:57 kasansavetrack+0x14/0x30 mm/kasan/common.c:78 poisonkmallocredzone mm/kasan/common.c:398 [inline] kasankmalloc+0xaa/0xb0 mm/kasan/common.c:415 kasankmalloc include/linux/kasan.h:263 [inline] dokmallocnode mm/slub.c:5296 [inline] kmallocnoprof+0x32a/0x850 mm/slub.c:5308 kmallocnoprof include/linux/slab.h:954 [inline] kzallocnoprof include/linux/slab.h:1188 [inline] allocrdatomicresources drivers/infiniband/sw/rxe/rxeqp.c:155 [inline] rxeqpfromattr+0x3f8/0x2150 drivers/infiniband/sw/rxe/rxeqp.c:714 rxemodifyqp+0x1e2/0x530 drivers/infiniband/sw/rxe/rxeverbs.c:623 ibsecuritymodifyqp+0x223/0xfa0 drivers/infiniband/core/security.c:625 ibmodifyqp+0x333/0xec0 drivers/infiniband/core/verbs.c:1915 modifyqp+0x13ca/0x1940 drivers/infiniband/core/uverbscmd.c:1932 ibuverbsmodifyqp+0xcb/0x120 drivers/infiniband/core/uverbscmd.c:1958 ibuverbswrite+0xb86/0x1030 drivers/infiniband/core/uverbsma ---truncated---
In the Linux kernel, the following vulnerability has been resolved:
nvme-tcp: fix usage of pagefragcache
nvme uses pagefragcache to preallocate PDU for each preallocated request of block device. Block devices are created in parallel threads, consequently pagefragcache is used in not thread-safe manner. That leads to incorrect refcounting of backstore pages and premature free.
That can be catched by !sendpageok inside network stack:
WARNING: CPU: 7 PID: 467 at ../net/core/skbuff.c:6931 skbsplicefromiter+0xfa/0x310. tcpsendmsglocked+0x782/0xce0 tcpsendmsg+0x27/0x40 socksendmsg+0x8b/0xa0 nvmetcptrysendcmdpdu+0x149/0x2a0 Then random panic may occur.
Fix that by serializing the usage of pagefragcache.
In the Linux kernel, the following vulnerability has been resolved:
fuse: fix missing barrier when checking io-uring readiness
fuseblockalloc() reads fch->initialized and then fch->iouring. fch->iouring is set before fch->initialized, ordered by the smpwmb() in fusechansetintialized(), but fuseblockalloc() has no matching read barrier between the two loads.
This may lead a CPU to observe fch->initialized=1 but fch->iouring=0, and skip the check that blocks request allocation until the io-uring queues are ready. This can reintroduce the lock-order inversion deadlock that commit 3393ff964e0f prevents.
Add an smprmb() barrier to pair with the smpwmb() in fusechansetinitialized() to prevent this.
In the Linux kernel, the following vulnerability has been resolved:
fuse: wait for FRFINISHED on abortonkill to prevent use-after-free
The abortonkill path in requestwaitanswer() calls fuseabortconn() and returns without waiting for FRFINISHED. If fusedevdowrite() is concurrently processing the same request (FRLOCKED set), the caller frees req->args while it is still being accessed, causing a use-after-free.
Fix this by jumping to the existing waitevent(FRFINISHED) instead of returning early. The wait will not hang because fuseabortconn() ensures all requests are ended.
fuse: fix invalidate lock leak on setattr writeback failure
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: ftcm: keep port count until LUN teardown completes
tcmusbgdropnexus() permits session removal once tpgportcount reaches zero. However, usbgportunlink() currently decrements that count from the fabricpreunlink() callback, before coredevdellun() waits for active selun references to drain.
If removal of the last LUN races a nexus removal, the latter can observe a zero port count and call targetremovesession(). This frees sesscmdmap while an in-flight struct usbgcmd, including its work item, can still be accessed.
Overlapping the last-LUN unlink with nexus removal reproduces this lifetime violation as a DEBUGOBJECTS "free active" warning for usbgcmdwork, followed by a target-core BUG/Oops.
The generic target-core unlink path has no callback after coredevdellun() completes. Add an optional fabricpostunlink() callback and use it for the ftcm port count. The count now remains nonzero until coredevdellun() has finished draining active LUN references, preventing nexus removal from freeing the session during command completion.
In the Linux kernel, the following vulnerability has been resolved:
tls: device: fix out-of-bounds write in tlsappendfrag()
Found with syzkaller and a local syzbot instance running on top of a netdevsim TLS offload emulation; tlsdevice.c is otherwise only reachable on a machine with a NIC that implements the offload.
tlspushdata() only checks whether the open record still has room for another frag at the bottom of its loop, and the MSGMORE early break skips that check. The record survives to the next syscall with the frag count it already had, and tlsappendfrag() does not check either, so with TLSTXZEROCOPYRO every splice(SPLICEFMORE) of a byte or two adds a non-coalescing pipe page and numfrags walks off the end of tlsrecordinfo.frags[MAXSKBFRAGS]. Once the record is pushed, tlspushrecord() runs the same index over sgtxdata[MAXSKBFRAGS] and the sgsetpage() writes land on the destructwork that follows it, which the workqueue then calls.
The byte limit is fine because copy drops to 0 and the loop falls through to the same check; the frag count has no such feedback.
Push the record rather than keep a full one open, which is what a plain TCP socket does - tcpsendmsglocked() uses tcpmarkpush() and newsegment in both the copy and the MSGSPLICEPAGES paths, and tlssw already sets fullrecord when the skmsg ring fills up, MSGMORE or not.
BUG: KASAN: slab-out-of-bounds in tlsappendfrag ( net/tls/tlsdevice.c:269) Write of size 8 at addr ffff8881104d1530 by task tlsoob/450
CPU: 2 UID: 0 PID: 450 Comm: tlsoob Not tainted 7.2.0-rc7+ #329 PREEMPT Call Trace: <TASK> dumpstacklvl (lib/dumpstack.c:94 lib/dumpstack.c:120) printreport (mm/kasan/report.c:378 mm/kasan/report.c:482) kasanreport (mm/kasan/report.c:595) tlsappendfrag (net/tls/tlsdevice.c:269) tlspushdata (net/tls/tlsdevice.c:518) tlsdevicesendmsg (net/tls/tlsdevice.c:583) inetsendmsg (net/ipv4/afinet.c:865) socksendmsg (net/socket.c:775 net/socket.c:790 net/socket.c:813) splicetosocket (fs/splice.c:884) dosplice (fs/splice.c:936 fs/splice.c:1349) dosplice (fs/splice.c:1431) x64syssplice (fs/splice.c:1634 fs/splice.c:1616) dosyscall64 (arch/x86/entry/syscall64.c:63 arch/x86/entry/syscall64.c:94) entrySYSCALL64afterhwframe (arch/x86/entry/entry64.S:121) </TASK>
and, once the record is pushed:
UBSAN: array-index-out-of-bounds in net/tls/tlsdevice.c:300:24 index 18 is out of range for type 'skbfragt [17]' UBSAN: array-index-out-of-bounds in net/tls/tlsdevice.c:301:41 index 18 is out of range for type 'scatterlist [17]' UBSAN: array-index-out-of-bounds in net/tls/tlsdevice.c:302:39 index 18 is out of range for type 'scatterlist [17]' UBSAN: array-index-out-of-bounds in net/tls/tlsdevice.c:307:38 index 26 is out of range for type 'scatterlist [17]'
kernel tried to execute NX-protected page - exploit attempt? (uid: 0) BUG: unable to handle page fault for address: ffffea000411a680 #PF: supervisor instruction fetch in kernel mode #PF: errorcode(0x0011) - permissions violation Oops: Oops: 0011 [#1] SMP KASAN PTI Workqueue: ktlsdevicedestruct 0xffffea000411a680 RIP: 0010:0xffffea000411a680 Call Trace: <TASK> workerthread (kernel/workqueue.c:3405 kernel/workqueue.c:3486) kthread (kernel/kthread.c:436) retfromfork (arch/x86/kernel/process.c:158) retfromforkasm (arch/x86/entry/entry64.S:245) </TASK>
In the Linux kernel, the following vulnerability has been resolved:
net/tcp-ao: fix use-after-free of currentkey on reconnect to another peer
tcpinboundaohash() is called before bhlocksocknested() is taken, with only rcureadlock() held. On the fast path for established sockets, if the rnextkeyid sent by the peer differs from currentkey->sndid, the key the peer asked for is looked up and stored in currentkey. The lookup is inside the RCU read side, but currentkey outlives it.
When the socket is disconnected and connect() is called again for another peer, tcpaoconnectinit() unlinks every key that does not match the new peer and frees it with callrcu(). If currentkey points at such a key, it is cleared to NULL.
The fast path reads skstate only once on entry, so a softirq that got into it while the socket was still established can update currentkey after that loop has already run. The update is inside the RCU read side, so it comes before the callrcu() callback, and once the callback frees the key, currentkey is left pointing at freed memory.
The next transmission picks that pointer up in tcpgetcurrentkey(). tcpaotransmitskb() then reads the traffic key from the freed object, which is the use-after-free.
Wait for one grace period before unlinking, and only if a key is going to be removed. By the time tcpconnect() runs the socket is already in TCPSYNSENT, and TCPAOESTABLISHED does not contain TCPFSYNSENT, so a softirq entering after the wait cannot reach the fast path, and the ones already in it have finished. The existing NULL handling in the loop is then enough.
In the Linux kernel, the following vulnerability has been resolved:
xfrm: drop ESP-in-TCP packets with no ingress device
ESP-in-TCP receives records through the TCP strparser. handleesp() restores skb->dev from the saved skbiif before passing the packet into the XFRM input path.
Queued TCP data can be processed after the original ingress device has been removed, for example during veth or net namespace teardown. In that case devgetbyindexrcu() returns NULL. The XFRM IPv4 and IPv6 input paths both expect skb->dev to be valid while building the route lookup, so queued ESP-in-TCP data can dereference a NULL device.
Drop the packet if the saved ingress device can no longer be resolved. Such a packet can no longer be routed through the normal XFRM receive path, and this preserves the existing behaviour for packets whose ingress device still exists.
In the Linux kernel, the following vulnerability has been resolved:
xfrm: avoid lock inversion in nat keepalive work
natkeepalivework() walks the state table while xfrmstatewalk() holds net->xfrm.xfrmstatelock. Its callback then acquires x->lock, which conflicts with the delete path taking the same locks in reverse order via xfrmstatedelete() and xfrmstatedelete(). This creates an AB-BA deadlock that is reported by lockdep when a NAT keepalive worker races with SA deletion.
Fix this by splitting the keepalive walk into two phases. First, collect the candidate states while the walk holds xfrmstatelock and take a reference on each state. Then, after the walk completes, process each collected state and acquire x->lock without nesting it under xfrmstatelock.