CVE-2024-26582: Verified Repro With Script Download
CVE-2024-26582: Linux kernel kTLS Use-After-Free
CVE-2024-26582 is verified against torvalds/linux · github. Affected versions: Linux 6.2.0 through 6.6.18; also 6.1.x before 6.1.82, 6.7.x before 6.7.7. Vulnerability class: Use-After-Free. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00265.
What Is CVE-2024-26582?
CVE-2024-26582 is a high-severity use-after-free vulnerability in the Linux kernel's in-kernel TLS (kTLS) software receive path in net/tls/tls_sw.c. Pruva reproduced it (reproduction REPRO-2026-00265).
CVE-2024-26582 Severity & CVSS Score
CVE-2024-26582 is rated high severity, with a CVSS base score of 7.8 out of 10.
High — serious impact or readily exploitable. Prioritize remediation.
Affected torvalds/linux Versions
torvalds/linux · github versions Linux 6.2.0 through 6.6.18; also 6.1.x before 6.1.82, 6.7.x before 6.7.7 are affected.
How to Reproduce CVE-2024-26582
pruva-verify REPRO-2026-00265 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00265/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2024-26582
- reached the target end-to-end
- crash observed
- on the real production code path
- high confidence
kTLS session with async decryption and partial read pattern
- tls_sw_recvmsg
- tls_decrypt_sg (clear_skb path, darg.zc=false)
- tls_do_decryption (async via cryptd)
- tls_decrypt_done (frees clear_skb pages via put_page, bug: sgout!=sgin check)
- process_rx_list (accesses freed pages, KASAN UAF)
Bypass of the CVE-2024-26582 fix 32b55c5 (free_sgout) on the FIXED Linux v6.6.18 kernel. The async kTLS decrypt use-after-free class is only partially fixed: 32b55c5 corrects the page-free heuristic in tls_decrypt_done() for the normal async (-EINPROGRESS) + partial-read path, but does NOT cover the crypto-backlog (-E…
How the agent worked
Root Cause and Exploit Chain for CVE-2024-26582
CVE-2024-26582 is a use-after-free vulnerability in the Linux kernel's in-kernel TLS (kTLS) software receive path (net/tls/tls_sw.c). When a kTLS session uses asynchronous decryption and the receiving application performs a partial read (reading fewer bytes than the TLS record size), the tls_decrypt_done() completion callback incorrectly frees pages belonging to the clear_skb buffer. These freed pages are subsequently accessed by process_rx_list() when the application reads the remaining data, triggering a use-after-free. The fix (commit 32b55c5ff9103b8508c1e04bfa5a08c64e7a925f) adds a free_sgout flag to track whether tls_decrypt_sg() actually allocated the destination pages, and only frees them when they were newly allocated.
- Package/component affected: Linux kernel kTLS software implementation (
net/tls/tls_sw.c) - Affected versions: Linux 6.2.0 through 6.6.18 (fixed in 6.6.19+, 6.7.7+, 6.1.82+, 6.8-rc3)
- Risk level: High — kernel-space use-after-free can lead to memory corruption, information leaks, or potentially privilege escalation
- Consequences: An attacker who can establish a kTLS session and control the read pattern (partial reads) can trigger premature page freeing, leading to use-after-free when the freed pages are accessed. With page poisoning or KASAN, this manifests as data corruption or sanitizer reports. Without sanitizers, this could lead to silent memory corruption or exploitation.
Impact Parity
- Disclosed/claimed maximum impact: Memory corruption (use-after-free in kernel space)
- Reproduced impact from this run: Memory corruption confirmed via KASAN use-after-free report and data corruption (page poisoning). The KASAN report shows a read of freed memory in
copyout()called fromprocess_rx_list()→tls_sw_recvmsg(). Data mismatch detected when freed pages are poisoned. - Parity:
full— the claimed memory corruption impact is fully reproduced with KASAN detection and data corruption evidence. - Not demonstrated: Code execution / privilege escalation (the UAF is demonstrated as memory corruption, not exploit chain to code execution).
Root Cause
The vulnerability is in tls_decrypt_done() in net/tls/tls_sw.c. This function is the async completion callback for AEAD decryption in the kTLS software receive path.
The bug: tls_decrypt_done() uses the check if (sgout != sgin) to determine whether to free destination pages. This check was intended to distinguish in-place decryption (where destination and source scatterlists are the same, so no pages should be freed) from non-in-place decryption (where destination pages were allocated and should be freed). However, the check is incorrect because sgout != sgin is also true when sgout points to pages from clear_skb (allocated by tls_alloc_clrtxt_skb()), not just when pages were newly allocated by tls_decrypt_sg().
The flow:
tls_sw_recvmsg()is called with a partial read (len < record_size)darg.zc = falsebecauseto_decrypt > len(record doesn't fit in user buffer)tls_decrypt_sg()takes theclear_skbpath: allocatesclear_skbwith pages, setssgoutto point toclear_skbpagestls_do_decryption()starts async decryption (returns-EINPROGRESSviacryptdworkqueue)- The
clear_skbis placed onctx->rx_listfor later processing tls_decrypt_async_wait()waits for async completiontls_decrypt_done()is called from the workqueue → seessgout != sgin→ callsput_page()onclear_skbpages → pages freed whileclear_skbstill references them- On the next
recv()call,process_rx_list()reads from theclear_skb→ accesses freed pages → use-after-free
The fix (commit 32b55c5ff9103b8508c1e04bfa5a08c64e7a925f):
- Adds
bool free_sgouttostruct tls_decrypt_ctx - Sets
dctx->free_sgout = !!pagesintls_decrypt_sg()(only true when pages were actually allocated) - Changes the check in
tls_decrypt_done()fromif (sgout != sgin)toif (dctx->free_sgout)
Reproduction Steps
- Reference:
bundle/repro/reproduction_steps.sh - What the script does:
- Downloads Linux kernel v6.6.18 source
- Applies GCC 15 compatibility patches (adds
-std=gnu11to REALMODE_CFLAGS, boot/compressed, and EFI libstub Makefiles) - Patches
crypto/simd.cto force AEAD decrypt operations through thecryptdworkqueue (simulating async crypto behavior that occurs with hardware crypto accelerators or in contexts where SIMD is unavailable) - Creates two kernel builds: vulnerable (fix reverted) and fixed (fix present)
- Both builds include
CONFIG_TLS=y,CONFIG_KASAN=y,CONFIG_CRYPTO_AES_NI_INTEL=y,CONFIG_PAGE_POISONING=y - Creates a minimal initramfs with a static kTLS test program that:
- Establishes a loopback TCP connection
- Configures kTLS with AES-128-GCM (TLS 1.2)
- Sends 4096-byte records and performs partial reads (100 bytes then 3996 bytes)
- Checks for data corruption
- Boots both kernels in QEMU (TCG mode,
-cpu maxfor AES-NI) withpage_poison=1 - Captures serial console output for KASAN reports and corruption detection
- Expected evidence:
- Vulnerable kernel:
BUG: KASAN: use-after-free in copyout+Data MISMATCH - corruption detected!+BUG: Bad page state - Fixed kernel: No KASAN reports, no corruption, test completes normally
- Vulnerable kernel:
Evidence
- Vulnerable kernel log:
bundle/logs/qemu-vuln-ktls.log - Fixed kernel log:
bundle/logs/qemu-fixed-ktls.log - Reproduction script log:
bundle/logs/reproduction_steps.log
Key excerpts from vulnerable kernel:
[ 4.956611] BUG: KASAN: use-after-free in copyout+0x2d/0x50
[ 4.957007] Read of size 100 at addr ff1100000186000d by task init/58
[ 4.957072] Call Trace:
[ 4.957072] copyout+0x2d/0x50
[ 4.957072] _copy_to_iter+0x15b/0x1070
[ 4.957072] __skb_datagram_iter+0x3c7/0x890
[ 4.957072] skb_copy_datagram_iter+0x2f/0x120
[ 4.957072] process_rx_list+0x2b5/0x5f0
[ 4.957072] tls_sw_recvmsg+0x1081/0x17b0
[kTLS] Data MISMATCH - corruption detected!
[ 4.969549] BUG: Bad page state in process init pfn:02efc
Key excerpts from fixed kernel (negative control):
[kTLS] Data matches (no corruption observed yet)
[kTLS] Completed 20 iterations
[kTLS] Test complete. If KASAN is enabled, check dmesg for UAF report.
(No KASAN reports, no corruption, no bad page state)
Environment details:
- Kernel: Linux 6.6.18 (v6.6.18 with fix reverted for vulnerable, fix present for fixed)
- Compiler: GCC 15.2.0 with
-std=gnu11compatibility patches - QEMU: QEMU 10.2.1, TCG mode,
-cpu max(AES-NI emulation), 2 vCPUs, 1024MB RAM - KASAN: Generic KASAN with inline instrumentation
- Page poisoning: enabled (
page_poison=1) - Crypto: AES-NI GCM with forced async decrypt via
cryptdworkqueue - Test: kTLS AES-128-GCM, TLS 1.2, 4096-byte records, 100-byte partial reads
Recommendations / Next Steps
- Upgrade: Apply the fix (commit
32b55c5ff9103b8508c1e04bfa5a08c64e7a925f) or upgrade to Linux 6.6.19+, 6.7.7+, 6.1.82+, or 6.8-rc3+. - Testing: Enable
CONFIG_KASANandCONFIG_PAGE_POISONINGin kernel testing configurations to detect similar use-after-free bugs in the kTLS receive path. - Code review: Audit other completion callbacks in the kTLS code that use pointer comparison (
sgout != sgin) instead of explicit allocation tracking. - Mitigation: If kTLS is used in production with hardware crypto accelerators (which naturally produce async completions), ensure the kernel is patched. The bug only manifests with async decryption, which is the normal case with hardware crypto.
Additional Notes
- Idempotency: The reproduction script is idempotent — it checks for existing build artifacts and reuses them. Running it multiple times produces the same result.
- Async path simulation: The
crypto/simd.cpatch forces AEAD decrypt operations through thecryptdworkqueue, simulating the async behavior that occurs naturally with hardware crypto accelerators or in contexts where SIMD/FPU is unavailable (e.g., softirq context). This does not modify the vulnerable code path intls_sw.c; it only ensures the async completion path is exercised. In production, this async path is triggered by hardware crypto offload or when the crypto operation is deferred. - Page poisoning:
CONFIG_PAGE_POISONINGwithpage_poison=1fills freed pages with a poison pattern (0xAA), making the use-after-free visible through data corruption even without KASAN. This provides an additional layer of detection beyond KASAN's shadow memory tracking. - GCC 15 compatibility: The v6.6.18 kernel requires minor Makefile patches to build with GCC 15, which defaults to C23 where
true/falseare keywords. The patches add-std=gnu11to REALMODE_CFLAGS, boot/compressed, and EFI libstub Makefiles, matching the fix applied in newer kernel versions.
Variant Analysis & Alternative Triggers for CVE-2024-26582
A confirmed bypass of the CVE-2024-26582 fix commit 32b55c5ff9103b8508c1e04bfa5a08c64e7a925f
(net: tls: fix use-after-free with partial reads and async decrypt, the free_sgout fix) was
found and reproduced on the fixed Linux v6.6.18 kernel. The free_sgout fix only corrects the
page-freeing heuristic in the async completion callback tls_decrypt_done() (replacing the buggy
sgout != sgin test with dctx->free_sgout = !!pages). It does not cover the crypto-backlog
error path: when an async kTLS decrypt request is enqueued to the crypto backlog
(crypto_aead_decrypt() returns -EBUSY) and a pending async decrypt fails with -EBADMSG
(e.g. an attacker-controlled malformed/mismatched-key TLS record), tls_do_decryption() waits for
the backlog to drain (tls_decrypt_async_wait()); during that wait tls_decrypt_done() already
runs and kfree()s the aead_req/tls_decrypt_ctx block (and frees the destination pages when
free_sgout). tls_do_decryption() then returns -EBADMSG, tls_decrypt_sg() jumps to
exit_free_pages/exit_free and frees the same memory again → slab-use-after-free /
double-free, confirmed by KASAN. This second UAF is fixed upstream by commit
13114dc5543069f7b97991e3b79937b6da05f5b0 (tls: fix use-after-free on failed backlog decryption,
adds the async_done flag), which is absent in v6.6.18. We reproduced the UAF on v6.6.18
(32b55c5 present, 13114dc absent) and verified that adapting 13114dc closes it.
Fix Coverage / Assumptions
The original fix 32b55c5 relies on this invariant:
The decision of whether to free the AEAD destination pages in the async completion callback
tls_decrypt_done()can be made correctly at submit time by recording whethertls_decrypt_sg()actually allocated those pages (dctx->free_sgout = !!pages), instead of the fragilesgout != sginpointer comparison.
Code paths 32b55c5 explicitly covers:
tls_decrypt_done()(the async AEAD completion callback) — page-free condition changed toif (dctx->free_sgout).- All three
sgoutsetup sub-cases intls_decrypt_sg(): clear_skb (non-ZC,pages=0),out_iov(ZC,pages>0), andout_sg(ZC,pages=0).
What 32b55c5 does NOT cover:
- The
-EBUSYbacklog error path intls_do_decryption(). Whencrypto_aead_decrypt()returns-EBUSY,tls_do_decryption()callstls_decrypt_async_wait()and may return an error (-EBADMSG) after the async callbacktls_decrypt_done()has already run and released the memory.tls_decrypt_sg()'s error cleanup (exit_free_pages→put_pageloop, thenexit_free→kfree(mem)) then releases the same memory a second time. 32b55c5only governs whethertls_decrypt_donefrees pages; it has no mechanism to telltls_decrypt_sg()'s error path that the callback already ran. That mechanism (async_done) is exactly what13114dcadds.
The reproduction's own instrumentation already forces the async path (a crypto/simd.c patch that
defers all AEAD decrypts to the cryptd workqueue, simulating an async/hardware crypto accelerator),
and v6.6.18 already contains the -EBUSY backlog handling from 859054147318 ("net: tls: handle
backlogging of crypto requests"). Only the 13114dc completion of that fix is missing.
Variant / Alternate Trigger
Entry point: recv() / recvmsg() on a kTLS (TLS 1.2) software RX socket — the same syscall
surface as the original CVE, but driven through the backlog error sub-path instead of the
partial-read process_rx_list() path.
Trigger conditions (all attacker-relevant):
- A kTLS TLS 1.2 session with an async-capable AEAD (
ctx->async_capable = true; any cipher whose tfm isCRYPTO_ALG_ASYNC, e.g.gcm(aes)via the simd/cryptd wrapper, or a hardware crypto accelerator). TLS 1.3 disables async, so TLS 1.2 is required — same as the original CVE. - A decrypt request that is backlogged (
crypto_aead_decrypt()→-EBUSY). This is the natural behavior under crypto backlog congestion (theCRYPTO_TFM_REQ_MAY_BACKLOGflag kTLS sets on every AEAD request). With a busy/congested async crypto queue (hardware accelerator or cryptd under load),-EBUSYis returned instead of-EINPROGRESS. - A pending async decrypt that fails with
-EBADMSG. An attacker who controls the TLS record bytes on the wire (the trust boundary the original CVE crosses — network-received ciphertext) can send a malformed/corrupt record (bad AEAD tag) so decryption fails. In the reproducer this is simulated with mismatched TX/RX keys (every record fails-EBADMSG), which exercises the identicaltls_decrypt_done(... err=-EBADMSG)code path.
Exact code path (files / functions), all in net/tls/tls_sw.c:
__x64_sys_recvfrom -> ... -> tls_sw_recvmsg()
-> tls_rx_one_record() -> tls_decrypt_sw() -> tls_decrypt_sg()
-> tls_do_decryption()
crypto_aead_decrypt() == -EBUSY [backlog congestion]
-> tls_decrypt_async_wait() [waits; tls_decrypt_done() runs on cryptd
workqueue, frees pages if free_sgout AND
kfree(aead_req)/dctx block]
returns -EBADMSG [a pending decrypt failed]
err = -EBADMSG -> goto exit_free_pages:
for (; pages>0; ...) put_page(sg_page(&sgout[pages])) [DOUBLE-FREE of ZC pages]
exit_free: kfree(mem) [DOUBLE-FREE / UAF of aead_req||dctx block]
KASAN attributes the freed object to tls_decrypt_done() running on the cryptd workqueue
(cryptd_aead_crypt -> cryptd_queue_worker -> process_one_work), and the buggy re-access to
tls_decrypt_sg() — exactly the 13114dc bug.
The reproduction additionally forces -EINPROGRESS -> -EBUSY for async decrypts
(bundle/vuln_variant/ebusy_force.patch) because the backlog-congestion condition is
non-deterministic in a single-CPU loopback QEMU. This is analogous to the reproduction's existing
crypto/simd.c patch that forces the cryptd async path; it does not alter the page-freeing
(free_sgout) logic — it only makes the backlog (-EBUSY) code path reachable on demand.
- Package / component affected: Linux kernel kTLS software RX,
net/tls/tls_sw.c(tls_do_decryption,tls_decrypt_done,tls_decrypt_sg). - Affected versions (as tested): Linux v6.6.18 — i.e. any branch that has
32b55c5(free_sgout) but not13114dc(async_done). Concretely v6.6.18 ships32b55c5and the backlog handling859054147318, but predates13114dc(committed 2024-02-29, after v6.6.18). - Risk level: High — kernel-space slab use-after-free / double-free in the kTLS receive path, triggerable by an attacker who can send malformed TLS records to a kTLS peer whose async crypto queue is congested. Same impact class as the parent CVE (memory corruption; potential info leak / privilege escalation).
Impact Parity
- Disclosed / claimed maximum impact (parent CVE-2024-26582): kernel-space use-after-free / memory corruption in the kTLS async decrypt receive path.
- Reproduced impact from this variant run: kernel-space slab-use-after-free confirmed by
KASAN (
BUG: KASAN: slab-use-after-free in tls_decrypt_sg+0x2037/0x29c0), where the freedaead_req/dctxblock (kmalloc-512) was freed bytls_decrypt_done()on the cryptd workqueue and re-accessed bytls_decrypt_sg()'s error path. This is a memory-corruption primitive of the same class as the parent CVE, on the fixed (v6.6.18 +32b55c5) kernel. - Parity:
full— same component, same async-decrypt UAF class, same trust boundary (network-controlled TLS records), reproduced on the patched code path. - Not demonstrated: no exploit chain to privilege escalation / code execution was built; the reproduction demonstrates the memory-corruption primitive (KASAN UAF) only, consistent with the parent CVE's reproduced scope.
Root Cause
tls_decrypt_sg() allocates a single block mem = kmalloc(aead_req || tls_decrypt_ctx) that owns
both the AEAD request and the destination scatterlist/free_sgout flag. In the async case the
completion callback tls_decrypt_done() is responsible for freeing the destination pages (when
free_sgout) and for kfree(aead_req) (the mem block). The error path of tls_decrypt_sg()
(exit_free_pages/exit_free) also frees those pages and kfree(mem).
For the normal async path (crypto_aead_decrypt() → -EINPROGRESS), tls_do_decryption() returns
0 and tls_decrypt_sg() returns without hitting its error cleanup, so only the callback frees —
no double-free. 32b55c5 makes the callback's page-free decision correct.
For the backlog path (-EBUSY), tls_do_decryption() synchronously waits for the backlog to
drain (tls_decrypt_async_wait()). By the time the wait returns, tls_decrypt_done() has already
executed for the backlogged request and freed its memory. If the wait also observed a failure
(ctx->async_wait.err == -EBADMSG), tls_do_decryption() returns -EBADMSG, and tls_decrypt_sg()
runs its error cleanup on the already-freed memory → double-free / UAF. 32b55c5 does not provide
any signal that the callback already ran, so it cannot prevent this.
The missing fix is upstream commit 13114dc5543069f7b97991e3b79937b6da05f5b0 ("tls: fix
use-after-free on failed backlog decryption"), Fixes: 859054147318. It adds bool async_done to
tls_decrypt_arg; on the -EBUSY path tls_do_decryption() sets async_done=true and returns the
wait result, and tls_decrypt_sg() then skips exit_free_pages/exit_free (goto exit_free_skb)
when async_done is set, avoiding the double-free. We verified this exact behavior by adapting
13114dc to v6.6.18: the UAF disappears.
Reproduction Steps
- See
bundle/vuln_variant/reproduction_steps.sh. - The script builds four v6.6.18 kernels side by side (all have the async-forcing
crypto/simd.cpatch from the parent reproduction):vuln+ebusy(32b55c5 reverted +ebusy_force.patch) — variant on the vulnerable tree,fixed(32b55c5 present, no backlog forcing) — baseline,fixed+ebusy(32b55c5 +ebusy_force.patch:-EINPROGRESS -> -EBUSYfor async decrypts) — bypass,fixed+ebusy+13114dc(also adapts the13114dcasync_donefix) — gap-closure. It builds a static init binary (backlog_variant_test.c) that sets up kTLS TLS 1.2 AES-128-GCM over loopback with mismatched TX/RX keys (so every record fails-EBADMSGduring async decrypt), sends 16 records, andrecv()s them with a large buffer (zero-copy full reads,darg.zc=true,pages>0,free_sgout=true). It runs each kernel in QEMU (KASAN + page poisoning) and countsBUG: KASANreports.
- Expected evidence:
vuln+ebusyandfixed+ebusyboth showBUG: KASAN: slab-use-after-free in tls_decrypt_sg;fixed(no backlog) shows none;fixed+ebusy+13114dcshows none. Exit 0 = bypass confirmed on the FIXED kernel. Thevuln+ebusyresult corroborates that the variant is present on the vulnerable tree too (both lack13114dc).
Evidence
bundle/logs/vuln_variant/qemu-vuln-ebusy-variant.log— variant on vulnerable tree (32b55c5 reverted + ebusy):BUG: KASAN: slab-use-after-free in tls_decrypt_sg(corroborates the variant is the same on the vulnerable tree, which also lacks13114dc).bundle/logs/vuln_variant/qemu-fixed-ebusy-variant.log— bypass: containsBUG: KASAN: slab-use-after-free in tls_decrypt_sg+0x2037/0x29c0(Read of size 8, 440 bytes into a freed kmalloc-512 region). Allocated by__kmallocintls_decrypt_sg; Freed by task 26 viatls_decrypt_done -> cryptd_aead_crypt -> cryptd_queue_worker(async workqueue). Program output:recv returned -1 (errno=74 Bad message).bundle/logs/vuln_variant/qemu-fixed-nobacklog-baseline.log— baseline: same test, no backlog forcing →EBADMSGreturned, no KASAN (proves32b55c5holds for the normal async path and the-EBUSYcondition is the trigger).bundle/logs/vuln_variant/qemu-fixed-ebusy-13114dc.log— gap-closure: same test with13114dcadapted →EBADMSGreturned, no KASAN (proves13114dccloses the bypass).bundle/logs/vuln_variant/kasan_report_excerpt.txt— extracted KASAN report.bundle/logs/vuln_variant/fixed_version.txt— tested source identity (v6.6.18 tarball;free_sgoutpresent,async_doneabsent).bundle/vuln_variant/ebusy_force.patch,bundle/vuln_variant/apply_fix13114dc.py,bundle/vuln_variant/backlog_variant_test.c— instrumentation / test program.
Recommendations / Next Steps
- Close the gap: backport / apply commit
13114dc5543069f7b97991e3b79937b6da05f5b0("tls: fix use-after-free on failed backlog decryption") to every branch that carries the CVE 2024-26582free_sgoutfix (32b55c5) but not13114dc(e.g. v6.6.18 / v6.6.19-only branches that took only the first patch). The32b55c5fix alone is incomplete for the async-decrypt UAF class. The fix must add anasync_done-style signal sotls_decrypt_sg()'s error path skipsexit_free_pages/exit_freewhen the async completion callback has already released the memory. - Rule-out matrix (other surfaces inspected, all covered/sync — not bypasses):
tls_sw_splice_read()(splice syscall): usesdarg.async = false(sync) → usescrypto_req_done, nevertls_decrypt_done→ not reachable. Not a variant.tls_sw_read_sock()(sendfile /tcp_read_sock): likewise sync. Not a variant.decrypt_skb()/out_sgpath (Case C, device fallback):darg = { .zc = true }withasync = false(sync) → nevertls_decrypt_done. Not a variant.- Other ciphers (CHACHA20-POLY1305, AES-256-GCM, AES-128-CCM): the bug is cipher-agnostic (all
flow through
tls_decrypt_sg/tls_do_decryption/tls_decrypt_done);32b55c5'sfree_sgoutand the missing13114dcasync_doneapply identically. (CHACHA20-POLY1305 exercises a different IV-prep branch attls_sw.c:1531but the same sink.) These are alternate triggers of the same sink, all covered by32b55c5+13114dc; not independent bypasses.
- Hardening: treat the two CVE-2024-26582 patches (
32b55c5and13114dc) as a single mandatory unit when backporting; add a regression test that exercises the async decrypt backlog + failure combination (the reproducer in this bundle is a starting point).
Additional Notes
- Idempotency:
bundle/vuln_variant/reproduction_steps.shwas run twice; both runs produced identical results (fixed(no ebusy) KASAN=0 | fixed+ebusy KASAN=1 | fixed+ebusy+13114dc KASAN=0) and exit 0. Kernel builds and the initramfs are cached and skipped on repeat runs; the shared kernel source tree is always restored to pristine (tls_sw.c.orig) after each variant build. - Trust boundary: the attacker controls the TLS record bytes received over the network
(malformed record →
-EBADMSG); the-EBUSYbacklog congestion is an environmental condition (busy async crypto), not attacker-controlled, but it is a normal operating condition for systems using async/hardware crypto accelerators. The reproducer forces-EBUSYdeterministically because loopback single-CPU QEMU cannot naturally congest the crypto backlog; this mirrors the parent reproduction'scrypto/simd.casync-forcing approach. - Instrumentation caveat:
ebusy_force.patchconverts-EINPROGRESS -> -EBUSYfor async decrypts to make the backlog path reachable on demand. It does not changefree_sgoutor any page-freeing logic; the double-free is the genuine v6.6.18 code path, not an artifact of the patch. The13114dc-adapted kernel shows no UAF under the same forcing, proving the gap is exactly the missingasync_donefix. - The v6.6.18 source is a kernel.org release tarball (no git metadata); source identity is recorded
in
bundle/vuln_variant/source_identity.jsonvia release-tag resolution.
CVE-2024-26582 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
cd /data/pruva/project-cache/6cba72b6-b104-4ebf-be7b-01f748e87ccf/linux-src && git log --oneline -3 2>/dev/null; echo "---HEAD---"; git rev-parse HEAD 2>/dev/null; echo "---VERSION---"; head -5 Makefile---HEAD--- ---VERSION--- # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 18 SUBLEVEL = 18 EXTRAVERSION =
cd /data/pruva/project-cache/6cba72b6-b104-4ebf-be7b-01f748e87ccf/linux-src-7rc2 && git log --oneline -3 2>/dev/null; echo "---HEAD---"; git rev-parse HEAD 2>/dev/null; echo "---VERSION---"; head -5 Makefile---HEAD--- ---VERSION--- # SPDX-License-Identifier: GPL-2.0 VERSION = 7 PATCHLEVEL = 0 SUBLEVEL = 0 EXTRAVERSION = -rc2
Artifacts and Evidence for CVE-2024-26582
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2024-26582
FAQ: CVE-2024-26582
How does the CVE-2024-26582 use-after-free get triggered?
tls_decrypt_done() frees the clear_skb pages prematurely, and the subsequent read via process_rx_list() dereferences the already-freed pages, leading to memory corruption, information leaks, or potential further exploitation.Which Linux kernel versions are affected by CVE-2024-26582, and where is it fixed?
32b55c5ff9103b8508c1e04bfa5a08c64e7a925f, which adds a free_sgout flag so tls_decrypt_sg()-allocated pages are only freed if they were newly allocated.How severe is CVE-2024-26582?
How can I reproduce CVE-2024-26582?
References for CVE-2024-26582
Authoritative sources for CVE-2024-26582 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.