# CVE-2026-97903: exit: hold a reference to thread_pid across proc_flush_pid

> A race condition in the Linux kernel allows an unprivileged user to trigger a use-after-free in proc_flush_pid, potentially leading to code execution or privilege escalation.

- **Severity:** High 7.8 (`CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`)
- **Exploited in the wild:** Not known
- **Login needed:** Any signed-in user
- **Attackable:** Local or same network only
- **Victim action needed:** Not needed
- **Fix available:** Yes
- **Published:** 25 Sep 2026
- **Updated:** 19 Oct 2026
- **Also known as:** BELL-CVE-2026-97903, DEBIAN-CVE-2026-97903, GHSA-cpwj-27c2-jfgq, UBUNTU-CVE-2026-97903

## What is CVE-2026-97903?

CVE-2026-97903 is a high-severity use after free vulnerability in Linux, published on 25 Sep 2026. It can only be exploited from the same machine or local network, with no action from the victim.

### Official description

In the Linux kernel, the following vulnerability has been resolved:

exit: hold a reference to thread_pid across proc_flush_pid

Commit 0a36bad01731 ("release_task: kill the no longer needed
get/put_pid(thread_pid)") removed the reference around proc_flush_pid().
It assumed that free_pids(post.pids) at the end of release_task() would
keep thread_pid alive until then.

That assumption is wrong.  __change_pid() only records a detached PID in
post.pids when pid_has_task() is false for every PIDTYPE.  If another task
still uses the exiting task's PID as its process group or session ID,
__unhash_process() removes the exiting task's PIDTYPE_PID link but leaves
the PID out of post.pids.  release_task() therefore holds no reference to
it after dropping tasklist_lock.

The other task can then remove the remaining PIDTYPE links.  Its
free_pids() call schedules delayed_put_pid(), and the RCU callback can free
the PID before the first release_task() reaches proc_flush_pid().

An unprivileged reproducer races wait4(-1) against setsid() to trigger this
ordering.  Three of three fresh v7.2 KASAN boots reported:

    BUG: KASAN: slab-use-after-free in
    proc_invalidate_siblings_dcache+0x3e2/0x3f0
    Read of size 8 by task h7_pid_reaper/1921

    Call Trace:
     proc_invalidate_siblings_dcache
     release_task
     wait_consider_task
     __do_wait
     do_wait
     kernel_wait4

    Freed by task 0:
     kmem_cache_free
     put_pid
     delayed_put_pid
     rcu_core

    Last potentially related work creation:
     __call_rcu_common
     free_pids
     ksys_setsid

KASAN identified a 144-byte object from the pid cache and located the bad
read 80 bytes into the freed object, matching pid->inodes.  With an
explicit reference, three of three fresh boots completed without a KASAN
report.  The concurrent RCU callback dropped its reference while
proc_flush_pid() was protected, and the balancing put_pid() performed the
final free afterward.

Take a reference before __unhash_process() clears p->thread_pid and release
it after proc_flush_pid() completes.

A tested source reproducer is available privately on request.  No
controlled read or write, information leak, or privilege escalation is
claimed.  The mainline patch applies directly to v6.19.y and newer;
v6.16.y through v6.18.y need a context-adjusted backport.

## Which versions are affected by CVE-2026-97903?


## How do I fix CVE-2026-97903?

Apply the vendor's patch.

## Is CVE-2026-97903 being exploited?

There is no known exploitation of CVE-2026-97903 in the wild and no public exploit code.

## Fix prompt for AI coding agents

```text
Check this codebase for CVE-2026-97903 and fix it if it is affected.

What it is: CVE-2026-97903 is a high-severity use after free vulnerability in Linux, published on 25 Sep 2026. It can only be exploited from the same machine or local network, with no action from the victim.
Exploitation: There is no known exploitation of CVE-2026-97903 in the wild and no public exploit code.

Affected product: Linux. No package-level version data is available, so check the vendor advisory linked from the reference page.

Task:
1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.
2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.
3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.
4. Run the tests and summarise what changed and why.
5. If nothing in the project is affected, say so and change nothing.

Reference: https://insights.sbomify.com/CVE-2026-97903/ (Markdown: https://insights.sbomify.com/CVE-2026-97903/index.md)
```

## Sources

- CVE record: https://www.cve.org/CVERecord?id=CVE-2026-97903
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-97903
- OSV: https://osv.dev/vulnerability/CVE-2026-97903

---
From sbomify Insights: https://insights.sbomify.com/CVE-2026-97903/
Summaries are generated and may contain mistakes; the official description above is the record.
