{ "dataType": "CVE_RECORD", "dataVersion": "5.2", "cveMetadata": { "cveId": "CVE-2025-40061", "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "state": "PUBLISHED", "assignerShortName": "Linux", "dateReserved": "2025-04-16T07:20:57.158Z", "datePublished": "2025-10-28T11:48:33.361Z", "dateUpdated": "2026-08-05T12:07:27.040Z" }, "containers": { "cna": { "providerMetadata": { "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux", "dateUpdated": "2026-08-05T12:07:27.040Z" }, "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nRDMA/rxe: Fix race in do_task() when draining\n\nWhen do_task() exhausts its iteration budget (!ret), it sets the state\nto TASK_STATE_IDLE to reschedule, without a secondary check on the\ncurrent task->state. This can overwrite the TASK_STATE_DRAINING state\nset by a concurrent call to rxe_cleanup_task() or rxe_disable_task().\n\nWhile state changes are protected by a spinlock, both rxe_cleanup_task()\nand rxe_disable_task() release the lock while waiting for the task to\nfinish draining in the while(!is_done(task)) loop. The race occurs if\ndo_task() hits its iteration limit and acquires the lock in this window.\nThe cleanup logic may then proceed while the task incorrectly\nreschedules itself, leading to a potential use-after-free.\n\nThis bug was introduced during the migration from tasklets to workqueues,\nwhere the special handling for the draining case was lost.\n\nFix this by restoring the original pre-migration behavior. If the state is\nTASK_STATE_DRAINING when iterations are exhausted, set cont to 1 to\nforce a new loop iteration. This allows the task to finish its work, so\nthat a subsequent iteration can reach the switch statement and correctly\ntransition the state to TASK_STATE_DRAINED, stopping the task as intended." } ], "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 - Both sides of the race are driven through local verbs calls on /dev/infiniband/uverbsN — posting work requests to exhaust the 1024-iteration budget and concurrently issuing modify_qp(RESET)/destroy_qp. Remote RoCE packets can feed the responder task, but the draining half (rxe_disable_task/rxe_cleanup_task) is only reachable from a local ioctl/write on the uverbs device.\nAC:L - The attacker controls both racers: one thread posts more than RXE_MAX_ITERATIONS work items so do_task deterministically hits the `!ret` branch, while another thread calls modify_qp(RESET) or destroy_qp to set TASK_STATE_DRAINING. The window can be retried unboundedly across many QPs and widened with CPU contention, so no condition lies outside the attacker's influence.\nPR:L - The kernel's uverbs_devnode() publishes /dev/infiniband/uverbsN with mode 0666, so any unprivileged local account can allocate a PD/CQ/QP and drive the race with no capabilities. Only the one-time creation of the rdma_rxe link requires CAP_NET_ADMIN, which is administrator setup rather than a privilege the attacker must hold.\nUI:N - The attacker performs every step itself from its own process; no victim action, mount, or file open is involved.\nS:U - The corruption is confined to kernel objects owned by the same kernel security authority (rxe QP, queues, CQs, MRs); no VM, IOMMU, or sandbox boundary is crossed.\nC:H - Clobbering DRAINING lets a work item run rxe_responder/rxe_requester against a QP whose send/receive queues have been vfree'd or memset and whose MRs and CQs have been put, giving use-after-free reads of freed kernel memory that are copied into userspace-mapped completion queues and onto the wire.\nI:H - The same use-after-free is a write primitive: the re-scheduled responder writes CQ entries, WQE state, and RDMA payloads into freed queue and MR memory, and duplicated rxe_put() calls underflow object refcounts, enabling heap grooming toward control-flow hijack.\nA:H - The race trips WARN_ON(task->num_done != task->num_sched) and dereferences freed rxe_queue, CQ, MR, and socket objects, reliably producing an oops or panic and taking down the machine." } ] } ], "affected": [ { "product": "Linux", "vendor": "Linux", "defaultStatus": "unaffected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "drivers/infiniband/sw/rxe/rxe_task.c" ], "versions": [ { "version": "9b4b7c1f9f54120940e243251e2b1407767b3381", "lessThan": "85288bcf7ffe11e7b036edf91937bc62fd384076", "status": "affected", "versionType": "git" }, { "version": "9b4b7c1f9f54120940e243251e2b1407767b3381", "lessThan": "52edccfb555142678c836c285bf5b4ec760bd043", "status": "affected", "versionType": "git" }, { "version": "9b4b7c1f9f54120940e243251e2b1407767b3381", "lessThan": "660b6959c4170637f5db2279d1f71af33a49e49b", "status": "affected", "versionType": "git" }, { "version": "9b4b7c1f9f54120940e243251e2b1407767b3381", "lessThan": "8ca7eada62fcfabf6ec1dc7468941e791c1d8729", "status": "affected", "versionType": "git" } ] }, { "product": "Linux", "vendor": "Linux", "defaultStatus": "affected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "drivers/infiniband/sw/rxe/rxe_task.c" ], "versions": [ { "version": "6.5", "status": "affected" }, { "version": "0", "lessThan": "6.5", "status": "unaffected", "versionType": "semver" }, { "version": "6.6.112", "lessThanOrEqual": "6.6.*", "status": "unaffected", "versionType": "semver" }, { "version": "6.12.53", "lessThanOrEqual": "6.12.*", "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.5", "versionEndExcluding": "6.6.112" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.5", "versionEndExcluding": "6.12.53" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.5", "versionEndExcluding": "6.17.3" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.5", "versionEndExcluding": "6.18" } ] } ] } ], "references": [ { "url": "https://git.kernel.org/stable/c/85288bcf7ffe11e7b036edf91937bc62fd384076" }, { "url": "https://git.kernel.org/stable/c/52edccfb555142678c836c285bf5b4ec760bd043" }, { "url": "https://git.kernel.org/stable/c/660b6959c4170637f5db2279d1f71af33a49e49b" }, { "url": "https://git.kernel.org/stable/c/8ca7eada62fcfabf6ec1dc7468941e791c1d8729" } ], "title": "RDMA/rxe: Fix race in do_task() when draining", "x_generator": { "engine": "bippy-1.2.0" } } } }