In the Linux kernel, the following vulnerability has been resolved:
xfrm: Fix skb double-free in xfrmdevdirectoutput()
A return value other than 1 from localout() means that the skb has been consumed or its ownership was transferred. xfrmdevdirectoutput() nevertheless frees the skb on this path, causing a double-free when netfilter drops the packet and invalidating any other owner.
Return the localout() result directly, matching the ownership handling in xfrmoutputresume().
IB/isert: reject login PDUs declaring more data than was received
In the Linux kernel, the following vulnerability has been resolved:
sunrpc: xprtsock: annotate shared socket callbacks with READONCE/WRITEONCE
xprtsock replaces and restores sk->skdataready and sk->skwritespace on live sockets with plain stores, and xsudpdosetbuffersize() invokes sk->skwritespace via a plain load. These callback pointers are shared with generic socket and protocol paths that may read or invoke them concurrently, so xprtsock needs the same READONCE()/WRITEONCE() callback visibility contract that the validated 4022 family applied elsewhere.
When SUNRPC takes over an AFLOCAL, UDP, or TCP socket and later restores the lower-socket callbacks during teardown, another CPU may still hold an earlier callback snapshot. The plain replace/restore pattern leaves the same visibility hole as the validated 4022 family, so a stale snapshot can still invoke xsdataready() or xsudpwritespace() after the live callback fields have already been restored to the lower-socket handlers.
Use WRITEONCE() for the shared skdataready and skwritespace stores in xslocalfinishconnecting(), xsudpfinishconnecting(), xstcpfinishconnecting(), and xsrestoreoldcallbacks(). Use READONCE() for the direct skwritespace invocation in xsudpdosetbuffersize(). This matches the required callback visibility contract while leaving adjacent skstatechange and skerrorreport handling unchanged.
In the Linux kernel, the following vulnerability has been resolved:
nvmet: fix heap out-of-bounds read in nvmetauthnegotiate()
nvmetexecuteauthsend() allocates the DH-HMAC-CHAP message buffer with the host-supplied transfer length (tl) and hands it to nvmetauthnegotiate() without passing tl along. nvmetauthnegotiate() then reads the negotiate header and, for each of the halen hash identifiers and dhlen DH group identifiers, indexes into the fixed idlist[60] array (hashes at idlist[0..halen), groups at idlist[30..]).
Neither the transfer length nor halen/dhlen is validated. A malicious or non-conformant host can report a tl smaller than the negotiate structure, or a halen/dhlen larger than the array (both are u8, up to 255), making the loops read past the end of the allocated buffer (heap out-of-bounds read). The sibling nvmetauthreply() already validates tl against the structure size; the negotiate path did not.
Pass tl into nvmetauthnegotiate(), reject a tl that does not cover the negotiate data plus one full protocol descriptor, and reject halen/dhlen larger than NVMEAUTHDHCHAPMAXDHIDS.
In the Linux kernel, the following vulnerability has been resolved:
net: skbuff: don't skbtxerror() the source skb in skbzerocopy()
skbzerocopy() copies frags from @from into @to. On an skborphanfrags() failure it calls skbtxerror(@from), a destructive operation on the source skb the copy helper does not own. That completes @from's zerocopy uarg and clears SKBFLALLZEROCOPY, including the SKBFLSHAREDFRAG page-ownership marker.
Both callers already report the failure on their own drop path. nfnetlinkqueue does it at nlaputfailure, and Open vSwitch does it in the flow-miss drop arm of ovsdpprocesspacket(), so nothing is lost by dropping it here.
On Open vSwitch's OVSACTIONATTRUSERSPACE path the skb is not freed on this error: doexecuteactions() ignores outputuserspace()'s return value and, unless the upcall was the last action, keeps forwarding the same skb through the flow's remaining actions. The uarg is completed while that skb is still in flight, telling the producer its buffers are free, and SKBFLSHAREDFRAG is cleared on an skb the rest of the stack still handles. That flag is what makes espinput() call skbcowdata() instead of decrypting in place, so a later local ESP delivery can decrypt over frags the skb does not own privately.
Leave error reporting to the callers.
fs/ntfs3: fix slab-out-of-bounds write in nicreateattrlist()
In the Linux kernel, the following vulnerability has been resolved:
scsi: target: iscsi: Reserve a terminator byte for the login payload
iscsitargetcheckloginrequest() rejects a login PDU whose DataSegmentLength exceeds MAXKEYVALUEPAIRS, but the test is '>' and login->reqbuf is allocated with exactly MAXKEYVALUEPAIRS bytes. Since iscsitgetloginrx() receives payloadlength + padding bytes, where
padding = ((-payloadlength) & 3);
any payloadlength from 8189 to 8192 fills the whole 8192 byte buffer. The write stays in bounds, but no byte is left for a NUL terminator.
The buffer is subsequently consumed as a C string. In the CHAP path chapcheckalgorithm() calls kstrdup(astr), and extractparam() calls strstr(inbuf, pattern) followed by strlensemi(), none of which take a length. convertnulltosemi() additionally rewrites every embedded NUL to ';', so even a payload made of well formed NUL separated key=value records is left without a terminator. These walk past the end of the object into adjacent slab memory. It is reachable by an unauthenticated initiator against a portal configured for CHAP; when authentication is not required iscsiloginzerotsihs2() rewrites AuthMethod to None and the CHAP path is never entered.
Allocate one extra byte. kzalloc() zeroes it and nothing ever writes to it, as every writer copies to offset 0 for at most MAXKEYVALUEPAIRS bytes, so the buffer is always terminated.
In the Linux kernel, the following vulnerability has been resolved:
nvmet-auth: Synchronize timeout work during SQ teardown
nvmetauthsqfree() cancels authexpiredwork with canceldelayedwork(). If the work has already started, cancellation does not wait for the callback. Transport teardown can consequently free or reuse the queue containing struct nvmetsq while nvmetauthexpiredwork() still accesses that SQ.
Add a teardown-specific helper that synchronously drains the delayed work before freeing authentication state, and use it from nvmetsqdestroy(). Keep the non-synchronous helper for in-band authentication state cleanup, where the SQ owner remains alive.
In the Linux kernel, the following vulnerability has been resolved:
nvmet-tcp: fix out-of-bounds write when receiving an over-long PDU
nvmettcptryrecvpdu() reads a PDU header into the fixed 128-byte queue->pdu union, then computes the remaining payload length as
queue->left = hdr->hlen - queue->offset + hdgst;
and reads that many more bytes into &queue->pdu + queue->offset, without ever bounding the result against sizeof(queue->pdu).
A struct nvmetcpicreqpdu is itself 128 bytes, exactly the size of the union. Once a header digest has been negotiated (hdgst = 4), a second ICReq passes the hlen == nvmettcppdusize() check but yields queue->left = 128 - 8 + 4 = 124, so bytes 8..132 are written into the 128-byte buffer -- 4 bytes past its end, over queue->hdrdigest and queue->datadigest. Those bytes are attacker-controlled (an ICReq carries no digest), and the duplicate ICReq is only rejected later, after the overflow. A remote unauthenticated host can thus corrupt kernel memory adjacent to the receive buffer.
Reject any PDU whose declared length would read past the end of queue->pdu before the second recv.
In the Linux kernel, the following vulnerability has been resolved:
KVM: nVMX: Service local TLB flushes on failed nested VM-Enter
KVM services local TLB flushes on "full" nested VM-Exits (through nestedvmxvmexit()), but not if a nested VM-Enter fails (e.g. due to failed VMCS checks in nestedvmxenternonrootmode()).
However, it is possible that KVM had queued TLB flushes that need to be performed, even if the nested VM-Enter was not successful. For example, if VPID is disabled for L2 (via nestedvmxtransitiontlbflush(), or if via the MSR load lists, as the SDM says:
If any MSR is being loaded in such a way that would architecturally require a TLB flush, the TLBs are updated so that, after VM entry, the logical processor will not use any translations that were cached before the transition.
The SDM is unclear about when the TLB flush should occur, and whether or not a failed VM entry would flush the TLB, so it is safer to always do the TLB flush in this case.
More concretely, KVM also updates the last VPID L1 used for L2 in nestedvmxtransitiontlbflush() (i.e. lastvpid), even if the VM entry ultimately fails. With the current code, KVM could miss a TLB flush if L1 changes L2's VPID, then does a failed VM entry followed by a successful one, as the failed VM entry would update lastvpid but not actually flush the TLB. Servicing local TLB flushes on failed VM entries makes sure that the TLB is always flushed when lastvpid is updated.
In the Linux kernel, the following vulnerability has been resolved:
scsi: qla2xxx: Avoid double completion in async IOCB timeout
qla2x00asynciocbtimeout() tries to abort a timed-out async IOCB. When qla24xxasyncabortcmd() fails, both the SRBLOGINCMD path and the SRBCTRLVP/default path scan outstandingcmds[] for the SRB and then call sp->done(sp, QLAFUNCTIONTIMEOUT) unconditionally, without checking whether the SRB was actually found and removed.
If the response ISR completes the same handle first, it removes the SRB under qplockptr and runs sp->done() -> complete(sp->comp). The submitter qla24xxcontrolvp() wakes from waitforcompletion(), clears sp->comp, drops its reference and returns, reclaiming the on-stack completion. The timer reference keeps the SRB alive across the timeout handler, but not the submitter's stack. The timeout then issues a second sp->done() -> qlactrlvpspdone(), which evaluates "if (sp->comp) complete(sp->comp)"; with the pointer loaded before the submitter's NULL store, complete() writes into the freed stack frame, a use-after-free.
Track whether this path removed the SRB from outstandingcmds and only call sp->done() when it did, so the command is completed exactly once by whichever path owns it. This mirrors the spfound guard already used in qla24xxabortiocbtimeout().
ext4: fix out-of-bounds read in ext4readinlinedir()
In the Linux kernel, the following vulnerability has been resolved:
xfrm6: fix out-of-bounds write in xfrm6inputaddr() when secpath is full
The depth check in xfrm6inputaddr() is off by one:
if (1 + sp->len == XFRMMAXDEPTH) goto drop; ... sp->xvec[sp->len++] = x;
xfrminput() can leave sp->len == XFRMMAXDEPTH, and the transport-mode receive path re-enters IPv6 input via xfrmtransreinject() with that secpath preserved. If the inner packet carries a destination-options HAO option or a type-2 routing header, xfrm6inputaddr() is called with sp->len == XFRMMAXDEPTH; the check (1 + 6 == 6) is false, so sp->xvec[sp->len++] writes one slot past the 6-element xvec[]. The write stays within the secpath allocation (invisible to KASAN); UBSANBOUNDS flags it and panics under paniconwarn.
Use "sp->len >= XFRMMAXDEPTH", matching xfrminput(). This also restores one chain level the old check rejected at sp->len == 5.
UBSAN: array-index-out-of-bounds in net/ipv6/xfrm6input.c:309:10 index 6 is out of range for type 'xfrmstate [6]'
fs/ntfs3: validate ef->size covers the record's name and value
In the Linux kernel, the following vulnerability has been resolved:
isofs: fix out-of-bounds page array access on empty zisofs block
zisofsuncompressblock()'s empty-block fast path returns pcount << PAGESHIFT, ignoring the incoming poffset, unlike the decompression path which returns bytes produced relative to poffset. zisofsfillpages() uses that return to advance its page cursor, so when the zisofs block size is below PAGESIZE and a sub-page block leaves poffset partway into a page, a following empty block over-counts and advances pages[] one element past its end, after which "if (poffset && pages)" reads pages[1] out of bounds. rock.c only rejects a block-size shift > 17, so a crafted "ZF" Rock Ridge record can set it below PAGESHIFT; the bug is reached by an ordinary read() of a compressed file on such a mounted ISO9660 image.
Return the byte count relative to poffset and zero only [poffset, PAGESIZE) of the first page, matching the decompression path. The page-aligned case (poffset == 0) is unaffected.
BUG: KASAN: slab-out-of-bounds in zisofsreadfolio (fs/isofs/compress.c:290) Read of size 8 at addr ffff88800f5eac48 by task exploit/142 zisofsreadfolio (fs/isofs/compress.c:290) readpages (mm/readahead.c:184) ... filemapread (mm/filemap.c:2814) vfsread (fs/readwrite.c:574) x64syspread64 (fs/readwrite.c:769) dosyscall64 (arch/x86/entry/syscall64.c:94) entrySYSCALL64afterhwframe (arch/x86/entry/entry64.S:121) The buggy address is located 0 bytes to the right of the allocated 8-byte region in the kmalloc-8 cache
In the Linux kernel, the following vulnerability has been resolved:
nfsd: gate nfs3 setacl by argp->mask
nfsd3procsetacl() calls setposixacl() unconditionally for both ACLTYPEACCESS and ACLTYPEDEFAULT, passing argp->aclaccess and argp->acldefault verbatim. The NFSv3 ACL decoder only populates those pointers when the corresponding mask bit is set:
nfs3svcdecodesetaclargs() if (args->mask & NFSACL) decode into aclaccess if (args->mask & NFSDFACL) decode into acldefault / otherwise the pointer stays NULL (pcargzero) /
nfsd3procsetacl() setposixacl(.., ACLTYPEACCESS, argp->aclaccess) setposixacl(.., ACLTYPEDEFAULT, argp->acldefault)
setposixacl(idmap, dentry, type, NULL) is the VFS "remove this ACL type" operation. A NULL pointer that means "the client did not send this arm" is therefore indistinguishable from "the client asked to remove this ACL". A SETACL with mask=NFSACL silently drops the directory's default ACL; mask=0 drops both.
The sibling nfsd3procgetacl() already consults argp->mask before touching each arm; mirror that in setacl.
Fix by wrapping each setposixacl() call in the matching mask bit check and initializing error to 0 before inodelock so that a request with neither bit set leaves the on-disk ACLs untouched and returns nfsok. The outdroplock path and the unconditional posixaclrelease() at out: are preserved; both NULL-tolerate the skipped arms.
In the Linux kernel, the following vulnerability has been resolved:
nfsd: initialize copy-notify stateid before publishing it
nfsd4copynotify() finished initializing the cpntf state after nfs4allocinitcpntfstate() had already linked it into the s2scpstateids IDR and the parent's sccplist, with cscount == 1 (the membership reference) and none held for the caller. A racing OFFLOADCANCEL (crafted clid == nn->s2scpclid plus the guessable soid) could reach managecpntfstate() and free the entry, turning the caller's subsequent cpncnrstateid read and cppstateid/cppclid writes into use-after-free. The owning clientid was also only recorded after publication, so it could not gate an ownership check in that window.
Record cppstateid and cppclid inside nfs4allocinitcpntfstate() before nfs4initcpstate() publishes the entry, and return it with an extra reference. The caller reads the stateid under that reference and drops it with nfs4putcpntfstate(); on a late error the laundromat reaps the entry.
In the Linux kernel, the following vulnerability has been resolved:
NFSD: Prevent lock owner use-after-free during client teardown
destroyclient() releases a client's open owners, but a lock owner whose only reference is a blocked lock (nbl) stays on clownerstrhashtbl. clienthasstate() does not count a bare owner, so DESTROYCLIENTID can reach destroyclient() with such owners present.
destroyclient() then walks the table, calling removeblockedlocks() on each owner without a reference. Freeing a blocked lock drops the owner reference held via flcowner. The per-net laundromat reaps blocked locks from nn->blockedlockslru independently of client state. The two paths share blockedlockslock only for the list splice, not the owner's lifetime. The laundromat therefore frees the owner as destroyclient() dereferences it, a NULL dereference in removeblockedlocks().
nfsd4releaselockowner() holds a reference across the same call; destroyclient() does not. Hold cllock across the walk, taking a reference and unhashing each owner, then drop it before removeblockedlocks() and nfs4putstateowner(), which take blockedlockslock and cllock.
In the Linux kernel, the following vulnerability has been resolved:
libceph: reject buckets with mismatched CRUSH ids
crushdecode() stores bucket data by array slot, and the mapper later derives the per-bucket workspace index from the decoded bucket id. A malformed map can therefore make one bucket reuse another bucket's workspace by encoding an id different from -1 - slot.
For uniform buckets, the second replica selection expands the source bucket's permutation into that aliased workspace buffer. If the source bucket is larger than the aliased bucket, the write runs past the smaller permutation array and can escape the kvmalloc'd CRUSH workspace. KASAN reports a slab OOB write of 4 bytes in bucketpermchoose().
Reject buckets whose encoded id does not match their array slot. Valid CRUSH maps already use the canonical negative id corresponding to the bucket slot, so this restores the invariant expected by work->work[-1 - in->id] without changing valid map behavior.
ceph: reject exporttargets ranks >= CEPHMAXMDS in mdsmap decode
ceph: bound xattr value length in buildxattrs()
ceph: bound numexporttargets array for mds info v2/v3
audit: avoid dropping live tree ref on fsnotify rule autoremove
In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: xdrbuftrim: clamp buf->len to avoid underflow
xdrbuftrim() trims len bytes from the tail of an xdrbuf by walking the tail, pages, and head iovecs. Each per-section step uses mint() so it never removes more bytes than that section holds, but the final accounting at the fixlen label subtracts the total bytes actually consumed from buf->len without any clamp:
fixlen: buf->len -= (len - trim);
When the caller has set buf->len to a value smaller than the sum of the iovlens, (len - trim) can exceed buf->len and the unsigned subtraction wraps to near UINTMAX. gsskrb5unwrapv2() reaches xdrbuftrim() in exactly that state:
buf->head[0].iovlen -= GSSKRB5TOKHDRLEN + headskip; buf->len = len - (GSSKRB5TOKHDRLEN + headskip); xdrbuftrim(buf, ec + GSSKRB5TOKHDRLEN + tailskip);
buf->len is a small wire-derived value while the iovlens are at page scale, so the per-section loops legitimately consume far more bytes than buf->len records. The wrapped buf->len then propagates as the authoritative stream bound into every downstream XDR decoder.
Fix by clamping the decrement so buf->len bottoms out at zero:
buf->len -= mint(unsigned int, buf->len, len - trim);
On the normal path where the iovlens sum to buf->len, (len - trim) is always <= buf->len and the result is identical to before. No callers change behavior outside the underflow case.
In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: svcauthgss: enforce krb5 token minimum length
svcauthgssunwrappriv() validates only an upper bound on the wire-supplied opaque length before handing the buffer to gssunwrap():
if (len > xdrstreamremaining(xdr)) goto unwrapfailed; offset = xdrstreampos(xdr); ... majstat = gssunwrap(ctx, offset, offset + len, buf);
The wire value len flows unchanged as the upper bound into the krb5 unwrap path, so a len in [0, 16] passes this check and is handed to gssunwrap(). For a krb5 v2 context that lands in gsskrb5unwrapv2(), which reads the 16-byte RFC 4121 token header fields at ptr+4 and ptr+6 and then calls rotateleft() before any integrity check. With a sub-header length the header reads run past the token, and rotateleft()'s shift %= buf->len path can divide by zero when buf->len has been driven to zero by the truncated token. A header-only token (len == 16) is equally invalid: with a non-zero RRC field and the opaque blob ending at the XDR buffer boundary, rotateleft() builds a zero-length subbuffer, reaching the same division.
Reject the token at the server entry point before it reaches the krb5 unwrap core. A valid sealed RFC 4121 token must contain the 16-byte header plus at least some encrypted payload.
Fix by adding a minimum-length check immediately after the existing upper-bound check:
if (len <= GSSKRB5TOKHDRLEN) goto unwrapfailed;
In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: harden gsskrb5unwrapv2 against short tokens
gsskrb5unwrapv2() reads the EC and RRC header fields at ptr+4 and ptr+6 before validating that the token is at least GSSKRB5TOKHDRLEN (16) bytes long, and its rotateleft() helper passes buf->len - base to xdrbufsubsegment() without verifying that base <= buf->len. When a caller hands in a sub-16-byte token, or a token whose declared len leaves base past the end of the buffer, three distinct failures follow:
gsskrb5unwrapv2(offset, len, buf) ptr = buf->head[0].iovbase + offset ec = (ptr + 4) / OOB read on short head / rrc = (ptr + 6) / OOB read on short head / rotateleft(offset + 16, buf, rrc) xdrbufsubsegment(buf, &subbuf, base, buf->len - base) / u32 wrap when base > len / rotateleft(&subbuf, shift) shift %= buf->len / divide-by-zero when base == len /
After decryption, the cleanup arithmetic has the same shape:
movelen = mint(unsigned int, buf->head[0].iovlen, len); movelen -= offset + GSSKRB5TOKHDRLEN + headskip; BUGON(offset + GSSKRB5TOKHDRLEN + headskip + movelen > buf->head[0].iovlen);
The BUGON re-adds the value just subtracted, so it reduces to min(A, B) > A and is permanently false; it cannot catch the unsigned underflow of movelen, which then drives a ~UINTMAX-byte memmove().
Add four defense-in-depth guards inside the unwrap core so it is safe regardless of what its callers validate:
- reject tokens with len - offset < GSSKRB5TOKHDRLEN before touching ptr+4/ptr+6; - bail from rotateleft() when buf->len <= base, covering both the underflow and zero-length cases; - return early from rotateleft() when buf->len is zero, so the shift %= buf->len modulo cannot fault; - replace the dead BUGON with a live check that returns GSSSDEFECTIVETOKEN before the movelen subtraction.
In the Linux kernel, the following vulnerability has been resolved:
svcrdma: Fix pclforeachsegment for empty chunks
When a parsed chunk list contains a chunk whose chsegcount is zero, pclforeachsegment computes its inclusive upper bound as &chunk->chsegments[chsegcount - 1]. chsegcount is u32, so the subtraction wraps to 0xFFFFFFFF and the bound lands far past the chsegments flex array. The loop body then walks unrelated memory at sizeof(struct svcrdmasegment) stride until it faults.
A zero-segcount chunk is reachable from the wire: xdrcheckwritechunk() only rejects segcount values greater than rcmaxpages, and pclallocwrite() links a freshly allocated chunk onto rcwritepcl/rcreplypcl before its segment-fill loop runs, so a Write or Reply chunk advertising zero segments leaves chsegcount == 0 on the list. When the transport has negotiated Send-With-Invalidate, svcrdmagetinvrkey() iterates all four PCLs with pclforeachsegment and dereferences segment->rshandle on each iteration, turning the underflow into an out-of-bounds read and a general protection fault.
xdrcheckwritelist / xdrcheckreplychunk pclallocwrite() chunk = pclallocchunk(...) / chsegcount = 0 / listaddtail(&chunk->chlist, &pcl->clchunks) / fill loop iterates zero times for wire segcount 0 /
svcrdmagetinvrkey() pclforeachchunk(rcwritepcl) pclforeachsegment(segment, chunk) pos <= &chsegments[0u - 1u] / 0xFFFFFFFF / segment->rshandle / OOB read -> GPF /
Fix by switching the macro to a half-open upper bound that uses chsegcount directly. For chsegcount == 0 the loop start equals the loop end and the body is skipped; for chsegcount > 0 the iteration range is unchanged. All six existing call sites in net/sunrpc/xprtrdma/svcrdmarecvfrom.c and net/sunrpc/xprtrdma/svcrdmarw.c remain correct under the new bound, so no caller changes are needed.
In the Linux kernel, the following vulnerability has been resolved:
nvme-tcp: do not accept C2HData based on blkrqpayloadbytes() alone
Commit 25e5cb780e62 ("nvme-tcp: fix possible crash in writezeroes processing") established that blkrqpayloadbytes() must not be read without first checking blkrqnrphyssegments(), and recorded the result in nvmetcpsetupcmdpdu() as req->datalen. The receive side was left as it was.
The two differ for REQOPWRITEZEROES, which has no physical segments but a non-zero blkrqbytes(), so setup leaves req->iter untouched while the receive gate lets a C2HData through and nvmetcprecvdata() copies into whatever the previous command on that tag left there. The driver-private area is zeroed only when the tag set is allocated.
Reproduced with a test target that leaves a residual iterator on a tag and then sends a C2HData for a WRITEZEROES command on the same tag:
BUG: KASAN: wild-memory-access in copytoiter+0x642/0x1330 Write of size 512 at addr ffe728c2175dfa81 by task kworker/0:1H/103
CPU: 0 UID: 0 PID: 103 Comm: kworker/0:1H Not tainted 7.2.0-rc5-NVMETCP-gf5098b6bae76 #1 PREEMPT(lazy) 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 Workqueue: nvmetcpwq nvmetcpiowork Call Trace: <TASK> dumpstacklvl+0x53/0x70 kasanreport+0xce/0x100 ? copytoiter+0x642/0x1330 kasancheckrange+0x105/0x1b0 asanmemcpy+0x3c/0x60 copytoiter+0x642/0x1330 ? pfxsockhasperm+0x10/0x10 ? workerthread+0x45b/0xd10 ? pfxcopytoiter+0x10/0x10 ? rawspinlockbh+0x83/0xe0 ? pfxrawspinlockbh+0x10/0x10 skbdatagramiter+0xf3/0x820 ? pfxsimplecopytoiter+0x10/0x10 ? asanmemcpy+0x3c/0x60 ? skbcopybits+0x58d/0x830 skbcopydatagramiter+0x37/0x120 nvmetcprecvskb+0xa07/0x4320 ? pfxnvmetcprecvskb+0x10/0x10 tcpreadsock+0x1ab/0x810 ? pfxnvmetcprecvskb+0x10/0x10 ? pfxlocksocknested+0x10/0x10 ? pfxtcpreadsock+0x10/0x10 nvmetcptryrecv+0x152/0x1e0 ? pfxnvmetcptryrecv+0x10/0x10 ? pfxmutexunlock+0x10/0x10 nvmetcpiowork+0x1e4/0x6c0 ? schedule+0x181a/0x49f0 ? pfxnvmetcpiowork+0x10/0x10 processonework+0x633/0x1030
Keep the blkrqpayloadbytes() test and add req->datalen to it. The old test is what rejects a C2HData naming a tag that is no longer in flight, because blkupdaterequest() zeroes rq->datalen on completion; req->datalen and req->currbio are driver-private and survive completion, so they cannot stand in for it. Setup initialises the iterator only when both req->currbio and req->datalen are set, so the gate now tests the same two.
In the Linux kernel, the following vulnerability has been resolved:
sctp: stop processing a packet once its association is deleted
sctpendpointbhrcv() looks the association up only when chunk->asoc is NULL, and caches the result in chunk->asoc and chunk->transport without taking a reference.
A packet that matches no association is handed to the endpoint, so a peer can bundle COOKIE ECHO, SHUTDOWN and SHUTDOWN ACK in one packet. The COOKIE ECHO creates the association, the SHUTDOWN chunk caches it, and with the outqueue empty the SHUTDOWN ACK reaches sctpsfdo92final(), so the association and its transports are freed.
The endpoint loop has no counterpart to the asoc->base.dead check in sctpassocbhrcv(). The next chunk writes to lasttimeheard in the freed transport and is then passed to sctpdosm() with the freed association. The transport is freed through RCU, so this needs the packet to come off the socket backlog, where the loop runs in task context.
The endpoint loop cannot do the same check: it holds no reference on the association, so reading asoc->base.dead would itself be a use-after-free. Mark the packet for discard in the command interpreter, just before it deletes the association. That is also before sctpinqfree() releases the chunk on the association receive path.
sctpsfdo524dupcook() issues SCTPCMDDELETETCB for the temporary association, while the one the packet belongs to stays alive. A restarting peer can bundle DATA behind its COOKIE ECHO, so compare against chunk->asoc and leave that case alone.
In the Linux kernel, the following vulnerability has been resolved:
iommu/vt-d: Force requesting ACS when tboot is enabled
Currently the conditions of requesting ACS in detectinteliommu() don't include tboot, leading to a possible misconfiguration with ACS disabled (e.g. due to user opts) while iommu is later forced on by tbootforceiommu().
Fix it by checking tboot in detectinteliommu().