In the Linux kernel, the following vulnerability has been resolved:
net/handshake: Take a long-lived file reference at submit
handshakenlacceptdoit() needs the file pointer backing req->hrsk->sksocket to survive the window between handshakereqnext() and the subsequent FDPREPARE() and getfile(). The submit-side sockhold() does not provide that. skrefcnt keeps struct sock alive, but struct socket is owned by sock->file: when the consumer fputs the last file reference, sockrelease() tears the socket down regardless of any sockhold.
Add an hrfile pointer to struct handshakereq and acquire an explicit reference on sock->file during handshakereqsubmit(). handshakecomplete() and handshakereqcancel() release the reference on the completion-bit-winning path.
The submit error path must also release the file reference, but after rhashtable insertion a concurrent handshakereqcancel() can discover the request and race the error path. Gate the error-path cleanup -- skdestruct restoration, fput, and request destruction -- with testandsetbit(HANDSHAKEFREQCOMPLETED), the same serialization handshakecomplete() and handshakereqcancel() already use. When cancel has already claimed ownership, the submit error path returns without touching the request; socket teardown handles final destruction.
The accept-side dereferences are not yet retargeted; that change comes in the next patch.
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
scsi: target: iscsi: Bound iscsiencodetextoutput() appends to rspbuf
iscsiencodetextoutput() concatenates "key=value\0" records into login->rspbuf, an 8192-byte kzalloc(MAXKEYVALUEPAIRS) buffer allocated in iscsitallocloginsetupbuffer(). The three sprintf() call sites in this function (lines 1398, 1411, 1424 in v7.1-rc2) never check the remaining buffer capacity:
length += sprintf(outputbuf, "%s=%s", er->key, er->value); length += 1; outputbuf = textbuf + length;
The 8192-byte ceiling at iscsitargetcheckloginrequest() bounds the input Login PDU payload, but a single PDU can carry up to 2048 minimal four-byte "a=b\0" pairs, each unknown key expanding to a 16-byte "a=NotUnderstood\0" output record via iscsiaddnotunderstoodresponse(). 2048 16 = 32 KiB of output into an 8 KiB buffer, producing a ~24 KiB heap overrun in the kmalloc-8k slab.
The fix introduces a static iscsiencodetextrecord() helper that uses snprintf() with a per-call bounds check against the remaining buffer, and threads a u32 textbufsize parameter through iscsiencodetextoutput(). Both call sites in iscsitargethandlecsgzero() (PHASESECURITY) and iscsitargethandlecsgone() (PHASEOPERATIONAL) pass MAXKEYVALUEPAIRS. On overflow the encoder logs the condition, calls iscsireleaseextraresponses() to drop queued records, and returns -1; both caller sites now emit ISCSISTATUSCLSINITIATORERR / ISCSILOGINSTATUSINITERR via iscsittxloginrsp() before returning, so the initiator sees an explicit failed-login response rather than a silent connection drop. (Prior to this patch only the PHASEOPERATIONAL caller did that; the PHASESECURITY caller is converted to the same shape.)
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
net/handshake: hand off the pinned file reference to acceptdoit
handshakereqnext() removes the request from the per-net pending list and drops hnlock before handshakenlacceptdoit() reads req->hrsk->sksocket and dereferences sock->file (once in FDPREPARE() and again in getfile()). In that window a consumer running tlshandshakecancel() followed by sockfdput() (svcsockfree) or fputsync() (xsresettransport) releases sock->file. sockrelease() then runs sockorphan(), zeroing sksocket, and frees the struct socket. The accept-side code either reads NULL through sksocket or chases freed memory.
The submit-side sockhold() does not prevent this. skrefcnt protects struct sock, but struct socket and sock->file are independently refcounted via the file descriptor the consumer owns. Pinning sk leaves sock and sock->file unprotected.
Retarget the accept-side dereferences at req->hrfile, which was pinned at submit time, instead of req->hrsk->sksocket->file. Pinning on its own is not sufficient: a consumer that cancels between handshakereqnext() returning and acceptdoit reaching FDPREPARE() takes the !removepending() branch in handshakereqcancel() and drops hrfile before the accept side takes its own reference. Hand off an additional file reference inside handshakereqnext(), under hnlock, so the accept side operates on a reference that no concurrent handshakereqcancel() can revoke. FDPREPARE() consumes that handed-off reference, either by transferring it to the new fd in fdpublish() or by dropping it in the cleanup destructor on error; the explicit getfile() that previously balanced FDPREPARE() is therefore redundant and goes away.
Update handshakereqcanceltest2 and test3 to simulate the FDPREPARE() consumption with an fput() so the kunit file-count assertions stay balanced.
In the Linux kernel, the following vulnerability has been resolved:
net/handshake: Drain pending requests at net namespace exit
The arguments to listspliceinit() in handshakenetexit() are reversed. The call moves the local empty "requests" list onto hn->hnrequests, leaving the local list empty, so the subsequent drain loop runs zero iterations. Pending handshake requests that had not yet been accepted are not torn down when the net namespace is destroyed; each one keeps a reference on a socket file and on the handshakereq allocation.
Pass the source and destination in the documented order (listspliceinit(list, head) moves list onto head) so the pending list is transferred to the local scratch list and drained through handshakecomplete().
Fixing the splice direction exposes a list-corruption race. After the splice each req->hrlist still has non-empty link pointers, threading the stack-local scratch list rather than hnrequests. A concurrent handshakereqcancel() -- for example, from sunrpc's TLS timeout on a kernel socket whose netns reference was not taken -- finds the request through the rhashtable, calls removepending(), and sees !listempty(&req->hrlist). removependinglocked() then listdelinit()s an entry off the scratch list while the drain iterates, corrupting it. The same call arriving after the drain loop has run listdel() on an entry hits LISTPOISON instead.
Have removepending() check HANDSHAKEFNETDRAINING under hnlock and report not-found when drain is in progress. The drain has already taken ownership; handshakecomplete()'s existing testandset on HANDSHAKEFREQCOMPLETED still arbitrates between drain and cancel for who calls the consumer's hpdone. Use listdelinit() rather than listdel() in the drain so req->hrlist does not carry LISTPOISON after drain releases the entry.
The DRAINING guard in removepending() makes cancel return false, but cancel still falls through to testandsetbit on HANDSHAKEFREQCOMPLETED and drops the request's hrfile reference. Without another pin, if that is the last reference, skdestruct frees the request while it is still linked on the drain loop's local list. Pin each request's hrfile under hnlock before releasing the list, and drop that drain pin after the loop finishes with the request.
In the Linux kernel, the following vulnerability has been resolved:
KVM: SEV: Ignore Port I/O requests of length '0'
Explicitly ignore Port I/O requests of length '0' (or count '0'), so that setting up the software scratch area (and other code) doesn't have to worry about underflowing the length, and to allow for WARNing on trying to configure the scratch area with len==0.
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
scsi: target: iscsi: Validate CHAPR length before base64 decode
chapservercomputehash() allocates clientdigest as kzalloc(chap->digestsize) and then, for BASE64-encoded responses, passes chapr directly to chapbase64decode() without checking whether the input length could produce more than digestsize bytes of output.
chapbase64decode() writes to the destination unconditionally as long as there is input to consume. With MAXRESPONSELENGTH set to 128 and the "0b" prefix stripped by extractparam(), up to 127 base64 characters can reach the decoder. 127 characters decode to 95 bytes. For SHA-256 (digestsize=32) this overflows clientdigest by 63 bytes; for MD5 (digestsize=16) the overflow is 79 bytes.
The length check at line 344 fires after the write has already happened.
The HEX branch in the same switch statement already validates the length up front. Apply the same approach to the BASE64 branch: strip trailing base64 padding characters, then reject any input whose data length exceeds DIVROUNDUP(digestsize 4, 3) before calling the decoder.
Stripping trailing '=' before the comparison handles both padded and unpadded encodings. chapbase64decode() already returns early on '=', so the full original string is still passed to the decoder unchanged.
The mutual CHAP path decodes CHAPC into initiatorchgbinhex, which is kzalloc(CHAPCHALLENGESTRLEN). extractparam() caps initiatorchg at CHAPCHALLENGESTRLEN characters, so at most CHAPCHALLENGESTRLEN-1 base64 characters reach the decoder. The maximum decoded size, DIVROUNDUP((CHAPCHALLENGESTRLEN-1) 3, 4), is less than CHAPCHALLENGESTRLEN, so no overflow is possible there. A comment is added at the call site to document this.
In the Linux kernel, the following vulnerability has been resolved:
KVM: SEV: Require in-GHCB scratch area if GHCB v2+ is in use
As per the GHCB spec, when using GHCB v2+ require the software scratch area to reside in the GHCB's shared buffer. Note, things like Page State Change (PSC) requests rely on this behavior, as the guest can't provide a length when making the request, i.e. the size of the guest payload is bounded by the size of the shared buffer.
Failure to force usage of the GHCB, and a slew of other flaws, lets a malicious SNP guest corrupt host kernel heap memory, and leak host heap layout information.
setupvmgexitscratch() allocates a buffer via kvzalloc(exitinfo2), where exitinfo2 is guest-controlled. With exitinfo2=24, this yields a 24-byte allocation in kmalloc-cg-32 (32-byte slab objects). The buffer holds an 8-byte pschdr followed by 8-byte pscentry structs, so only entries[0] and entries[1] are in-bounds.
snpbeginpsc() validates endentry against VMGEXITPSCMAXCOUNT (253) but NOT against the actual buffer size:
idxend = hdr->endentry;
if (idxend >= VMGEXITPSCMAXCOUNT) { // checks 253, not buffer snpcompletepsc(svm, ...); return 1; }
for (idx = idxstart; idx <= idxend; idx++) { entrystart = entries[idx]; // OOB when idx >= 2
The guest sets endentry=10+, causing the host to iterate entries[2+] which are OOB into adjacent slab objects. For each OOB entry:
- The host reads 8 bytes (OOB READ / info leak oracle) - If the data passes PSC validation, snpcompleteonepsc() writes curpage = 1 or 512 into the entry (OOB WRITE, sev.c:3806) - If validation fails, the error response reveals whether adjacent memory is zero vs non-zero (information disclosure to guest)
The guest controls allocation size (exitinfo2), entry range (curentry/endentry), and can fire unlimited VMGEXITs to repeatedly hit different slab positions.
By exploiting the variety of bugs, a malicious SEV-SNP guest can: - OOB read adjacent kmalloc-cg-32 objects (heap layout disclosure) - OOB write curpage bits into adjacent objects (heap corruption) - Trigger use-after-free conditions across VMGEXITs
E.g. with KASAN enabled, a single insmod of the PoC guest module produces 73 KASAN reports:
BUG: KASAN: slab-out-of-bounds in snpbeginpsc+0x126/0x890 Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199
BUG: KASAN: slab-out-of-bounds in snpbeginpsc+0x468/0x890 Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199
The buggy address belongs to the object at ffff888XXXXXXXXX which belongs to the cache kmalloc-cg-32 of size 32 The buggy address is located N bytes to the right of allocated 32-byte region [ffff888XXXXXXXXX, ffff888XXXXXXXXX)
Breakdown: 62 slab-out-of-bounds (reads + writes past allocation) 7 slab-use-after-free 4 use-after-free
All credit to Stan for the wonderful description and reproducer!
[sean: write changelog]
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved: