In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
netfilter: nfnetlinkosf: fix out-of-bounds read on option matching
In nfosfmatch(), the nfosfhdrctx structure is initialized once and passed by reference to nfosfmatchone() for each fingerprint checked. During TCP option parsing, nfosfmatchone() advances the shared ctx->optp pointer.
If a fingerprint perfectly matches, the function returns early without restoring ctx->optp to its initial state. If the user has configured NFOSFLOGLEVELALL, the loop continues to the next fingerprint. However, because ctx->optp was not restored, the next call to nfosfmatchone() starts parsing from the end of the options buffer. This causes subsequent matches to read garbage data and fail immediately, making it impossible to log more than one match or logging incorrect matches.
Instead of using a shared ctx->optp pointer, pass the context as a constant pointer and use a local pointer (optp) for TCP option traversal. This makes nfosfmatchone() strictly stateless from the caller's perspective, ensuring every fingerprint check starts at the correct option offset.
In the Linux kernel, the following vulnerability has been resolved:
ipv6: rpl: reserve maclen headroom when recompressed SRH grows
ipv6rplsrhrcv() decompresses an RFC 6554 Source Routing Header, swaps the next segment into ipv6hdr->daddr, recompresses, then pulls the old header and pushes the new one plus the IPv6 header back. The recompressed header can be larger than the received one when the swap reduces the common-prefix length the segments share with daddr (CmprI=0, CmprE>0, seg[0][0] != daddr[0] gives the maximum +8 bytes).
pskbexpandhead() was gated on segmentsleft == 0, so on earlier segments the push consumed unchecked headroom. Once skbpush() leaves fewer than skb->maclen bytes in front of data, skbmacheaderrebuild()'s call to:
skbsetmacheader(skb, -skb->maclen);
will store (data - head) - maclen into the u16 macheader field, which wraps to ~65530, and the following memmove() writes maclen bytes ~64KiB past skb->head.
A single AFINET6/SOCKRAW/IPV6HDRINCL packet over lo with a two segment type-3 SRH (CmprI=0, CmprE=15) reaches headroom 8 after one pass; KASAN reports a 14-byte OOB write in ipv6rthdrrcv.
Fix this by expanding the head whenever the remaining room is less than the push size plus maclen, and request that much extra so the rebuilt MAC header fits afterwards.
In the Linux kernel, the following vulnerability has been resolved:
ipv6: icmp: clear skb2->cb[] in ip6errgenicmpv6unreach()
Sashiko AI-review observed:
In ip6errgenicmpv6unreach(), the skb is an outer IPv4 ICMP error packet where its cb contains an IPv4 inetskbparm. When skb is cloned into skb2 and passed to icmp6send(), it uses IP6CB(skb2).
IP6CB interprets the IPv4 inetskbparm as an inet6skbparm. The cipso offset in inetskbparm.opt directly overlaps with dsthao in inet6skbparm at offset 18.
If an attacker sends a forged ICMPv4 error with a CIPSO IP option, dsthao would be a non-zero offset. Inside icmp6send(), mip6addrswap() is called and uses ipv6findtlv(skb, opt->dsthao, IPV6TLVHAO).
This would scan the inner, attacker-controlled IPv6 packet starting at that offset, potentially returning a fake TLV without checking if the remaining packet length can hold the full 18-byte struct ipv6destopthao.
Could mip6addrswap() then perform a 16-byte swap that extends past the end of the packet data into skbsharedinfo?
Should the cb array also be cleared in ip6errgenicmpv6unreach() and ip6ip6err() to prevent this?
This patch implements the first suggestion.
I am not sure if ip6ip6err() needs to be changed. A separate patch would be better anyway.
In the Linux kernel, the following vulnerability has been resolved:
net/x25: Fix potential double free of skb
When allocskb fails in x25queuerxframe it calls kfreeskb(skb) at line 48 and returns 1 (error). This error propagates back through the call chain:
x25queuerxframe returns 1 | v x25state3machine receives the return value 1 and takes the else branch at line 278, setting queued=0 and returning 0 | v x25processrxframe returns queued=0 | v x25backlogrcv at line 452 sees queued=0 and calls kfreeskb(skb) again
This would free the same skb twice. Looking at x25backlogrcv:
net/x25/x25in.c:x25backlogrcv() { ... queued = x25processrxframe(sk, skb); ... if (!queued) kfreeskb(skb); }
bridge: brndsend: linearize skb before parsing ND options
In the Linux kernel, the following vulnerability has been resolved:
net: stmmac: fix integer underflow in chain mode
The jumbofrm() chain-mode implementation unconditionally computes
len = nopagedlen - bmax;
where nopagedlen = skbheadlen(skb) (linear bytes only) and bmax is BUFSIZE8KiB or BUFSIZE2KiB. However, the caller stmmacxmit() decides to invoke jumbofrm() based on skb->len (total length including page fragments):
isjumbo = stmmacisjumbofrm(priv, skb->len, enhdesc);
When a packet has a small linear portion (nopagedlen <= bmax) but a large total length due to page fragments (skb->len > bmax), the subtraction wraps as an unsigned integer, producing a huge len value (~0xFFFFxxxx). This causes the while (len != 0) loop to execute hundreds of thousands of iterations, passing skb->data + bmax i pointers far beyond the skb buffer to dmamapsingle(). On IOMMU-less SoCs (the typical deployment for stmmac), this maps arbitrary kernel memory to the DMA engine, constituting a kernel memory disclosure and potential memory corruption from hardware.
Fix this by introducing a buflen local variable clamped to min(nopagedlen, bmax). Computing len = nopagedlen - buflen is then always safe: it is zero when the linear portion fits within a single descriptor, causing the while (len != 0) loop to be skipped naturally, and the fragment loop in stmmacxmit() handles page fragments afterward.
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix heap overflow in NFSv4.0 LOCK replay cache
The NFSv4.0 replay cache uses a fixed 112-byte inline buffer (rpibuf[NFSD4REPLAYISIZE]) to store encoded operation responses. This size was calculated based on OPEN responses and does not account for LOCK denied responses, which include the conflicting lock owner as a variable-length field up to 1024 bytes (NFS4OPAQUELIMIT).
When a LOCK operation is denied due to a conflict with an existing lock that has a large owner, nfsd4encodeoperation() copies the full encoded response into the undersized replay buffer via readbytesfromxdrbuf() with no bounds check. This results in a slab-out-of-bounds write of up to 944 bytes past the end of the buffer, corrupting adjacent heap memory.
This can be triggered remotely by an unauthenticated attacker with two cooperating NFSv4.0 clients: one sets a lock with a large owner string, then the other requests a conflicting lock to provoke the denial.
We could fix this by increasing NFSD4REPLAYISIZE to allow for a full opaque, but that would increase the size of every stateowner, when most lockowners are not that large.
Instead, fix this by checking the encoded response length against NFSD4REPLAYISIZE before copying into the replay buffer. If the response is too large, set rpbuflen to 0 to skip caching the replay payload. The status is still cached, and the client already received the correct response on the original request.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: nfconntrackh323: check for zero length in DecodeQ931()
In DecodeQ931(), the UserUserIE code path reads a 16-bit length from the packet, then decrements it by 1 to skip the protocol discriminator byte before passing it to DecodeH323UserInformation(). If the encoded length is 0, the decrement wraps to -1, which is then passed as a large value to the decoder, leading to an out-of-bounds read.
Add a check to ensure len is positive after the decrement.
In the Linux kernel, the following vulnerability has been resolved:
ip6gre: make ip6greheader() robust
Over the years, syzbot found many ways to crash the kernel in ip6greheader() [1].
This involves team or bonding drivers ability to dynamically change their dev->neededheadroom and/or dev->hardheaderlen
In this particular crash mldnewpack() allocated an skb with a too small reserve/headroom, and by the time mldsendpack() was called, syzbot managed to attach an ip6gre device.
[1] skbuff: skbunderpanic: text:ffffffff8a1d69a8 len:136 put:40 head:ffff888059bc7000 data:ffff888059bc6fe8 tail:0x70 end:0x6c0 dev:team0 ------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:213 ! <TASK> skbunderpanic net/core/skbuff.c:223 [inline] skbpush+0xc3/0xe0 net/core/skbuff.c:2641 ip6greheader+0xc8/0x790 net/ipv6/ip6gre.c:1371 devhardheader include/linux/netdevice.h:3436 [inline] neighconnectedoutput+0x286/0x460 net/core/neighbour.c:1618 neighoutput include/net/neighbour.h:556 [inline] ip6finishoutput2+0xfb3/0x1480 net/ipv6/ip6output.c:136 ip6finishoutput net/ipv6/ip6output.c:-1 [inline] ip6finishoutput+0x234/0x7d0 net/ipv6/ip6output.c:220 NFHOOKCOND include/linux/netfilter.h:307 [inline] ip6output+0x340/0x550 net/ipv6/ip6output.c:247 NFHOOK+0x9e/0x380 include/linux/netfilter.h:318 mldsendpack+0x8d4/0xe60 net/ipv6/mcast.c:1855 mldsendcr net/ipv6/mcast.c:2154 [inline] mldifcwork+0x83e/0xd60 net/ipv6/mcast.c:2693
In the Linux kernel, the following vulnerability has been resolved:
nfsd: clear aclaccess/acldefault after releasing them
If getting acldefault fails, aclaccess and acldefault will be released simultaneously. However, aclaccess will still retain a pointer pointing to the released posixacl, which will trigger a WARNING in nfs3svcreleasegetacl like this:
------------[ cut here ]------------ refcountt: underflow; use-after-free. WARNING: CPU: 26 PID: 3199 at lib/refcount.c:28 refcountwarnsaturate+0xb5/0x170 Modules linked in: CPU: 26 UID: 0 PID: 3199 Comm: nfsd Not tainted 6.12.0-rc6-00079-g04ae226af01f-dirty #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:refcountwarnsaturate+0xb5/0x170 Code: cc cc 0f b6 1d b3 20 a5 03 80 fb 01 0f 87 65 48 d8 00 83 e3 01 75 e4 48 c7 c7 c0 3b 9b 85 c6 05 97 20 a5 03 01 e8 fb 3e 30 ff <0f> 0b eb cd 0f b6 1d 8a3 RSP: 0018:ffffc90008637cd8 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff83904fde RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffff88871ed36380 RBP: ffff888158beeb40 R08: 0000000000000001 R09: fffff520010c6f56 R10: ffffc90008637ab7 R11: 0000000000000001 R12: 0000000000000001 R13: ffff888140e77400 R14: ffff888140e77408 R15: ffffffff858b42c0 FS: 0000000000000000(0000) GS:ffff88871ed00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000562384d32158 CR3: 000000055cc6a000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? refcountwarnsaturate+0xb5/0x170 ? warn+0xa5/0x140 ? refcountwarnsaturate+0xb5/0x170 ? reportbug+0x1b1/0x1e0 ? handlebug+0x53/0xa0 ? excinvalidop+0x17/0x40 ? asmexcinvalidop+0x1a/0x20 ? ticknohztickstopped+0x1e/0x40 ? refcountwarnsaturate+0xb5/0x170 ? refcountwarnsaturate+0xb5/0x170 nfs3svcreleasegetacl+0xc9/0xe0 svcprocesscommon+0x5db/0xb60 ? pfxsvcprocesscommon+0x10/0x10 ? rcureadunlock+0x69/0xa0 ? pfxnfsddispatch+0x10/0x10 ? svcxprtreceived+0xa1/0x120 ? xdrinitdecode+0x11d/0x190 svcprocess+0x2a7/0x330 svchandlexprt+0x69d/0x940 svcrecv+0x180/0x2d0 nfsd+0x168/0x200 ? pfxnfsd+0x10/0x10 kthread+0x1a2/0x1e0 ? kthread+0xf4/0x1e0 ? pfxkthread+0x10/0x10 retfromfork+0x34/0x60 ? pfxkthread+0x10/0x10 retfromforkasm+0x1a/0x30 </TASK> Kernel panic - not syncing: kernel: paniconwarn set ...
Clear aclaccess/acldefault after posixaclrelease is called to prevent UAF from being triggered.
In the Linux kernel, the following vulnerability has been resolved:
mptcp: consolidate suboption status
MPTCP maintains the received sub-options status is the bitmask carrying the received suboptions and in several bitfields carrying per suboption additional info.
Zeroing the bitmask before parsing is not enough to ensure a consistent status, and the MPTCP code has to additionally clear some bitfiled depending on the actually parsed suboption.
The above schema is fragile, and syzbot managed to trigger a path where a relevant bitfield is not cleared/initialized:
BUG: KMSAN: uninit-value in mptcpexpandseq net/mptcp/options.c:1030 [inline] BUG: KMSAN: uninit-value in mptcpexpandseq net/mptcp/protocol.h:864 [inline] BUG: KMSAN: uninit-value in ackupdatemsk net/mptcp/options.c:1060 [inline] BUG: KMSAN: uninit-value in mptcpincomingoptions+0x2036/0x3d30 net/mptcp/options.c:1209 mptcpexpandseq net/mptcp/options.c:1030 [inline] mptcpexpandseq net/mptcp/protocol.h:864 [inline] ackupdatemsk net/mptcp/options.c:1060 [inline] mptcpincomingoptions+0x2036/0x3d30 net/mptcp/options.c:1209 tcpdataqueue+0xb4/0x7be0 net/ipv4/tcpinput.c:5233 tcprcvestablished+0x1061/0x2510 net/ipv4/tcpinput.c:6264 tcpv4dorcv+0x7f3/0x11a0 net/ipv4/tcpipv4.c:1916 tcpv4rcv+0x51df/0x5750 net/ipv4/tcpipv4.c:2351 ipprotocoldeliverrcu+0x2a3/0x13d0 net/ipv4/ipinput.c:205 iplocaldeliverfinish+0x336/0x500 net/ipv4/ipinput.c:233 NFHOOK include/linux/netfilter.h:314 [inline] iplocaldeliver+0x21f/0x490 net/ipv4/ipinput.c:254 dstinput include/net/dst.h:460 [inline] iprcvfinish+0x4a2/0x520 net/ipv4/ipinput.c:447 NFHOOK include/linux/netfilter.h:314 [inline] iprcv+0xcd/0x380 net/ipv4/ipinput.c:567 netifreceiveskbonecore net/core/dev.c:5704 [inline] netifreceiveskb+0x319/0xa00 net/core/dev.c:5817 processbacklog+0x4ad/0xa50 net/core/dev.c:6149 napipoll+0xe7/0x980 net/core/dev.c:6902 napipoll net/core/dev.c:6971 [inline] netrxaction+0xa5a/0x19b0 net/core/dev.c:7093 handlesoftirqs+0x1a0/0x7c0 kernel/softirq.c:561 dosoftirq+0x14/0x1a kernel/softirq.c:595 dosoftirq+0x9a/0x100 kernel/softirq.c:462 localbhenableip+0x9f/0xb0 kernel/softirq.c:389 localbhenable include/linux/bottomhalf.h:33 [inline] rcureadunlockbh include/linux/rcupdate.h:919 [inline] devqueuexmit+0x2758/0x57d0 net/core/dev.c:4493 devqueuexmit include/linux/netdevice.h:3168 [inline] neighhhoutput include/net/neighbour.h:523 [inline] neighoutput include/net/neighbour.h:537 [inline] ipfinishoutput2+0x187c/0x1b70 net/ipv4/ipoutput.c:236 ipfinishoutput+0x287/0x810 ipfinishoutput+0x4b/0x600 net/ipv4/ipoutput.c:324 NFHOOKCOND include/linux/netfilter.h:303 [inline] ipoutput+0x15f/0x3f0 net/ipv4/ipoutput.c:434 dstoutput include/net/dst.h:450 [inline] iplocalout net/ipv4/ipoutput.c:130 [inline] ipqueuexmit+0x1f2a/0x20d0 net/ipv4/ipoutput.c:536 ipqueuexmit+0x60/0x80 net/ipv4/ipoutput.c:550 tcptransmitskb+0x3cea/0x4900 net/ipv4/tcpoutput.c:1468 tcptransmitskb net/ipv4/tcpoutput.c:1486 [inline] tcpwritexmit+0x3b90/0x9070 net/ipv4/tcpoutput.c:2829 tcppushpendingframes+0xc4/0x380 net/ipv4/tcpoutput.c:3012 tcpsendfin+0x9f6/0xf50 net/ipv4/tcpoutput.c:3618 tcpclose+0x140c/0x1550 net/ipv4/tcp.c:3130 mptcpclosessk+0x74e/0x16f0 net/mptcp/protocol.c:2496 mptcpclosessk+0x26b/0x2c0 net/mptcp/protocol.c:2550 mptcppmnlrmaddrorsubflow+0x635/0xd10 net/mptcp/pmnetlink.c:889 mptcppmnlrmsubflowreceived net/mptcp/pmnetlink.c:924 [inline] mptcppmflushaddrsandsubflows net/mptcp/pmnetlink.c:1688 [inline] mptcpnlflushaddrslist net/mptcp/pmnetlink.c:1709 [inline] mptcppmnlflushaddrsdoit+0xe10/0x1630 net/mptcp/pmnetlink.c:1750 genlfamilyrcvmsgdoit net/netlink/genetlink.c:1115 [inline] ---truncated---
In the Linux kernel, the following vulnerability has been resolved:
spi: fsl-lpspi: terminate the RX channel on TX prepare failure path
When dmaengineprepslavesg() fails for the TX channel, the error path terminates the TX DMA channel but leaves the RX channel running. Since the RX channel was already submitted and issued prior to preparing the TX descriptor, returning -EINVAL causes the SPI core to unmap the DMA buffers while the RX DMA engine continues writing to them, leading to potential memory corruption or use-after-free.
Terminate the RX channel before returning on the TX prepare failure path.
In the Linux kernel, the following vulnerability has been resolved:
tipc: fix out-of-bounds read in broadcast Gap ACK blocks
A broadcast PROTOCOL/STATEMSG can carry a Gap ACK blocks record in its data area. tipcgetgapackblks() only verifies that the record's len field is self-consistent with its ugackcnt/bgackcnt counts (sz == structsize(p, gacks, ugackcnt + bgackcnt)); it does not check that the record actually fits in the message data area, msgdatasz().
The unicast caller tipclinkprotorcv() bounds it ("if (glen > dlen) break;"), but the broadcast caller tipcbcastsyncrcv() discards the returned size, so tipclinkadvancetransmq() copies the record off the receive skb with an attacker-controlled count:
thisga = kmemdup(ga, structsize(ga, gacks, ga->bgackcnt), GFPATOMIC);
A TIPC neighbour that negotiated TIPCGAPACKBLOCK triggers it with one ordinary broadcast STATEMSG (msgbcackinvalid() clear), sized so its data area is short, carrying a Gap ACK record with len = 0x400, bgackcnt = 0xff and ugackcnt = 0. len then equals structsize(p, gacks, 255), so the consistency check passes and ga is non-NULL; kmemdup() reads structsize(ga, gacks, 255) = 1024 bytes out of the much smaller skb:
BUG: KASAN: slab-out-of-bounds in kmemdupnoprof+0x48/0x60 Read of size 1024 at addr ffff0000c7030d38 by task poc864/69 Call trace: kmemdupnoprof+0x48/0x60 tipclinkadvancetransmq+0x86c/0xb80 tipclinkbcackrcv+0x19c/0x1e0 tipcbcastsyncrcv+0x1c4/0x2c4 tipcrcv+0x85c/0x1340 tipcl2rcvmsg+0xac/0x104 The buggy address belongs to the object at ffff0000c7030d00 which belongs to the cache skbuffsmallhead of size 704 The buggy address is located 56 bytes inside of allocated 704-byte region [ffff0000c7030d00, ffff0000c7030fc0)
The copied-out bytes are subsequently consumed as gap/ack values, but the read is already out of bounds at the kmemdup() regardless of how they are used.
The unicast STATE path drops such a message: "if (glen > dlen) break;" skips the rest of STATEMSG handling and the skb is freed. Make the broadcast path drop it too. tipcbcastsyncrcv() now bounds the record against msgdatasz() and, when it does not fit, reports it back through tipcnodebcsyncrcv() to tipcrcv() so the skb is discarded rather than processed. ga is not cleared on this path: ga == NULL already means "legacy peer without Selective ACK", a distinct legitimate state.
In the Linux kernel, the following vulnerability has been resolved:
net: ethernet: cortina: Carry over frag counter
The gmacrx() NAPI poll function assembles packets in an SKB from a ring buffer.
If the ring buffer gets completely emptied during a poll cycle, we exit gmacrx(), but the packet is not yet completely assembled in the SKB, yet the fragment counter fragnr is reset to zero on the next invocation.
Solve this by making the RX fragment counter a part of the port struct, and carry it over between invocations.
Reset the fragment counter only right after calling napigrofrags(), on error (after calling napifreefrags()) or if stopping the port.
Reset it in some place where not strictly necessary just to emphasize what is going on.
This was found by Sashiko during normal patch review.
In the Linux kernel, the following vulnerability has been resolved:
net: ethernet: cortina: Make RX SKB per-port
The SKB used to assemble packets from fragments in gmacrx() is static local, but the Gemini has two ethernet ports, meaning there can be races between the ports on a bad day if a device is using both.
Make the RX SKB a per-port variable and carry it over between invocations in the port struct instead.
Zero the pointer once we call napigrofrags(), on error (after calling napifreefrags()) or if the port is stopped.
Zero it in some place where not strictly necessary just to emphasize what is going on.
This was found by Sashiko during normal patch review.
In the Linux kernel, the following vulnerability has been resolved:
net: tls: prevent chain-after-chain in plain text SG
Sashiko points out that if end = 0 (start != 0) the current code will create a chain link to content type right after the wrap link:
This would create a chain where the wrap link points directly to another chain link. The scatterlist API sgnext iterator does not recursively resolve consecutive chain links.
meaning this is illegal input to crypto.
The wrapping link is unnecessary if end = 0. end is the entry after the last one used so end = 0 means there's nothing pushed after the wrap:
end start i v v v [ ]...[ ][ d ][ d ][ d ][ d ][rsv for wrap]
Skip the wrapping in this case.
TLS 1.3 can use the "wrapping slot" for it's chaining if end = 0. This avoids the chain-after-chain.
Move the wrap chaining before marking END and chaining off content type, that feels like more logical ordering to me, but should not matter from functional perspective.
In the Linux kernel, the following vulnerability has been resolved:
net: tls: fix off-by-one in sgchain entry count for wrapped skmsg ring
When an skmsg scatterlist ring wraps (sg.end < sg.start), tlspushrecord() chains the tail portion of the ring to the head using sgchain(). An extra entry in the sg array is reserved for this:
struct skmsgsg { [...] / The extra two elements: 1) used for chaining the front and sections when the list becomes partitioned (e.g. end < start). The crypto APIs require the chaining; 2) to chain tailer SG entries after the message. / struct scatterlist data[MAXMSGFRAGS + 2];
The current code uses MAXSKBFRAGS + 1 as the ring size:
sgchain(&msgpl->sg.data[msgpl->sg.start], MAXSKBFRAGS - msgpl->sg.start + 1, msgpl->sg.data);
This places the chain pointer at
sgchain(data[start], (MAXSKBFRAGS - msgstart + 1) .. = &data[start] + (MAXSKBFRAGS - msgstart + 1) - 1 = data[start + (MAXSKBFRAGS - start + 1) - 1] = data[MAXSKBFRAGS]
instead of the true last entry. This is likely due to a "race" of the commit under Fixes landing close to commit 031097d9e079 ("bpf: skmsg, zap ingress queue on psock down")
Convert to ARRAYSIZE and drop the data[start] / - start (as suggested by Sabrina).
In the Linux kernel, the following vulnerability has been resolved:
ip6tunnel: clear skb2->cb[] in ip4ip6err()
Oskar Kjos reported the following problem.
ip4ip6err() calls icmpsend() on a cloned skb whose cb[] was written by the IPv6 receive path as struct inet6skbparm. icmpsend() passes IPCB(skb2) to ipoptionsecho(), which interprets that cb[] region as struct inetskbparm (IPv4). The layouts differ: inet6skbparm.nhoff at offset 14 overlaps inetskbparm.opt.rr, producing a non-zero rr value. ipoptionsecho() then reads optlen from attacker-controlled packet data at sptr[rr+1] and copies that many bytes into dopt->data, a fixed 40-byte stack buffer (IPOPTIONSDATAFIXEDSIZE).
To fix this we clear skb2->cb[], as suggested by Oskar Kjos.
Also add minimal IPv4 header validation (version == 4, ihl >= 5).
In the Linux kernel, the following vulnerability has been resolved:
scsi: lpfc: Fix buffer free/clear order in deferred receive path
Fix a use-after-free window by correcting the buffer release sequence in the deferred receive path. The code freed the RQ buffer first and only then cleared the context pointer under the lock. Concurrent paths (e.g., ABTS and the repost path) also inspect and release the same pointer under the lock, so the old order could lead to double-free/UAF.
Note that the repost path already uses the correct pattern: detach the pointer under the lock, then free it after dropping the lock. The deferred path should do the same.
In the Linux kernel, the following vulnerability has been resolved:
crypto: pcrypt - Fix handling of MAYBACKLOG requests
MAYBACKLOG requests can return EBUSY. Handle them by checking for that value and filtering out EINPROGRESS notifications.
In the Linux kernel, the following vulnerability has been resolved:
nfsd: handle getclientlocked() failure in nfsd4setclientidconfirm()
Lei Lu recently reported that nfsd4setclientidconfirm() did not check the return value from getclientlocked(). a SETCLIENTIDCONFIRM could race with a confirmed client expiring and fail to get a reference. That could later lead to a UAF.
Fix this by getting a reference early in the case where there is an extant confirmed client. If that fails then treat it as if there were no confirmed client found at all.
In the case where the unconfirmed client is expiring, just fail and return the result from getclientlocked().
In the Linux kernel, the following vulnerability has been resolved:
nvme: avoid double free special payload
If a discard request needs to be retried, and that retry may fail before a new special payload is added, a double free will result. Clear the RQFSPECIALLOAD when the request is cleaned.
In the Linux kernel, the following vulnerability has been resolved:
nvme-tcp: fix UAF when detecting digest errors
The Linux kernel CVE team has assigned CVE-2022-48686 to this issue.
Upstream advisory: https://lore.kernel.org/linux-cve-announce/2024050342-CVE-2022-48686-5e8e@gregkh/T
In the Linux kernel, the following vulnerability has been resolved:
RDMA/siw: bound Read Response placement to the RREAD length
In drivers/infiniband/sw/siw/siwqprx.c, siwprocrresp() places each inbound Read Response DDP segment at sge->laddr + wqe->processed and then accumulates wqe->processed, but it never checks the running total against the sink buffer length on continuation segments. siwchecksge() resolves and validates the sink memory only on the first fragment (the if (!mem) branch), and siwrrespcheckntoh() compares the cumulative length against wqe->bytes only on the final segment (the !frx->moreddpsegs guard).
A connected siw peer that answers an outstanding RREAD with Read Response segments that keep the DDP Last flag clear, carrying more total payload than the RREAD requested, drives wqe->processed past the validated sink buffer; the next siwrxdata() call writes out of bounds at sge->laddr + wqe->processed. siw runs iWARP over ordinary routable TCP, so the peer is the remote end of an established RDMA connection and needs no local privilege.
Bound every segment before placement, exactly as siwprocsend() and siwprocwrite() already do for their tagged and untagged paths, and terminate the connection with a base-or-bounds DDP error when the Read Response would overrun the sink buffer.
This is the second receive-path length fix for this file. A separate change rejects an MPA FPDU length that underflows the per-fragment remainder in the header decode; that guard does not cover this case, because here each individual segment length is self-consistent and only the accumulated placement offset overruns the buffer.
In the Linux kernel, the following vulnerability has been resolved:
pNFS: Fix use-after-free in pnfsupdatelayout()
When hitting the NFSLAYOUTRETURN branch in pnfsupdatelayout(), the code calls pnfspreparetoretrylayoutget(lo). If it succeeds, pnfsputlayouthdr(lo) is called before tracepnfsupdatelayout(), which still references 'lo'. This results in a use-after-free when the tracepoint accesses lo's fields.
Fix this by moving the tracepoint call before pnfsputlayouthdr(lo).
In the Linux kernel, the following vulnerability has been resolved:
nfsd: release layout stid on setlease failure
nfs4allocstid() publishes the new stid into cl->clstateids via idralloccyclic() under cllock before returning to nfsd4alloclayoutstateid(). When nfsd4layoutsetlease() then fails, the error path frees the layout stateid directly with kmemcachefree() without ever calling idrremove(), leaving the IDR slot pointing at freed slab memory. Any subsequent IDR walker (statesshow, client teardown) dereferences the dangling pointer.
The correct teardown for an IDR-published stid is nfs4putstid(), which removes the IDR slot under cllock, dispatches scfree (nfsd4freelayoutstateid) to release ls->lsfile via nfsd4closelayout(), and drops the nfs4file reference in its tail.
A second issue blocks that switch: nfsd4freelayoutstateid() unconditionally inspects ls->lsfencework via delayedworkpending() under lslock, but INITDELAYEDWORK(&ls->lsfencework, ...) currently runs only after the setlease call. On the setlease-failure path the destructor would touch an uninitialized delayedwork.
nfsd4alloclayoutstateid() nfs4allocstid() / idralloccyclic under cllock / nfsd4layoutsetlease() / fails / nfs4putstid() nfsd4freelayoutstateid() delayedworkpending(&ls->lsfencework) / needs INIT / nfsd4closelayout() / nfsdfileput(ls->lsfile) / putnfs4file()
Fix by hoisting the lsfenced / lsfencedelay / INITDELAYEDWORK initialization above the nfsd4layoutsetlease() call, and replace the manual nfsdfileput + putnfs4file + kmemcachefree cleanup with a single nfs4putstid(stp).