{"id":"CVE-2025-39977","state":"PUBLISHED","title":"futex: Prevent use-after-free during requeue-PI","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nfutex: Prevent use-after-free during requeue-PI\n\nsyzbot managed to trigger the following race:\n\n   T1                               T2\n\n futex_wait_requeue_pi()\n   futex_do_wait()\n     schedule()\n                               futex_requeue()\n                                 futex_proxy_trylock_atomic()\n                                   futex_requeue_pi_prepare()\n                                   requeue_pi_wake_futex()\n                                     futex_requeue_pi_complete()\n                                      /* preempt */\n\n         * timeout/ signal wakes T1 *\n\n   futex_requeue_pi_wakeup_sync() // Q_REQUEUE_PI_LOCKED\n   futex_hash_put()\n  // back to userland, on stack futex_q is garbage\n\n                                      /* back */\n                                     wake_up_state(q->task, TASK_NORMAL);\n\nIn this scenario futex_wait_requeue_pi() is able to leave without using\nfutex_q::lock_ptr for synchronization.\n\nThis can be prevented by reading futex_q::task before updating the\nfutex_q::requeue_state. A reference on the task_struct is not needed\nbecause requeue_pi_wake_futex() is invoked with a spinlock_t held which\nimplies a RCU read section.\n\nEven if T1 terminates immediately after, the task_struct will remain valid\nduring T2's wake_up_state().  A READ_ONCE on futex_q::task before\nfutex_requeue_pi_complete() is enough because it ensures that the variable\nis read before the state is updated.\n\nRead futex_q::task before updating the requeue state, use it for the\nfollowing wakeup.","publishedAt":"2025-10-15T07:55:58.283Z","updatedAt":"2026-10-15T22:02:35.093Z","severity":{"score":7.8,"label":"High","version":"3.1","vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","source":"Linux"},"assigner":"Linux","products":["Linux Linux"],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"cb5d19a61274b51b49601214a87af573b43d60fa","versionType":"git"},{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"348736955ed6ca6e99ca24b93b1d3fbfe352c181","versionType":"git"},{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"a170b9c0dde83312b8b58ccc91509c7c15711641","versionType":"git"},{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"d824b2dbdcfe3c390278dd9652ea526168ef6850","versionType":"git"},{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"b549113738e8c751b613118032a724b772aa83f2","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["kernel/futex/requeue.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"5.15","status":"affected"},{"version":"0","status":"unaffected","lessThan":"5.15","versionType":"semver"},{"version":"6.1.155","status":"unaffected","lessThanOrEqual":"6.1.*","versionType":"semver"},{"version":"6.6.109","status":"unaffected","lessThanOrEqual":"6.6.*","versionType":"semver"},{"version":"6.12.50","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.16.10","status":"unaffected","lessThanOrEqual":"6.16.*","versionType":"semver"},{"version":"6.17","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["kernel/futex/requeue.c"]}],"references":["https://git.kernel.org/stable/c/cb5d19a61274b51b49601214a87af573b43d60fa","https://git.kernel.org/stable/c/348736955ed6ca6e99ca24b93b1d3fbfe352c181","https://git.kernel.org/stable/c/a170b9c0dde83312b8b58ccc91509c7c15711641","https://git.kernel.org/stable/c/d824b2dbdcfe3c390278dd9652ea526168ef6850","https://git.kernel.org/stable/c/b549113738e8c751b613118032a724b772aa83f2","https://cert-portal.siemens.com/productcert/html/ssa-082556.html","https://cert-portal.siemens.com/productcert/html/ssa-019113.html","https://cert-portal.siemens.com/productcert/html/ssa-457936.html"],"weaknesses":[],"ingestedAt":"2026-10-29T20:09:09.358Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2025/39xxx/CVE-2025-39977.json","commit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2025-39977","state":"PUBLISHED","datePublished":"2025-10-15T07:55:58.283Z","dateUpdated":"2026-10-15T22:02:35.093Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2025-04-16T07:20:57.150Z"},"containers":{"cna":{"title":"futex: Prevent use-after-free during requeue-PI","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nfutex: Prevent use-after-free during requeue-PI\n\nsyzbot managed to trigger the following race:\n\n   T1                               T2\n\n futex_wait_requeue_pi()\n   futex_do_wait()\n     schedule()\n                               futex_requeue()\n                                 futex_proxy_trylock_atomic()\n                                   futex_requeue_pi_prepare()\n                                   requeue_pi_wake_futex()\n                                     futex_requeue_pi_complete()\n                                      /* preempt */\n\n         * timeout/ signal wakes T1 *\n\n   futex_requeue_pi_wakeup_sync() // Q_REQUEUE_PI_LOCKED\n   futex_hash_put()\n  // back to userland, on stack futex_q is garbage\n\n                                      /* back */\n                                     wake_up_state(q->task, TASK_NORMAL);\n\nIn this scenario futex_wait_requeue_pi() is able to leave without using\nfutex_q::lock_ptr for synchronization.\n\nThis can be prevented by reading futex_q::task before updating the\nfutex_q::requeue_state. A reference on the task_struct is not needed\nbecause requeue_pi_wake_futex() is invoked with a spinlock_t held which\nimplies a RCU read section.\n\nEven if T1 terminates immediately after, the task_struct will remain valid\nduring T2's wake_up_state().  A READ_ONCE on futex_q::task before\nfutex_requeue_pi_complete() is enough because it ensures that the variable\nis read before the state is updated.\n\nRead futex_q::task before updating the requeue state, use it for the\nfollowing wakeup."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"cb5d19a61274b51b49601214a87af573b43d60fa","versionType":"git"},{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"348736955ed6ca6e99ca24b93b1d3fbfe352c181","versionType":"git"},{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"a170b9c0dde83312b8b58ccc91509c7c15711641","versionType":"git"},{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"d824b2dbdcfe3c390278dd9652ea526168ef6850","versionType":"git"},{"version":"07d91ef510fb16a2e0ca7453222105835b7ba3b8","status":"affected","lessThan":"b549113738e8c751b613118032a724b772aa83f2","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["kernel/futex/requeue.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"5.15","status":"affected"},{"version":"0","status":"unaffected","lessThan":"5.15","versionType":"semver"},{"version":"6.1.155","status":"unaffected","lessThanOrEqual":"6.1.*","versionType":"semver"},{"version":"6.6.109","status":"unaffected","lessThanOrEqual":"6.6.*","versionType":"semver"},{"version":"6.12.50","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.16.10","status":"unaffected","lessThanOrEqual":"6.16.*","versionType":"semver"},{"version":"6.17","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["kernel/futex/requeue.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/cb5d19a61274b51b49601214a87af573b43d60fa"},{"url":"https://git.kernel.org/stable/c/348736955ed6ca6e99ca24b93b1d3fbfe352c181"},{"url":"https://git.kernel.org/stable/c/a170b9c0dde83312b8b58ccc91509c7c15711641"},{"url":"https://git.kernel.org/stable/c/d824b2dbdcfe3c390278dd9652ea526168ef6850"},{"url":"https://git.kernel.org/stable/c/b549113738e8c751b613118032a724b772aa83f2"}],"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 race is driven entirely through the futex(2) syscall (FUTEX_WAIT_REQUEUE_PI on one thread, FUTEX_CMP_REQUEUE_PI on another), which requires local execution on the target system. There is no remote or adjacent-network path into kernel/futex/requeue.c.\nAC:L - The attacker controls both sides of the race: it creates the waiter thread with an attacker-chosen short timeout (or delivers a signal) and simultaneously issues the requeue from a second thread, and can retry the loop millions of times with CPU pinning and interrupt pressure to hit the window between futex_requeue_pi_complete() and wake_up_state(). syzbot hit it with random fuzzing, and on PREEMPT_RT the hb spinlock_t is preemptible, making the window wide.\nPR:L - Any unprivileged local user can call futex() with FUTEX_WAIT_REQUEUE_PI/FUTEX_CMP_REQUEUE_PI; do_futex() and futex_requeue() contain no capability or credential checks, and CONFIG_FUTEX_PI is default-y. The path is reachable from inside containers and sandboxes with no elevated privileges.\nUI:N - The attacker's own two threads perform every step of the exploit; no victim action, mount, or file open is involved.\nS:U - The corruption occurs in kernel memory (a stale kernel stack frame and a type-confused task_struct) and stays within the kernel's own security authority. No VM, IOMMU, or hypervisor boundary is crossed.\nC:H - This is a use-after-free read of the waiter's dead kernel stack frame, and the resulting attacker-influenced task_struct pointer is dereferenced in try_to_wake_up() (p->__state, p->saved_state, p->on_rq, p->sched_class), giving an arbitrary kernel-memory read/oracle primitive. Per UAF guidance this is High.\nI:H - The stale futex_q lives on the attacker's own kernel stack, which can be refilled with controlled bytes by an immediately following syscall, so q->task becomes an attacker-chosen pointer; try_to_wake_up() then writes to it (raw_spin_lock on p->pi_lock, WRITE_ONCE(p->__state, TASK_RUNNING), runqueue list manipulation) and makes an indirect call through p->sched_class->enqueue_task(), a plausible local privilege-escalation path.\nA:H - In the unexploited case wake_up_state() dereferences a wild pointer from reused stack memory, causing an immediate oops/panic, and corrupting scheduler runqueue state can hang the machine. Any use-after-free of this kind is a High availability impact."}]}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-08-05T12:06:46.111Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.15","versionEndExcluding":"6.1.155"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.15","versionEndExcluding":"6.6.109"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.15","versionEndExcluding":"6.12.50"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.15","versionEndExcluding":"6.16.10"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.15","versionEndExcluding":"6.17"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}},"adp":[{"affected":[{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.5","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.6","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.7","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.5","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.6","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.7","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518F-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.5","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518F-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.6","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518F-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.7","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518F-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.5","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518F-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.6","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIMATIC S7-1500 CPU 1518F-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.7","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIPLUS S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.5","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIPLUS S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.6","status":"affected","lessThan":"*","versionType":"custom"}]},{"vendor":"Siemens","product":"SIPLUS S7-1500 CPU 1518-4 PN/DP MFP","defaultStatus":"unknown","versions":[{"version":"V3.1.7","status":"affected","lessThan":"*","versionType":"custom"}]}],"references":[{"url":"https://cert-portal.siemens.com/productcert/html/ssa-082556.html"},{"url":"https://cert-portal.siemens.com/productcert/html/ssa-019113.html"},{"url":"https://cert-portal.siemens.com/productcert/html/ssa-457936.html"}],"providerMetadata":{"shortName":"siemens-SADP","orgId":"0b142b55-0307-4c5a-b3c9-f314f3fb7c5e","dateUpdated":"2026-10-15T01:08:44.190Z"},"x_adpType":"supplier"},{"title":"CISA ADP Vulnrichment","metrics":[{"other":{"type":"ssvc","content":{"id":"CVE-2025-39977","role":"CISA Coordinator","options":[{"Exploitation":"none"},{"Automatable":"no"},{"Technical Impact":"total"}],"version":"2.0.3","timestamp":"2026-10-15T21:55:38.918885Z"}}}],"providerMetadata":{"shortName":"CISA-ADP","orgId":"134c704f-9b21-4f2e-91b3-4a467353bcc0","dateUpdated":"2026-10-15T22:02:35.093Z"}}]}}}