In the Linux kernel, the following vulnerability has been resolved:
smb: client: validate dacloffset before building DACL pointers
parsesecdesc(), buildsecdesc(), and the chown path in idmodetocifsacl() all add the server-supplied dacloffset to pntsd before proving a DACL header fits inside the returned security descriptor.
On 32-bit builds a malicious server can return dacloffset near U32MAX, wrap the derived DACL pointer below endofacl, and then slip past the later pointer-based bounds checks. buildsecdesc() and idmodetocifsacl() can then dereference DACL fields from the wrapped pointer in the chmod/chown rewrite paths.
Validate dacloffset numerically before building any DACL pointer and reuse the same helper at the three DACL entry points.
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix missing locking around retry adding new subreqs
Fix netfsretryreadsubrequests() and netfsretrywritestream() to take the appropriate lock when adding extra subrequests into stream->subrequests.
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix netfsreadtopagecache() to pause on subreq failure
Fix netfsreadtopagecache() so that it pauses the generation of new subrequests if an already-issued subrequest fails.
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix missing barriers when accessing stream->subrequests locklessly
The list of subrequests attached to stream->subrequests is accessed without locks by netfscollectreadresults() and netfscollectwriteresults(), and then they access subreq->flags without taking a barrier after getting the subreq pointer from the list. Relatedly, the functions that build the list don't use any sort of write barrier when constructing the list to make sure that the NETFSSREQINPROGRESS flag is perceived to be set first if no lock is taken.
Fix this by:
(1) Add a new listaddtailrelease() function that uses a release barrier to set the pointer to the new member of the list.
(2) Add a new listfirstentryornullacquire() function that uses an acquire barrier to read the pointer to the first member in a list (or return NULL).
(3) Use listaddtailrelease() when adding a subreq to ->subrequests.
(4) Use listfirstentryornullacquire() when initially accessing the front of the list (when an item is removed, the pointer to the new front iterm is obtained under the same lock).
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix cancellation of a DIO and single read subrequests
When the preparation of a new subrequest for a read fails, if the subrequest has already been added to the stream->subrequests list, it can't simply be put and abandoned as the collector may see it. Also, if it hasn't been queued yet, it has two outstanding refs that both need to be put. Both DIO read and single-read dispatch fail at this; further, both differ in the order they do things to the way buffered read works.
Fix cancellation of both DIO-read and single-read subrequests that failed preparation by the following steps:
(1) Harmonise all three reads (buffered, dio, single) to queue the subreq before prepping it.
(2) Make all three call netfsqueueread() to do the queuing.
(3) Set NETFSRREQALLQUEUED independently of the queuing as we don't know the length of the subreq at this point.
(4) In all cases, set the error and NETFSSREQFAILED flag on the subreq and then call netfsreadsubreqterminated() to deal with it. This will pass responsibility off to the collector for dealing with it.
In the Linux kernel, the following vulnerability has been resolved:
firmware: armffa: Snapshot notifier callbacks under lock
Both notification handlers currently look up a notifier callback under notifylock, drop the lock, and then dereference the returned notifier entry. A concurrent unregister can delete and free that entry in the gap, leaving the handler to dereference stale memory.
Copy the callback pointer and callback data while notifylock is still held and invoke the callback only after the lock is dropped. This keeps the existing callback execution model while removing the use-after-free window in both the framework and non-framework notification paths.
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:
netfs: Fix early put of sink folio in netfsreadgaps()
Fix netfsreadgaps() to release the sink page it uses after waiting for the request to complete. The way the sink page is used is that an ITERBVEC-class iterator is created that has the gaps from the target folio at either end, but has the sink page tiled over the middle so that a single read op can fill in both gaps.
The bug was found by KASAN detecting a UAF on the generic/075 xfstest in the cifsd kernel thread that handles reception of data from the TCP socket:
BUG: KASAN: use-after-free in copytoiter+0x48a/0xa20 Write of size 885 at addr ffff888107f92000 by task cifsd/1285 CPU: 2 UID: 0 PID: 1285 Comm: cifsd Not tainted 7.0.0 #6 PREEMPT(lazy) Call Trace: dumpstacklvl+0x5d/0x80 printreport+0x17f/0x4f1 kasanreport+0x100/0x1e0 kasancheckrange+0x10f/0x1e0 asanmemcpy+0x3c/0x60 copytoiter+0x48a/0xa20 skbdatagramiter+0x2c9/0x430 skbcopydatagramiter+0x6e/0x160 tcprecvmsglocked+0xce0/0x1130 tcprecvmsg+0xeb/0x300 inetrecvmsg+0xcf/0x3a0 sockrecvmsg+0xea/0x100 cifsreadvfromsocket+0x3a6/0x4d0 [cifs] cifsreaditerfromsocket+0xdd/0x130 [cifs] cifsreadvreceive+0xaad/0xb10 [cifs] cifsdemultiplexthread+0x1148/0x1740 [cifs] kthread+0x1cf/0x210
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:
KVM: arm64: vgic-its: Drop the translation cache reference only for the erased entry
vgicitsinvalidatecache() walks the per-ITS translation cache with xaforeach() and drops the cache's reference on each entry with vgicputirq(). It puts the iterated pointer, though, rather than the value returned by xaerase().
The function is called from contexts that do not exclude one another: the ITS command handlers hold itslock, the GITSCTLR write path holds cmdlock, and the path that clears EnableLPIs in a redistributor's GICRCTLR holds neither. Two or more of them can drain the same cache concurrently, and if each one observes the same entry, erases it and then puts it, the single reference the cache holds on that entry is dropped more than once. The entry can then be freed while an ITE still maps it.
xaerase() is atomic and returns the previous entry, so put only the entry that this context actually removed. The cache reference is then dropped exactly once per entry even when the invalidations run concurrently, and the behavior is unchanged when only one context runs.
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix potential UAF in netfsunlockabandonedreadpages()
netfsunlockabandonedreadpages(rreq) accesses the index of the folios it is wanting to unlock and compares that to rreq->nounlockfolio so that it doesn't unlock a folio being read for netfsperformwrite() or netfswritebegin().
However, given that netfsunlockabandonedreadpages() is called after NETFSRREQINPROGRESS is cleared, the one folio that it's not allowed to dereference is the one specified by ->nounlockfolio as ownership immediately reverts to the caller.
Fix this by storing the folio pointer instead and using that rather than the index. Also fix netfsunlockreadfolio() where the same applies.
In the Linux kernel, the following vulnerability has been resolved:
smb/client: fix out-of-bounds read in symlinkdata()
Since smb2checkmessage() returns success without length validation for the symlink error response, in symlinkdata() it is possible for iov->iovlen to be smaller than sizeof(struct smb2errrsp). If the buffer only contains the base SMB2 header (64 bytes), accessing err->ErrorContextCount (at offset 66) or err->ByteCount later in symlinkdata() will cause an out-of-bounds read.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: nftinner: Fix IPv6 innerthoff desync
In nftinnerparsel2l3(), when processing inner IPv6 packets, ipv6findhdr() correctly computes the transport header offset traversing all extension headers, but the result is immediately overwritten with nhoff + sizeof(ip6h) (40 bytes), which only accounts for the IPv6 base header. This creates a desync between innerthoff (wrong — points to extension header start) and l4proto (correct — e.g., IPPROTOTCP), enabling transport header forgery and potential firewall bypass. This issue affects stable versions from Linux 6.2.
For comparison, the normal (non-inner) IPv6 path correctly preserves ipv6findhdr()'s result. Removing the incorrect overwrite ensures that ipv6findhdr()'s calculated transport header offset is preserved, thereby fixing the desynchronization.
In the Linux kernel, the following vulnerability has been resolved:
ksmbd: close durable scavenger races against mfplist lookups
ksmbddurablescavenger() has two related races against any walker that iterates fci->mfplist, including ksmbdlookupfdinode() (used by ksmbdvfsrename) and the share-mode checks in fs/smb/server/smbcommon.c.
(1) fp->node list-head reuse. Durable-preserved handles can remain linked on fci->mfplist after session teardown so share-mode checks still see them while the handle is reconnectable. The scavenger collected expired handles by adding fp->node to a local scavengerlist after removing them from the global durable idr. Because fp->node is the same listhead used by mfplist, listadd(&fp->node, &scavengerlist) overwrites the mfplist links and corrupts both lists. CONFIGDEBUGLIST can report this on the share-mode walk path.
(2) Refcount race against mfplist walkers. The scavenger qualifies an expired durable handle with atomicread(&fp->refcount) > 1 and fp->conn under globalft.lock, removes fp from globalft, then drops globalft.lock before unlinking fp from mfplist and freeing it. During that gap fp is still linked on mfplist with fstate == FPINITED. ksmbdlookupfdinode() under mlock read calls ksmbdfpget() (atomicincnotzero on refcount that is still 1) and takes a live reference; the scavenger then unlinks and frees fp while the holder owns a reference, leading to UAF on the holder's subsequent ksmbdfdput() and on any field reads performed by a concurrent share-mode walker that iterates mfplist without taking ksmbdfpget() (smbcheckpermdleases-like paths).
Fix both:
Stop reusing fp->node as a scavenger-private list node. Remove one expired handle from globalft under globalft.lock, take an explicit transient reference, drop the lock, unlink fp->node from mfplist under fci->mlock, then drop both the durable lifetime and transient references with atomicsubandtest(2, &fp->refcount). If the scavenger is the last putter the close runs there; otherwise an in-flight holder that already raced through the mfplist lookup owns the final close via its ksmbdfdput() path. The one-at-a-time disposal can rescan the durable idr when multiple handles expire in the same pass, but durable scavenging is a background expiration path and the final full scan recomputes mintimeout before the next wait.
Clear fp->persistentid inside ksmbdremovedurablefd() right after idrremove(), so a delayed final close from a holder that snatched fp does not re-issue idrremove() on a persistent id that idralloccyclic() in ksmbdopendurablefd() may have already handed out to a brand-new durable handle.
Bypass the per-conn openfilescount decrement in putfdfinal() when fp is detached from any session table (fp->conn cleared by sessionfdcheck() at durable preserve -- paired with the volatileid clear at unpublish, so checking fp->conn alone is sufficient). The walker that owns the final close runs from an unrelated work->conn whose stats.openfilescount never tracked this durable fp; without this guard the holder would underflow that unrelated counter.
The two races are folded into one patch because patch (1) alone cleans up the corrupted list but leaves a deterministic UAF window for mfplist walkers that the transient-reference and persistentid discipline in (2) close; bisecting onto an intermediate state would land on a UAF that pre-patch chaos merely made less reproducible.
Validation: CONFIGDEBUGLIST coverage for the listhead reuse path. KASAN-enabled direct SMB2 durable-handle coverage that exercised ksmbddurablescavenger() and non-NULL ksmbdlookupfdinode() returns while durable handles expired under concurrent rename lookups, with no KASAN, UAF, list-corruption, ODEBUG, or WARNING reports. ---truncated---
In the Linux kernel, the following vulnerability has been resolved:
netfilter: nftinner: release locallock before re-enabling softirqs
Quoting sashiko: In the error path, localbhenable() is called before localunlocknestedbh().
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix potential for tearing in ->remoteisize and ->zeropoint
Fix potential tearing in using ->remoteisize and ->zeropoint by copying isizeread() and isizewrite() and using the same seqcount as for isize.
We need to make sure that netfslib and the filesystems that use it always hold ilock whilst updating any of the sizes to prevent isizeseqcount from getting corrupted.
In the Linux kernel, the following vulnerability has been resolved:
idpf: fix readdevclklock spinlock init in idpfptpinit()
In idpfptpinit(), readdevclklock is initialized after ptpscheduleworker() had already been called (and after idpfptpsettime64() could reach the lock). The PTP aux worker fires immediately upon scheduling and can call into idpfptpreadsrcclkregdirect(), which takes spinlock(&ptp->readdevclklock) on an uninitialized lock, triggering the lockdep "non-static key" warning:
[12973.796587] idpf 0000:83:00.0: Device HW Reset initiated [12974.094507] INFO: trying to register non-static key. ... [12974.097208] Call Trace: [12974.097213] <TASK> [12974.097218] dumpstacklvl+0x93/0xe0 [12974.097234] registerlockclass+0x4c4/0x4e0 [12974.097249] ? lockacquire+0x427/0x2290 [12974.097259] lockacquire+0x98/0x2290 [12974.097272] lockacquire+0xc6/0x310 [12974.097281] ? idpfptpreadsrcclkreg+0xb7/0x150 [idpf] [12974.097311] ? lockdephardirqsonprepare+0xde/0x190 [12974.097318] ? finishtaskswitch.isra.0+0xd2/0x350 [12974.097330] ? pfxptpauxkworker+0x10/0x10 [ptp] [12974.097343] rawspinlock+0x30/0x40 [12974.097353] ? idpfptpreadsrcclkreg+0xb7/0x150 [idpf] [12974.097373] idpfptpreadsrcclkreg+0xb7/0x150 [idpf] [12974.097391] ? kthreadworkerfn+0x88/0x3d0 [12974.097404] ? kthreadworkerfn+0x4e/0x3d0 [12974.097411] idpfptpupdatecachedphctime+0x26/0x120 [idpf] [12974.097428] ? rawspinunlockirq+0x28/0x50 [12974.097436] idpfptpdoauxwork+0x15/0x20 [idpf] [12974.097454] ptpauxkworker+0x20/0x40 [ptp] [12974.097464] kthreadworkerfn+0xd5/0x3d0 [12974.097474] ? pfxkthreadworkerfn+0x10/0x10 [12974.097482] kthread+0xf4/0x130 [12974.097489] ? pfxkthread+0x10/0x10 [12974.097498] retfromfork+0x32c/0x410 [12974.097512] ? pfxkthread+0x10/0x10 [12974.097519] retfromforkasm+0x1a/0x30 [12974.097540] </TASK>
Move the call to spinlockinit() up a bit to make sure readdevclklock is not touched before it's been initialized.
In the Linux kernel, the following vulnerability has been resolved:
net/mlx5e: Fix use-after-free in mlx5etxreportertimeoutrecover
mlx5etxreportertimeoutrecover() accesses sq->netdev after mlx5esafereopenchannels() has torn down and freed the channel (and its embedded SQs). Replace the three sq->netdev references with priv->netdev which is safe because priv outlives channel teardown.
The netdeverr() call already used priv->netdev for this reason; make the trylock/unlock and healthchanneleqrecover calls consistent.
This fixes the following KASAN splat:
BUG: KASAN: use-after-free in mlx5etxreportertimeoutrecover+0x1dd/0x360 [mlx5core] Read of size 8 at addr ffff889860ed0b28 by task kworker/u113:2/5277
Call Trace: mlx5etxreportertimeoutrecover+0x1dd/0x360 [mlx5core] devlinkhealthreporterrecover+0xa2/0x150 devlinkhealthreport+0x254/0x7c0 mlx5ereportertxtimeout+0x297/0x380 [mlx5core] mlx5etxtimeoutwork+0x109/0x170 [mlx5core] processonework+0x677/0xf20 workerthread+0x51f/0xd90 kthread+0x3a5/0x810 retfromfork+0x208/0x400 retfromforkasm+0x1a/0x30
In the Linux kernel, the following vulnerability has been resolved:
net: bcmgenet: keep RBUF EEE/PM disabled
Setting RBUFEEEEN | RBUFPMEN in RBUFENERGYCTRL breaks the RX path on GENET hardware once MAC EEE becomes active. RX traffic stops flowing while the link stays up and the usual descriptor/RX error counters remain quiet. In that state the MAC still accepts frames (rbufovflowcnt keeps climbing) but RBUF no longer forwards them to DMA, so rxpackets is no longer incremented at the netdev level. On some boards the corruption ends up as a paging fault in skbreleasedata via bcmgenetrxpoll on an LPI exit.
Reproduced on Pi 4B (BCM2711 + BCM54213PE) and confirmed by Florian Fainelli on an internal Broadcom 4908-family board with the same crash signature. RBUFPMEN is not publicly documented.
This shows up more often now that physupporteee() enables EEE by default, but it also affects older kernels as soon as TX LPI is turned on via ethtool, so it is not specific to recent changes.
Always clear RBUFEEEEN | RBUFPMEN in bcmgeneteeeenableset so the bits stay off across resets. UMAC and TBUF setup is left alone so TX-side EEE keeps working.
In the Linux kernel, the following vulnerability has been resolved:
ipv6: ioam: refresh hdr pointer before ioam6event()
Reported by Sashiko:
In ipv6hopioam(), the hdr pointer is initialized to point into the skb's linear data buffer. Later, the code calls skbensurewritable(), which might reallocate the buffer:
if (skbensurewritable(skb, optoff + 2 + hdr->optlen)) goto drop;
/ Trace pointer may have changed / trace = (struct ioam6tracehdr )(skbnetworkheader(skb) + optoff + sizeof(hdr));
ioam6filltracedata(skb, ns, trace, true);
ioam6event(IOAM6EVENTTRACE, devnet(skb->dev), GFPATOMIC, (void )trace, hdr->optlen - 2);
If the skb is cloned or lacks sufficient linear headroom, skbensurewritable() will invoke pskbexpandhead(), which reallocates the skb's data buffer and frees the old one, invalidating pointers to it. While the code recalculates the trace pointer immediately after the call to skbensurewritable(), it fails to recalculate the hdr pointer.
This patch fixes the above by recalculating the hdr pointer before passing hdr->optlen to ioam6event(), so that we avoid any UaF.
In the Linux kernel, the following vulnerability has been resolved:
smb: client: protect tccount increment in smb2findsmbsesstconunlocked()
Commit 96c4af418586 ("cifs: Fix locking usage for tcon fields") refactored cifs code to change cifstcpseslock for tclock around tccount changes.
There was missing lock around tccount increment inside smb2findsmbsesstconunlocked().
In the Linux kernel, the following vulnerability has been resolved:
block: recompute nrintegritysegments in blkinsertclonedrequest
blkinsertclonedrequest() already recomputes nrphyssegments against the bottom queue, because "the queue settings related to segment counting may differ from the original queue." The exact same reasoning applies to integrity segments: a stacked driver's underlying queue can have tighter virtboundarymask, segboundarymask, or maxsegmentsize than the top queue, in which case blkrqcountintegritysg() against the bottom queue produces a different count than the cached rq->nrintegritysegments inherited from the source request by blkrqprepclone().
When the cached count is lower than the bottom queue's actual count, blkrqmapintegritysg() trips
BUGON(segments > rq->nrintegritysegments);
on dispatch. The same families of stacked setups that motivated the existing nrphyssegments recompute -- dm-multipath fanning out to nvme-rdma in particular -- can produce this.
Mirror the nrphyssegments handling: when the request carries integrity, recompute nrintegritysegments against the bottom queue and reject the request if it exceeds the bottom queue's maxintegritysegments. blkrqcountintegritysg() and queuemaxintegritysegments() are both already available via <linux/blk-integrity.h>, which blk-mq.c includes.
This closes a latent gap in the stacking contract and brings the integrity-segment accounting in line with the existing phys-segment accounting.
In the Linux kernel, the following vulnerability has been resolved:
ixgbevf: fix use-after-free in VEPA multicast source pruning
ixgbevfcleanrxirq() prunes frames whose source MAC matches the VF's own address (VEPA multicast workaround) by freeing the skb and continuing to the next descriptor:
devkfreeskbirq(skb); continue;
The skb pointer is declared outside the while loop and persists across iterations. Because the continue skips the "skb = NULL" reset at the bottom of the loop, the next iteration enters the "else if (skb)" path and calls ixgbevfaddrxfrag() on the freed skb, dereferencing skbshinfo(skb)->nrfrags - a use-after-free in NAPI softirq context.
The sibling driver iavf already handles this correctly by nulling the pointer before continuing. Apply the same pattern here.
I do not have ixgbevf hardware; the bug was found by static analysis (scandropcontinueloops.py + semgrep dropcontinueinloop, multi-tool corroboration with the highest score in the scan). The UAF was confirmed under KASAN by loading a test module that reproduces the exact code pattern (alloc skb, kfreeskb, then read skbshinfo(skb)->nrfrags):
BUG: KASAN: slab-use-after-free in ixgbevfuaftestinit+0x100/0x1000 Read of size 8 at addr 000000006163ae78 by task insmod/30 freed 208-byte region [000000006163adc0, 000000006163ae90)
QEMU emulates igb (82576) but not ixgbe (82599), and the igbvf VF driver does not include the VEPA source pruning path, so a full end-to-end reproduction with emulated hardware was not possible.
In the Linux kernel, the following vulnerability has been resolved:
RDMA/siw: Reject MPA FPDU length underflow before signed receive math
A malicious connected siw peer can send an iWARP FPDU whose MPA length field (chdr->mpalen, 16 bit big-endian, peer-controlled) is smaller than the fixed DDP/RDMAP header for the announced opcode. Soft-iWARP parses the full header in siwgethdr() based on iwarppktinfo[opcode] .hdrlen, but never compares mpalen against that header length.
siwtcprxdata() then derives
srx->fpdupartrem = be16tocpu(mpalen) - fpdupartrcvd + MPAHDRSIZE;
where fpdupartrcvd equals iwarppktinfo[opcode].hdrlen at this point. For a tagged WRITE (hdrlen 16, MPAHDRSIZE 2) the smallest on-wire mpalen of 0 yields fpdupartrem = -14, and any mpalen below hdrlen - MPAHDRSIZE underflows to a negative int.
The signed value then flows into siwprocwrite()/siwprocrresp() as
bytes = min(srx->fpdupartrem, srx->skbnew);
is handed to siwcheckmem() as an int len (whose interval check addr + len > mem->va + mem->len is satisfied for a valid base when len is negative), and reaches siwrxdata() -> siwrxkva() / siwrxumem() -> skbcopybits() as a signed copy length. The header copy branch in skbcopybits() promotes that to sizet, producing a multi-gigabyte read.
KASAN under a KUnit harness that drives the real kernel TCP receive path -- a loopback AFINET socketpair, the malformed FPDU written via kernelsendmsg, skdataready firing in softirq, tcpreadsock dispatching to siwtcprxdata -- reports:
BUG: KASAN: use-after-free in skbcopybits+0x284/0x480 Read of size 4294967295 at addr ffff888... Call Trace: skbcopybits siwrxkva siwrxdata siwcheckmem siwprocwrite siwtcprxdata tcpreadsock siwqpllpdataready tcpdataready tcpdataqueue
Add the missing invariant at the earliest point where the peer header is fully assembled. iwarppktinfo[].hdrlen - MPAHDRSIZE is exactly the value the siw transmitter uses as the minimum mpalen for each opcode (drivers/infiniband/sw/siw/siwqp.c:33), so this matches the protocol contract. Out-of-range FPDUs terminate the connection with TERMERRORLAYERLLP / LLPETYPEMPA / LLPECODEFPDUSTART -- which is RFC 5044 Section 8 error code 3 ("Marker and ULPDU Length fields do not agree on the start of an FPDU"), the correct framing-error class for this inconsistency.
In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: vgic-its: Reject restored DTE with out-of-range numeventidbits
Userspace can restore an ITS Device Table Entry whose Size field encodes more EventID bits than the virtual ITS supports. The live MAPD path rejects that state, but vgicitsrestoredte() accepts it and stores the out-of-range value in dev->numeventidbits.
Reject restored DTEs with numeventidbits > VITSTYPERIDBITS before allocating the device. This mirrors the MAPD check and prevents the restored state from reaching vgicitsrestoreitt(), where the unchecked value can be converted into an oversized scanitstable() range.
In the Linux kernel, the following vulnerability has been resolved:
batman-adv: tt: fix TOCTOU race for reported vlans
The local TT based TVLV is generated by first checking the number of VLANs which have at least one TT entry. A new buffer with the correct size for the VLANs is then allocated. Only then, the list of VLANs s used to fill the VLAN entries in the buffer. During this time, the meshifvlanlistlock is held. But the actual number of TT entries of each VLAN can still increase during this time - just not the number of VLANs in the list.
But the prefilter used in the buffer size calculation might still cause an increase of the number of VLANs which need to be stored. Simply because a VLAN might now suddenly have at least one entry when it had none in the pre-alloc check - and then needs to occupy space which was not allocated.
It is better to overestimate the buffer size at the beginning and then fill the buffer only with the VLANs which are not empty.