{ "dataType": "CVE_RECORD", "dataVersion": "5.2", "cveMetadata": { "cveId": "CVE-2025-40046", "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "state": "PUBLISHED", "assignerShortName": "Linux", "dateReserved": "2025-04-16T07:20:57.154Z", "datePublished": "2025-10-28T11:48:24.022Z", "dateUpdated": "2026-08-05T12:07:19.429Z" }, "containers": { "cna": { "providerMetadata": { "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux", "dateUpdated": "2026-08-05T12:07:19.429Z" }, "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nio_uring/zcrx: fix overshooting recv limit\n\nIt's reported that sometimes a zcrx request can receive more than was\nrequested. It's caused by io_zcrx_recv_skb() adjusting desc->count for\nall received buffers including frag lists, but then doing recursive\ncalls to process frag list skbs, which leads to desc->count double\naccounting and underflow." } ], "metrics": [ { "cvssV3_1": { "version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H", "baseScore": 8.6, "baseSeverity": "HIGH" }, "scenarios": [ { "lang": "en", "value": "AV:N - The vulnerable function is a TCP read actor operating on skbs received from the remote peer, and the triggering condition — a `frag_list`-chained skb built by `skb_gro_receive()` when frags exceed `MAX_SKB_FRAGS` — is determined entirely by the remote sender's traffic pattern, not by any local action. A client connected to a zcrx-enabled network server triggers it over the wire.\nAC:L - A peer sending a sustained burst of TCP segments reliably drives GRO into the frag-list merge path, and the double-accounting underflow follows deterministically once the remaining `desc->count` budget is smaller than twice the frag-list bytes. No race and no attacker-uncontrollable state is involved.\nPR:N - The remote peer needs no credentials or privileges on the target — it only needs an established TCP connection to the zcrx-using service, which for a public-facing server is unauthenticated. The `capable(CAP_NET_ADMIN)` check in `io_register_zcrx_ifq()` is a property of the victim's own service setup, not a privilege the attacker must hold.\nUI:N - The overshoot occurs purely from processing inbound TCP data on an already-armed multishot `IORING_OP_RECV_ZC` request; no victim action beyond running the service is needed.\nS:U - The underflow, the over-read and the resulting request breakage are all confined to the kernel and the io_uring context that owns the socket and the registered zcrx area — no VM, IOMMU or sandbox boundary is crossed.\nC:L - The request is delivered socket data beyond the byte limit it explicitly requested, bypassing the read boundary that `IORING_OP_RECV_ZC`'s `len` is supposed to enforce; in designs where that limit demarcates data handed off to a different consumer the extra bytes are disclosed to the wrong one. There is no out-of-bounds read or kernel-memory leak, so the exposure is bounded to the connection's own stream.\nI:L - The kernel writes more data into the application's registered zcrx area than requested and advances the socket's `copied_seq` past the limit, consuming stream state that should have stayed queued, and `zc->len` is corrupted by an unsigned wrap. All writes remain within correctly sized objects, so there is no arbitrary-write or control-flow primitive.\nA:H - With `zc->len` wrapped to ~4 G the multishot recvzc request's completion condition can never be satisfied, so the request hangs indefinitely while unboundedly draining the socket, exhausting the zcrx area's niovs and overflowing the completion queue until it fails with a spurious `-ENOMEM`/`-ENOSPC`. A remote peer can reproduce this on every connection, rendering the affected network service non-functional." } ] } ], "affected": [ { "product": "Linux", "vendor": "Linux", "defaultStatus": "unaffected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "io_uring/zcrx.c" ], "versions": [ { "version": "6699ec9a23f85f1764183430209c741847c45f12", "lessThan": "8bcc9eaf1b19f1a7029cba19f6bd4122b40f6c4f", "status": "affected", "versionType": "git" }, { "version": "6699ec9a23f85f1764183430209c741847c45f12", "lessThan": "09cfd3c52ea76f43b3cb15e570aeddf633d65e80", "status": "affected", "versionType": "git" } ] }, { "product": "Linux", "vendor": "Linux", "defaultStatus": "affected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "io_uring/zcrx.c" ], "versions": [ { "version": "6.15", "status": "affected" }, { "version": "0", "lessThan": "6.15", "status": "unaffected", "versionType": "semver" }, { "version": "6.17.3", "lessThanOrEqual": "6.17.*", "status": "unaffected", "versionType": "semver" }, { "version": "6.18", "lessThanOrEqual": "*", "status": "unaffected", "versionType": "original_commit_for_fix" } ] } ], "cpeApplicability": [ { "nodes": [ { "operator": "OR", "negate": false, "cpeMatch": [ { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.15", "versionEndExcluding": "6.17.3" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.15", "versionEndExcluding": "6.18" } ] } ] } ], "references": [ { "url": "https://git.kernel.org/stable/c/8bcc9eaf1b19f1a7029cba19f6bd4122b40f6c4f" }, { "url": "https://git.kernel.org/stable/c/09cfd3c52ea76f43b3cb15e570aeddf633d65e80" } ], "title": "io_uring/zcrx: fix overshooting recv limit", "x_generator": { "engine": "bippy-1.2.0" } } } }