{ "dataType": "CVE_RECORD", "dataVersion": "5.2", "cveMetadata": { "cveId": "CVE-2025-38002", "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "state": "PUBLISHED", "assignerShortName": "Linux", "dateReserved": "2025-04-16T04:51:23.977Z", "datePublished": "2025-06-06T13:43:41.137Z", "dateUpdated": "2026-08-05T11:58:53.483Z" }, "containers": { "cna": { "providerMetadata": { "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux", "dateUpdated": "2026-08-05T11:58:53.483Z" }, "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nio_uring/fdinfo: grab ctx->uring_lock around io_uring_show_fdinfo()\n\nNot everything requires locking in there, which is why the 'has_lock'\nvariable exists. But enough does that it's a bit unwieldy to manage.\nWrap the whole thing in a ->uring_lock trylock, and just return\nwith no output if we fail to grab it. The existing trylock() will\nalready have greatly diminished utility/output for the failure case.\n\nThis fixes an issue with reading the SQE fields, if the ring is being\nactively resized at the same time." } ], "metrics": [ { "cvssV3_1": { "version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", "baseScore": 7.8, "baseSeverity": "HIGH" }, "scenarios": [ { "lang": "en", "value": "AV:L - The vulnerable path is reached purely through local syscalls — `io_uring_setup()`/`io_uring_register(IORING_REGISTER_RESIZE_RINGS)` plus a `read()` of `/proc/self/fdinfo/`. No remote or adjacent-network data is processed anywhere along the path.\nAC:L - The attacker controls both sides of the race, spinning one thread on resize and another on fdinfo reads, and can widen the window arbitrarily by using a large old ring and a small new ring so the unlocked SQE/CQE dump loop runs for thousands of iterations. No condition outside the attacker's influence is required.\nPR:L - Any unprivileged local user can create an io_uring instance with `IORING_SETUP_DEFER_TASKRUN|SINGLE_ISSUER` and resize it; no capability check exists on the register path. Reading one's own `/proc/self/fdinfo/` always satisfies the `ptrace_may_access(PTRACE_MODE_READ_FSCREDS)` gate in `proc_fdinfo_permission()`.\nUI:N - The entire attack runs inside the attacker's own process using its own ring fd and its own procfs entries. No other user or administrator has to do anything.\nS:U - The stale-pointer reads, faults, and information disclosure all occur in kernel context against the attacking process's own kernel objects, within the same security authority. No VM, IOMMU, or sandbox boundary is crossed.\nC:H - Stale `ctx->rings`/`ctx->sq_array` pointers are dereferenced after `release_pages()`/`vunmap()` frees the old ring regions, and stale `sq_entries`/`sq_mask` combined with the new smaller `ctx->sq_sqes` yield an out-of-bounds read of up to ~2 MB past the SQE region at an offset the attacker chooses through the userspace-mapped `sq_array`. The recovered bytes (`opcode, fd, flags, off, addr, rw_flags, buf_index, user_data`, or a full 128 bytes with SQE128) are `seq_printf()`ed directly into the fdinfo output the attacker reads, giving a repeatable kernel-memory disclosure primitive.\nI:H - This is a use-after-free on freed ring pages that can be recycled into arbitrary kernel allocations and then heap-sprayed by the attacker to steer the derived out-of-bounds dereference, consistent with UAF scoring practice for this subsystem. The leaked heap contents and kernel pointers also defeat KASLR and directly enable control-flow-hijacking exploitation of adjacent kernel state.\nA:H - `ctx->rings` and `ctx->sq_sqes` are transiently NULL during the swap, so `READ_ONCE(r->sq.head)` and `&ctx->sq_sqes[sq_idx << sq_shift]` produce a NULL-pointer oops, and dereferencing a `vunmap()`'d old region or reading megabytes past the new SQE region faults the kernel. An unprivileged user can trigger these in a tight loop for a reliable panic." } ] } ], "affected": [ { "product": "Linux", "vendor": "Linux", "defaultStatus": "unaffected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "io_uring/fdinfo.c" ], "versions": [ { "version": "79cfe9e59c2a12c3b3faeeefe38d23f3d8030972", "lessThan": "bdb7d2ec2e31c46c45d1f32667dfa8216a72705e", "status": "affected", "versionType": "git" }, { "version": "79cfe9e59c2a12c3b3faeeefe38d23f3d8030972", "lessThan": "d871198ee431d90f5308d53998c1ba1d5db5619a", "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/fdinfo.c" ], "versions": [ { "version": "6.13", "status": "affected" }, { "version": "0", "lessThan": "6.13", "status": "unaffected", "versionType": "semver" }, { "version": "6.14.8", "lessThanOrEqual": "6.14.*", "status": "unaffected", "versionType": "semver" }, { "version": "6.15", "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.13", "versionEndExcluding": "6.14.8" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.13", "versionEndExcluding": "6.15" } ] } ] } ], "references": [ { "url": "https://git.kernel.org/stable/c/bdb7d2ec2e31c46c45d1f32667dfa8216a72705e" }, { "url": "https://git.kernel.org/stable/c/d871198ee431d90f5308d53998c1ba1d5db5619a" }, { "url": "https://project-zero.issues.chromium.org/issues/417522668" } ], "title": "io_uring/fdinfo: grab ctx->uring_lock around io_uring_show_fdinfo()", "x_generator": { "engine": "bippy-1.2.0" } } } }