{ "dataType": "CVE_RECORD", "dataVersion": "5.2", "cveMetadata": { "cveId": "CVE-2025-38411", "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "state": "PUBLISHED", "assignerShortName": "Linux", "dateReserved": "2025-04-16T04:51:24.013Z", "datePublished": "2025-07-25T13:20:15.835Z", "dateUpdated": "2026-08-05T12:01:40.641Z" }, "containers": { "cna": { "providerMetadata": { "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux", "dateUpdated": "2026-08-05T12:01:40.641Z" }, "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nnetfs: Fix double put of request\n\nIf a netfs request finishes during the pause loop, it will have the ref\nthat belongs to the IN_PROGRESS flag removed at that point - however, if it\nthen goes to the final wait loop, that will *also* put the ref because it\nsees that the IN_PROGRESS flag is clear and incorrectly assumes that this\nhappened when it called the collector.\n\nIn fact, since IN_PROGRESS is clear, we shouldn't call the collector again\nsince it's done all the cleanup, such as calling ->ki_complete().\n\nFix this by making netfs_collect_in_app() just return, indicating that\nwe're done if IN_PROGRESS is removed." } ], "metrics": [ { "cvssV3_1": { "version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "baseScore": 9.8, "baseSeverity": "CRITICAL" }, "scenarios": [ { "lang": "en", "value": "AV:N - The pause loop is entered only when `NETFS_RREQ_PAUSE` is set, which happens in `netfs_read_subreq_terminated()`/`netfs_write_collection()` in response to subrequest errors, short reads or retry conditions produced by the remote file server (cifs/SMB, 9p, AFS, Ceph). A malicious, compromised, or MITM'd server drives the entire trigger sequence over the network with no local access.\nAC:L - The remote server controls both halves of the sequence — it chooses which subrequest to fail (setting PAUSE) and when to complete the remaining subrequests, so it can reliably make the request finish while the app thread is in the pause loop. Nothing depends on conditions outside the attacker's influence, and the attempt can be repeated on every read/write until it lands.\nPR:N - The attacker is the network peer itself (the file server or an on-path attacker on an unsigned/unencrypted SMB/9p connection) and needs no account, credentials, or privileges on the victim client. All processing happens in the client's normal I/O path with no capability check between the received response and the double put.\nUI:N - Once a share is mounted — an ordinary pre-existing system configuration, not a per-attack action — any routine read, readahead, direct I/O or write-through by any process on the client triggers the path. No victim interaction is needed at exploitation time, consistent with the adjacent netfs collection-path CVEs.\nS:U - The corrupted object is a kernel heap allocation (`struct netfs_io_request`) and the impact stays within the kernel's own security authority. There is no crossing of a VM, IOMMU, or sandbox boundary.\nC:H - The double `netfs_put_request()` drives the refcount to zero while the issuing thread still dereferences the request, reading `rreq->error`, `->transferred`, `->origin`, `->submitted` and `->len` out of freed slab memory. Because `netfs_io_request` comes from a dedicated mempool that can be re-filled by attacker-paced requests, the reclaimed contents can be groomed to leak arbitrary kernel data.\nI:H - The premature free yields a use-after-free write — a `refcount_dec` and a second `queue_work()` on `rreq->cleanup_work` inside an object that has been reallocated — which corrupts workqueue list pointers and gives a controllable write primitive suitable for control-flow hijack. The second collector pass additionally re-invokes `->ki_complete()` and `inode_dio_end()`, double-completing an AIO/io_uring request and underflowing `i_dio_count`.\nA:H - Even without grooming, the refcount underflow, double free and use-after-free reliably produce a refcount WARN, slab corruption, or kernel oops/panic, and the double `inode_dio_end()` underflow can wedge subsequent direct I/O on the inode. A hostile server can trigger it repeatedly to keep the client down." } ] } ], "affected": [ { "product": "Linux", "vendor": "Linux", "defaultStatus": "unaffected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "fs/netfs/misc.c", "include/trace/events/netfs.h" ], "versions": [ { "version": "329ba1cb402ac328224965b8fc7a554a5150908e", "lessThan": "d18facba5a5795ad44b2a00a052e3db2fa77ab12", "status": "affected", "versionType": "git" }, { "version": "2b1424cd131cfaba4cf7040473133d26cddac088", "lessThan": "9df7b5ebead649b00bf9a53a798e4bf83a1318fd", "status": "affected", "versionType": "git" } ] }, { "product": "Linux", "vendor": "Linux", "defaultStatus": "unaffected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "fs/netfs/misc.c", "include/trace/events/netfs.h" ], "versions": [ { "version": "6.15.3", "lessThan": "6.15.6", "status": "affected", "versionType": "semver" } ] } ], "cpeApplicability": [ { "nodes": [ { "operator": "OR", "negate": false, "cpeMatch": [ { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.15.3", "versionEndExcluding": "6.15.6" } ] } ] } ], "references": [ { "url": "https://git.kernel.org/stable/c/d18facba5a5795ad44b2a00a052e3db2fa77ab12" }, { "url": "https://git.kernel.org/stable/c/9df7b5ebead649b00bf9a53a798e4bf83a1318fd" } ], "title": "netfs: Fix double put of request", "x_generator": { "engine": "bippy-1.2.0" } } } }