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().
In the Linux kernel, the following vulnerability has been resolved:
inetpeer: randomize RB-tree node comparison using SipHash
The inetpeer rate limiting system stores peer entries in a Red-Black tree keyed deterministically on the remote IP address. Because tree lookups walk the RB-tree using standard lexicographical comparisons (inetpeeraddrcmp), an off-path adversary can predict the exact topology of the tree and the sequence of nodes traversed during lookups (the gcstack candidate list).
By combining deterministic tree traversal with aggressive garbage collection (triggered when tree size exceeds inetpeerthreshold), an attacker can selectively force the eviction of targeted inetpeer nodes. When an evicted node is subsequently re-created upon receiving a new packet, its rate-limiting token bucket (ratetokens, ratelast) is reset to full capacity. This creates a side-channel primitive allowing off-path attackers to bypass IP-keyed ICMP rate limits and infer open UDP ports (similar to SAD DNS style attacks).
Mitigate this by randomizing the RB-tree node comparison logic using SipHash with a secret key (inetpeerhashkey) initialized via netgetrandomonce(). Nodes are ordered in the tree by SipHash(addr, key) rather than raw IP addresses. Because the secret key is unknown to external entities, the tree layout and lookup traversal paths are unpredictable to off-path adversaries, breaking the deterministic eviction gadget.
Cache the computed 64-bit SipHash (hash) in struct inetpeer and compute the target hash (dhash) once at the beginning of inetgetpeer() to avoid recomputing SipHash at every step of the RB-tree walk.
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.
ceph: properly decrypt filenames in vmalloc() buffers
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:
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()
fs/ntfs3: validate ef->size covers the record's name and value
In the Linux kernel, the following vulnerability has been resolved:
nfsd: set SCSTATUSFREED in nfsd4droprevokedstid for delegations
nfsd4droprevokedstid() handles FREESTATEID for admin-revoked delegations but does not set SCSTATUSFREED before releasing cllock. revokedelegation() uses this flag to detect whether FREESTATEID has already processed the delegation -- without it, the freed delegation is added to clrevoked via listadd(), producing a use-after-free when clrevoked is later traversed in destroyclient().
The SCSTATUSREVOKED path in nfsd4freestateid() (line 7983) already sets SCSTATUSFREED correctly. Apply the same pattern to the SCSTATUSADMINREVOKED path in nfsd4droprevokedstid().
In the Linux kernel, the following vulnerability has been resolved:
nfsd: size fhverify server sockaddr slot by xptlocallen
The nfsdfhverify and nfsdfhverifyerr tracepoints declare the server sockaddr slot sized by xptremotelen but fill it from xptlocal using xptlocallen:
TPSTRUCTentry( ... sockaddr(server, rqstp->rqxprt->xptremotelen) ... ) TPfastassign( ... assignsockaddr(server, &rqstp->rqxprt->xptlocal, rqstp->rqxprt->xptlocallen); ... )
When xptlocallen exceeds xptremotelen, assignsockaddr's memcpy writes past the reserved ring-buffer slot. In the reverse direction (xptlocallen < xptremotelen) the slot is oversized and the unwritten tail leaks prior ring-buffer contents to trace consumers.
The write-past-end case is reachable on NFS/UDP. svcxprtsetremote() is only called from svctcpaccept() (net/sunrpc/svcsock.c) and from the RDMA connect path; svccreatesocket() for UDP calls only svcxprtsetlocal(), so xptremotelen stays 0 for the xprt's lifetime. Every fhverify trace for an NFSv2/v3-over-UDP request then copies 16 or 28 bytes from xptlocal into a zero-byte slot.
The other NFSD tracepoints that record the server address (NFSDTRACEPROCCALLFIELDS, NFSDTRACEPROCRESFIELDS, SVCRQSTENDPOINTFIELDS) already size the server slot by xptlocallen; nfsdfhverify and nfsdfhverifyerr were the only exceptions.
Fix by sizing the server slot with xptlocallen so the declared slot matches the copy length. The client slot and its assignment already agree on xptremotelen and are left untouched.
In the Linux kernel, the following vulnerability has been resolved:
nfsd: drop the stateid, not the stateowner, on seqidop replay retry
In nfs4preprocessseqidop() the stateid is obtained from nfsd4lookupstateid(), which holds a reference on the nfs4stid (sccount) but takes no reference on the stateowner. openlockstateid() merely casts that stid and likewise takes no reference.
When nfsd4cstateassignreplay() returns -EAGAIN (the replay owner is being torn down, RPUNHASHED) it has not taken a stateowner reference on that path. The error handling nevertheless called nfs4putstateowner(stp->ststateowner), dropping an socount reference the function never acquired -- risking a stateowner refcount underflow and use-after-free -- while leaking the sccount reference held on the stid. The leaked stid reference can also stall a concurrent nfsd4closeopenstateid() waiting for sccount to drop.
Drop the reference actually held -- the stid -- before retrying. The stateowner stays alive through the reference held by the stid. This mirrors the open path in nfsd4processopen1(), where the put balances a reference that path explicitly holds on the stateowner.
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix BUGON in nfsd4alloclayoutstateid on racing delegation revoke
nfsd4alloclayoutstateid reads fp->fidelegfile without holding filock when the parent stateid is a delegation. A concurrent delegation revoke via the laundromat can clear fidelegfile under filock, causing nfsdfileget() to return NULL and triggering the BUGON.
This race is client-reachable: two NFS clients can trigger it by having one hold a delegation while another opens the same file to force a recall. When the first client doesn't respond to the recall, the laundromat revokes it. A concurrent LAYOUTGET from any client using the delegation stateid hits the race window.
Fix this by taking filock around the fidelegfile read in the SCTYPEDELEG path, matching the locking discipline of the findanyfile() arm, and replacing the BUGON with a graceful error return that cleans up the partially-initialized layout stateid.
In the Linux kernel, the following vulnerability has been resolved:
NFSD: Prevent client use-after-free during delegation revoke
A delegation stateid holds only a bare pointer to its owning nfs4client and does not keep it alive. The client survives its stateids only because destroyclient() drains cldelegations and clrevoked before freeclient() runs.
nfs4laundromat() breaks that invariant: it unhashes an expired delegation from cldelegations, drops deleglock, then revokedelegation() relinks it onto clrevoked under cllock. In that window the delegation is on neither list, so clienthasstate() can report no remaining state.
Every teardown path first requires clrpcusers to be zero, but the laundromat holds no such reference. A client whose recalled delegation has just timed out can therefore reach freeclient() while revokedelegation() is still about to dereference cllock, a use-after-free.
Pin the client with clrpcusers across the revoke so teardown blocks until it completes, then reap the delegation from clrevoked. A client already expiring reaps its own, so skip it and leave the delegation on delrecalllru.
In the Linux kernel, the following vulnerability has been resolved:
ceph: fix UAF in kickflushingcaps() on cf entry freed during unlock
listforeachentry() iterates ci->icapflushlist but drops icephlock to send cap messages. During the unlock window, handlecapflushack() can acquire icephlock, detach cf entries with tid <= flushtid from the list, release icephlock, and free them via cephfreecapflush() outside any lock. When the original thread reacquires icephlock and the for-loop macro advances via cf = listnextentry(cf, ilist), it dereferences cf->ilist.next on freed memory.
The race timeline:
kickflushingcaps() handlecapflushack() ----------------------- ----------------------- holds icephlock <--- iterates to cf (tid=10) prepares FLUSH message drops icephlock <--- sendcap() ── FLUSH(tid=10) MDS sends FLUSHACK(tid=10) ---> acquires icephlock cf->tid(10) <= flushtid(10), detaches cf from icapflushlist drops icephlock cephfreecapflush(cf) <- frees it! acquires icephlock <--- for-loop advances: cf = listnextentry(cf, ilist) -- UAF on freed cf->ilist.next
The cf was just sent by kickflushingcaps itself via sendcap(). The MDS may respond with FLUSHACK quickly enough that handlecapflushack() frees cf before kickflushingcaps can finish the iteration.
Fix by converting to a manual while loop: save the next pointer under icephlock before dropping it, then use the saved pointer after reacquiring, so the potentially-freed cf is never accessed again.
In the Linux kernel, the following vulnerability has been resolved:
ceph: fix UAF in checknewmap() on session freed during unlock
checknewmap() iterates mdsc->sessions[] and for each active session drops mdsc->mutex to perform per-session operations. The forced-close path (rank removed from map) correctly takes a reference on s via cephgetmdssession() before releasing mdsc->mutex, but three other paths do not:
Path A (address changed): mutexunlock → mutexlock(&s->smutex) Path B (reconnect): mutexunlock → sendmdsreconnect(mdsc, s) Path C (active transition): mutexunlock → mutexlock(&s->smutex)
Without the extra reference, another thread can acquire mdsc->mutex during the unlock window, call unregistersession() which drops the last reference on s, and free it. The original thread then accesses freed memory via s->smutex.
Fix by adding cephgetmdssession(s) before each mutexunlock and cephputmdssession(s) after the corresponding mutexlock, matching the pattern already used in the forced-close path.
Race timeline (Path A):
Thread A (checknewmap) Thread B (another map update holds mdsc->mutex or session teardown) -------------------------- -------------------------- s = mdsc->sessions[i] (refcount == 1, held only by sessions[] array)
mutexunlock(&mdsc->mutex) ---> acquires mdsc->mutex unregistersession(mdsc, s) sessions[i] = NULL cephputmdssession(s) refcount: 1 -> 0 kfree(s) <--- freed!
mutexlock(&s->smutex) UAF on freed s->smutex
ceph: bound numexporttargets array for mds info v2/v3
In the Linux kernel, the following vulnerability has been resolved:
smb: client: clear ce->tgthint in freetgts()
When freetgts() frees all structures in ce->tlist, ce->tgthint is left pointing to one of the freed cachedfstgt structures.
If ce->tgthint is not reset before it is used later, it results in a use-after-free.
Set ce->tgthint to NULL in freetgts() after the elements are freed to reflect that no elements remain.
In the Linux kernel, the following vulnerability has been resolved:
smb: client: fix ALIGN() overflow in symlinkdata() error context loop
The check added by commit 7d9a7f1f96cd ("smb/client: fix possible infinite loop and oob read in symlinkdata()") compared the post-ALIGN length against the remaining buffer, but ALIGN() itself can overflow: for ErrorDataLength near UINT32MAX (e.g. 0xFFFFFFF9), ALIGN(x, 8) wraps to 0, so the subsequent bounds check passes, and the loop advances by zero bytes leaving 'p' pointing into stale data.
Fix by checking the raw ErrorDataLength against the remaining space before applying ALIGN(), then checking again after. Since rawlen is bounded by the buffer, rawlen + 7 cannot overflow, so the second check is an exact post-alignment bounds guard.
In the Linux kernel, the following vulnerability has been resolved:
smb: client: reject a tree connect response whose byte count is too small
CIFSTCon() bounds its strnlen() over the byte area with the server's ByteCount minus two, which for ByteCount 0 or 1 goes negative as an int and converts to a huge sizet. The later subtraction wraps the u16 bytesleft, and that is what bounds cifsstrndupfromutf16(): a bound of up to 65535 against a ~16 KB cifsreqpoolp object runs off the end of the slab object, and the bytes reach userspace through tcon->nativeFileSystem in /proc/fs/cifs/DebugData.
Reject a byte area too small for what the parser consumes. Two bytes is the least it can consume, and no conformant response carries fewer. The new trace point is the 129th smbeiotrace entry, which mode(byte) cannot represent, so the attribute goes with it.
In the Linux kernel, the following vulnerability has been resolved:
ntfs: bound the free-cluster bitmap scan to the volume
vol->lcnemptybitsperpage is sized from vol->nrclusters at mount, but ntfsclusteralloc() bounds its scan of that array by the size of $Bitmap. Those are independent on-disk quantities and the mount-time check only rejects a $Bitmap that is too small, so an image whose $Bitmap covers more clusters than the volume has lets the scan index past the array. A run whose LCN lies in that gap takes the allocator straight there, since the caller passes the file's own last LCN as its locality hint. KASAN reports a slab out-of-bounds read when a file on such a volume is extended.
Clamp the scan to what that array covers, mirroring the maxindex calculation the mount-time scan already uses, and reject a decoded LCN at or beyond nrclusters in the mapping pairs decoder. Conforming volumes are unaffected.
In the Linux kernel, the following vulnerability has been resolved:
ntfs: reject invalid empty mapping pairs
Reject an attribute with empty mapping pairs if it has inconsistent highest VCN and size.
In the Linux kernel, the following vulnerability has been resolved:
mpls: reload header after pskbmaypull()
mplsselectmultipath() calls mplsmultipathhash() to choose a nexthop when an MPLS route has multiple nexthops. While walking the MPLS label stack, the hash routine caches hdr for the current label. After finding the bottom-of-stack label, it calls pskbmaypull() before reading the inner IP header.
If an skb is constructed with the inner IP header in nonlinear data and insufficient tailroom in the linear head, pskbmaypull() calls pskbexpandhead() to replace the skb head and free the old one. This leaves hdr pointing to freed memory. The IPv6 path can invalidate hdr again when it performs a second pull for the larger header.
The issue was found through static analysis. A reproducer sending a legal Geneve packet through a bareudp/MPLS multipath setup triggered the same KASAN report in 2 of 2 unpatched runs:
BUG: KASAN: slab-use-after-free in mplsselectmultipath Read of size 1 at addr ffff88800ecc6e20 by task ksoftirqd/1/23
Call Trace: mplsselectmultipath mplsforward netifreceiveskblistcore netifreceiveskblistinternal napicompletedone grocellpoll napipoll netrxaction
Freed by task 23: kfree pskbexpandhead pskbpulltail mplsselectmultipath
Reload hdr from the current skb head after each successful pull before deriving the inner IPv4 or IPv6 header pointer.
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: Reject short RFC 4121 MIC tokens in gsskrb5verifymicv2
gsskrb5verifymicv2() reads the token ID at ptr[0..1], the flags byte at ptr[2], and padding at ptr[3..7], then passes ptr + GSSKRB5TOKHDRLEN and cksumlen to gsskrb5micbuildsg(). None of these accesses check readtoken->len first.
The minimum safe token size is GSSKRB5TOKHDRLEN (16) plus ctx->krb5e->cksumlen (12-24, depending on the enctype). All callers accept shorter tokens from the wire:
- gssunwraprespinteg() enforces only an upper bound (offset + len <= rcvbuf->len) before allocating mic.data = kmalloc(len) and passing it to gssverifymic(). A malicious NFS server can therefore supply a short checksum opaque, producing a small slab allocation that the Kerberos MIC verifier reads past.
- gssvalidate() enforces only len <= RPCMAXAUTHSIZE (400) before passing the wire-supplied length to gssvalidateseqnomic(), which constructs a mic xdrnetobj and calls gssverifymic().
- svcauthgssverifyheader() enforces only checksum.len >= XDRUNIT (4 bytes) before dispatching to gssverifymic().
- svcauthgssunwrapinteg() checks only that the checksum fits in gsd->gsdscratch.
Add a length guard at the top of gsskrb5verifymicv2(), before any ptr[] access or scatterlist construction. Well-formed MIC tokens from gsskrb5getmicv2() already have exactly GSSKRB5TOKHDRLEN + cksumlen bytes, so valid traffic is unaffected.
In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: wait for in-flight client TLS handshake callback
xstlshandshakesync() gives xstlshandshakedone() a reference to the lower transport before submitting the handshake request. On timeout or signal, the synchronous waiter drops that reference after calling tlshandshakecancel().
handshakereqcancel() returns false when handshakecomplete() has already marked the request complete. In that case the completion callback can still be running, so dropping the callback-owned reference in the waiter can free the lower transport before xstlshandshakedone() stores xprterr or drops its own reference.
If cancellation loses to completion, wait until xstlshandshakedone() signals handshakedone and let the callback release its reference. This mirrors the server-side handshake lifetime handling and keeps the timeout or signal return value unchanged.
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:
svcrdma: Reject inline replies that overflow the pull-up buffer
An RPC-over-RDMA client can request a reply, such as an NFS READ payload, without providing a Write list or a Reply chunk to carry it. When such a reply needs more scatter/gather entries than the device's Send Queue supports, svcrdmapullupneeded() selects pull-up and svcrdmapullupreplymsg() linearizes the whole reply into sctxt->scxprtbuf. That buffer is only scmaxreqsize bytes, while the reply on this path is bounded only by the client's request, so svcrdmaxblinearize() copies past the end of the buffer and corrupts adjacent slab memory. The oversized length is then stored in scsges[0].length and posted, so the device also reads beyond the mapped region.
The SGE-exhaustion branch is the only pull-up path that can exceed the buffer: the threshold branch pulls up only replies smaller than RPCRDMAPULLUPTHRESH, and replies that fit the device's SGE budget are sent directly without linearization. Make svcrdmapullupneeded() report -E2BIG when the reply it would pull up cannot fit scmaxreqsize, and fail the request with ERRCHUNK as RFC 8166 Section 4.5.3 directs rather than dropping the connection.
The helper no longer answers a simple yes/no question: it now reports pull-up, no pull-up, or -E2BIG for a reply too large to linearize. Rename svcrdmapullupneeded() to svcrdmacheckpullup() so its name no longer implies a boolean predicate.
In the Linux kernel, the following vulnerability has been resolved:
lockd: pin next file across nlminspectfile lock-drop
nlmtraversefiles() pins the current file with fcount++ across a mutexunlock for nlminspectfile(), but nothing pins the saved next pointer. A concurrent nlmreleasefile() can kfree the next file during the unlock window, and the iterator dereferences freed memory on the next loop step.
Pin both current and next before the lock-drop. Advance by swapping the pinned cursors at the end of each iteration so next is always held alive across the unlock.
Always call nlmfilerelease() after dropping the iteration pin, regardless of whether the file matched the predicate. Use nlmfileinuse(), which does a live walk of the inode lock list, rather than the cached flocks field, so skipped files that never ran nlminspectfile() are evaluated correctly.
Because every file in a hash bucket is now pinned and released, files skipped by the isfailoverfile predicate that have no locks, blocks, shares, or external references are deleted during traversal. The old code never evaluated skipped files for cleanup. The new behavior is intentional: such files are stale and should not persist in the table.