In the Linux kernel, the following vulnerability has been resolved:
ipvs: clear IPv4 options after rebasing tunnel ICMP errors
ipvsinicmp() rebases an skb from the outer ICMP packet to the quoted original request before passing it to icmpsend(). However, IPCB(skb)->opt still describes the outer IPv4 header.
A timestamp option in the outer header can therefore leave an offset that points into the quoted transport header after the rebase. ipoptionsecho() treats a byte at that stale location as the option length and copies it into the fixed-size option storage on the icmpsend() stack, causing a stack out-of-bounds write.
Clear the stale option metadata after resetting the network header. Keep the remaining control block fields, including the ingress interface used by the ICMP response path.
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:
nfsd: fix XDR length calculation in nfsd4ffencodelayoutget
The XDR buffer size calculation in nfsd4ffencodelayoutget() has multiple errors that can result in either an out-of-bounds write or leaking uninitialized kernel memory to the client:
- fhlen doesn't account for XDR padding on the file handle data - uid and gid lengths use "8 + len" but xdrencodeopaque() actually writes "4 + xdralignsize(len)" bytes - dslen omits the flags and statscollecthint fields (8 bytes), while len's header constant overestimates by 8 bytes -- these partially cancel but leave a net mismatch
The worst case occurs with short strings (e.g. uid=0, gid=0 with an odd-sized file handle), where the function writes up to 5 bytes past the reserved XDR buffer. Conversely, when string lengths happen to be 4-byte aligned, the reservation is too large and stale buffer content is sent to the client.
Fix this by breaking out every encoded field explicitly in the dslen calculation, using xdralignsize() for all variable-length opaque fields, and correcting the header constants.
In the Linux kernel, the following vulnerability has been resolved:
ipv4: free inetopt and ireqopt after an RCU grace period
tcpv4synrecvsock() transfers ownership of ireq->ireqopt to the child socket (newinet->inetopt) without copying it.
Another cpu can concurrently process a retransmitted SYN for the same request socket, and send a SYNACK from tcpcheckreq(). tcpv4sendsynack() and inetcskroutereq() read ireq->ireqopt under rcureadlock() only, and ipbuildandsendpkt() and ipoptionsbuild() then read opt->optlen twice.
Note that the SYNACK timer itself is not an issue: it holds a reference on its request socket, and inetcskreqskqueuedrop() calls timerdeletesync() before the child can be freed.
Since commit 079096f103fa ("tcp/dccp: install synrecv requests into ehash table"), request sockets are processed without holding the listener lock, so nothing prevents the child socket from being freed while the SYNACK is still being built. TCP child sockets do not have SOCKRCUFREE, and inetsockdestruct() frees inetopt with a plain kfree(), leading to a use-after-free in ipoptionsbuild().
A similar issue exists with request socket migration (net.ipv4.tcpmigratereq=1, or a BPFSKREUSEPORTSELECTORMIGRATE program). reqsktimerhandler() clones the request socket with inetreqskclone(), so that the old request socket and its clone share the same ireqopt, then reqskmigratereset() clears the pointer in the old one. Another cpu holding a reference on the old request socket can still be using these options (sending a SYNACK, or creating a child in tcpv4synrecvsock()) when the clone is freed, and tcpv4reqskdestructor() also uses a plain kfree().
Readers already use RCU, and other paths replacing inetopt (doipsetsockopt(), cipsov4socksetattr()...) already use kfreercu(). Use kfreercu() in inetsockdestruct() and tcpv4reqskdestructor() as well.
IPv6 is not affected by the first issue, because tcpv6synrecvsock() duplicates the options. tcpv6reqskdestructor() has the same migration issue with ipv6opt, which is only set by CALIPSO. This will be addressed in a separate patch.
In the Linux kernel, the following vulnerability has been resolved:
sctp: prevent peer transport count overflow
sctpassocaddpeer() increments the association's 16-bit transportcount for every new unique peer. Adding the 65,536th transport wraps the count to zero.
SCTP sockdiag uses transportcount to reserve the INETDIAGPEERS payload, then copies one sockaddrstorage for every entry in transportaddrlist. After the wrap, a diagnostic dump reserves an empty payload and writes 8 MiB of peer addresses past the skb tail.
Reject a new unique peer when transportcount has reached U16MAX. Perform the check after the existing-peer lookup so a duplicate address continues to return its existing transport at the limit.
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix overrun check in netfsextractuseriter()
Fix netfsextractuseriter() so that if ioviterextractpages() overfills pages[], then those pages don't get included in the iterator constructed at the end of the function. If there was an overfill, memory corruption has already happened.