Skip to content

CVE-2026-96812: Verified Reproduction

CVE-2026-96812: gVisor directfs openHandle host-FD identity TOCTOU → guest-to-host sandbox escape follow-up to CVE-2026-96812, no separate CVE assigned

CVE-2026-96812 is verified against google/gvisor · github. Fixed in release-20261005.0. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00382.

REPRO-2026-00382 google/gvisor · github Oct 9, 2026 CVE entry .txt
Severity
HIGH
Confidence
HIGH
Reproduced in
191m 18s
Tool calls
578
Spend
$22.53
01 · Overview

What Is CVE-2026-96812?

CVE-2026-96812 is a high-severity vulnerability affecting google/gvisor. Pruva has independently reproduced it and publishes a verified, runnable proof-of-concept (reproduction REPRO-2026-00382).

02 · Severity & CVSS

CVE-2026-96812 Severity

CVE-2026-96812 is rated high severity.

HIGH threat level
Weakness CWE-367

High — serious impact or readily exploitable. Prioritize remediation.

How to Reproduce CVE-2026-96812

$ pruva-verify REPRO-2026-00382
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00382/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-96812

sandbox escape — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

After the guest primes a regular directfs dentry, a host-side attacker atomically RENAME_EXCHANGEs its backing name with a selected host block-device node while guest O_TRUNC opens race revalidation against openHandle's open-by-name.

Attack chain
  1. production runsc --directfs=true --platform=systrap guest open(/race/target, O_RDWR|O_TRUNC)
  2. directfsInode.openHandle() unchecked openat()
  3. gofer preadv2/pwritev2 on the swapped host loop block descriptor
How the agent worked 1,069 events · 578 tool calls · 3h 11m
3h 11mDuration
578Tool calls
122Reasoning steps
1,069Events
44Dead-ends
Agent activity over 3h 11m
Policy
1
Support
8
Repro
647
Judge
100
Variant
307
Verify
1
0:00191:08

Root Cause and Exploit Chain for CVE-2026-96812

Versions: component: google/gvisor, pkg/sentry/fsimpl/gofer/directfs_inode.go, function (*directfsInode).openHandle().Fixed: version tested: release-20261005.0, commit 97e8e896904cb364319cd9758241d3f0bd27a6f4.

gVisor's directfs implementation in release-20260928.0 reopens a cached dentry by name in directfsInode.openHandle() without checking that the newly opened host file descriptor still identifies the file and type that the sentry previously revalidated. A host-side attacker who can modify the backing directory can preserve a cached regular-file dentry, then atomically race that name to a device node between revalidation and the later openat(). The vulnerable sentry uses the resulting device descriptor as a regular-file backing handle. This run proved the issue through the real runsc/directfs/systrap product path by racing a regular file with an otherwise sandbox-inaccessible host loop block device: the guest read a host-only secret and wrote unique guest-controlled markers into host-only backing images in two attempts. release-20261005.0 rejected the same swaps and wrote no marker.

  • Affected component: google/gvisor, pkg/sentry/fsimpl/gofer/directfs_inode.go, function (*directfsInode).openHandle().
  • Affected version tested: release-20260928.0, commit 6485c3fbdfe28172ced5d6aed49554cf494967db.
  • Fixed version tested: release-20261005.0, commit 97e8e896904cb364319cd9758241d3f0bd27a6f4.
  • Fix commit: cd968a36e5557215b5dcb8989011ce0e558b5dd0.
  • Required attacker/environment conditions: the attacker controls or can replace entries in a directfs-backed host directory after a guest has cached a regular-file dentry; the runsc host context can open the swapped device; the race wins between revalidation and open-by-name. This proof requires privileged host setup for an unattached loop device and uses the systrap platform.
  • Risk: high. A sandboxed guest obtained read/write access to a host block device that was neither present in the OCI rootfs nor mounted into the sandbox. On a real host, equivalent access to a security-relevant host block device can disclose or modify host filesystems and privileged state.

Impact Parity

  • Disclosed/claimed maximum impact: guest-to-host sandbox escape, described as host-root code execution through an unsafe host device FD.
  • Reproduced impact: repeatable guest-controlled read and write to an otherwise inaccessible host block device through production runsc. In two vulnerable attempts, the guest read HOST_ONLY_SECRET_4ec7309a from offset 4096 and wrote a unique 4096-byte marker at offset 8192. The host verified both markers directly in backing images outside the guest. Two fixed attempts created no markers and rejected the raced device opens.
  • Parity: partial.
  • Not demonstrated: no host process command was executed and no host-root shell or host executable modification was attempted. The proof establishes a concrete sandbox-boundary-crossing host storage read/write primitive, not a complete command-execution chain. The earlier CUSE path was not used as the final proof because gofer's regular-file I/O path forwards positional preadv2/pwritev2, which does not provide the normal CUSE handshake used by deterministic character-device passthrough.

Root Cause

The directfs dentry lifecycle separates identity validation from the host descriptor later used for data operations:

  1. The guest resolves /race/target while it is a stable regular file, so gVisor creates and caches a regular-file dentry/inode.

  2. Directfs revalidation examines a child reached from a parent control descriptor and validates metadata associated with that lookup.

  3. directfsInode.openHandle() subsequently obtains a usable handle by resolving the dentry name again:

    flags |= hostOpenFlags
    openFD, err := unix.Openat(parent.inode.impl.(*directfsInode).controlFD, d.name, int(flags), 0)
    if err != nil {
        return noHandle, err
    }
    return handle{fd: int32(openFD)}, nil
    
  4. In release-20260928.0, the returned openFD is accepted without fstat() or comparison against the cached inode type/device identity. A host renameat2(RENAME_EXCHANGE) can therefore let revalidation observe the original regular inode while the later openat() observes a device node at the same name.

  5. Because the sentry still treats the file description as a regular file, reads and writes are forwarded through the gofer host handle. With the raced loop block descriptor, guest pread() and pwrite() directly affected host block storage.

The fix commit cd968a36e5557215b5dcb8989011ce0e558b5dd0 performs Fstat(openFD), checks that the file type is supported, compares the reopened type with the cached inode type, and for character devices compares major/minor identity. A mismatch is closed and rejected as stale. For this block-device replacement, the fixed build rejects the block-device replacement with EPERM; the separate same-input /dev/cuse identity control returns ESTALE, exactly exercising the fix’s cached S_IFREG versus reopened S_IFCHR comparison. In both cases, the guest never receives a usable host device handle.

Reproduction Steps

  1. Run bundle/repro/reproduction_steps.sh from any directory. It accepts PRUVA_ROOT; the default resolves the bundle directory portably.
  2. The script reads bundle/project_cache_context.json, reuses the prepared gVisor repository and build cache when available, and otherwise creates bundle/artifacts/gvisor-cache.
  3. It anchors source/build identity to vulnerable commit 6485c3f... and fixed commit 97e8e896..., verifies that fix commit cd968a36... is absent/present respectively, and checks the actual Fstat(openFD) patch hunk.
  4. It builds or reuses genuine optimized runsc binaries, compiles the static guest and host racers, and starts a privileged Docker host fixture.
  5. For each of two vulnerable and two fixed attempts, the fixture creates a fresh 16 MiB host-only backing image and unattached loop device, writes a secret at offset 4096, starts a real runsc --directfs=true --platform=systrap sandbox, primes the target as a regular dentry, then begins atomic regular-file/block-device swaps.
  6. The guest races open(O_RDWR|O_TRUNC), reads the host secret, and attempts to write a unique marker at offset 8192. After runsc exits, the host reads that offset directly from the backing image.
  7. Exit code 0 requires both vulnerable attempts to read/write and create their exact markers, both fixed attempts to create no marker, and both fixed attempts to record device-open rejection.

Expected summary:

vulnerable_host_read_write_marker_attempts=2/2
fixed_host_write_marker_attempts=0/2
fixed_rejection_attempts=2/2
vulnerable_cuse_fd_control=1/1
fixed_cuse_estale_control=1/1

Evidence

Primary current-run evidence is under bundle/repro/results/ and is digest-bound by bundle/repro/runtime_manifest.json.

  • results/source-identity.log: exact vulnerable/fixed commits and patch presence.

  • results/runsc-version-{vuln,fixed}.txt: product versions exercised.

  • results/guest-vuln-1.log:

    GUEST_HOST_BLOCK_READ: secret=HOST_ONLY_SECRET_4ec7309a opens=2 offset=4096 bytes=4096
    GUEST_HOST_BLOCK_WRITE: marker=GUEST_HOST_MARKER_vuln_1_91d7c3ee offset=8192 bytes=4096 errno=0
    
  • results/guest-vuln-2.log: an independent vulnerable process repeats the read/write after 11 opens.

  • results/host-observation-vuln-1.log and host-observation-vuln-2.log: direct host inspection reports MATCH=true and includes marker bytes in hexadecimal.

  • results/host-marker-vuln-{1,2}.bin: exact marker bytes read from host-only backing images.

  • results/guest-fixed-1.log and guest-fixed-2.log: hundreds of thousands of block-device attempts produce no win; device-node windows return EPERM while regular-file windows remain usable.

  • results/cuse-guest-vuln.log: the vulnerable build accepts the raced /dev/cuse descriptor (GUEST_CUSE_FD_OPEN).

  • results/cuse-guest-fixed.log: the fixed build has no CUSE win and reports large nonzero estale counts for the identical synchronized swap, directly demonstrating the fix’s required ESTALE identity failure.

  • results/host-observation-fixed-{1,2}.log and host-marker-fixed-{1,2}.bin: host-side negative controls are all zero and report MATCH=false.

  • results/summary.txt: aggregate 2/2 vulnerable effects versus 0/2 fixed markers and 2/2 fixed rejection.

  • bundle/logs/reproduction_steps.log: complete final product-run diagnostics.

  • bundle/logs/final_run1_console.log and final_run2_console.log: two consecutive successful top-level executions.

  • bundle/repro/runtime_manifest.json: source identity, runtime stack, artifact list, and SHA-256 map.

The final run used Linux 6.8.0-142-generic, x86-64, Docker 29.1.3, gVisor systrap, directfs enabled, and no sanitizer.

The fdwatch files are retained as diagnostics only. They intentionally scope observations to runsc-reported process trees and exact loop major/minor, but sampled no rows because the vulnerable guest won and completed I/O faster than the /proc watcher acquired the process tree. Unlike the previous broad watcher, no unrelated host character-device rows are treated as proof. Exact guest output plus direct host backing-image marker comparison is the primary descriptor/effect correlation.

Recommendations / Next Steps

  • Upgrade to release-20261005.0 or later.
  • Preserve the fix's post-openat() identity checks. At minimum, compare file type against the cached inode; for device files, compare major/minor identity; close the descriptor and return ESTALE/an error on mismatch.
  • Add a regression test that synchronizes a cached regular dentry with an atomic replacement before openHandle(), covering character and block device substitutions.
  • Test all open modes that force a fresh handle, especially O_TRUNC, and test repeated revalidation/open races.
  • Treat any host device descriptor exposed through a cached regular dentry as a sandbox-boundary violation even if one specific device protocol is not usable through positional I/O.
  • For terminal exploit research, a host filesystem block device can be used to study controlled modification of a non-production fixture filesystem, but that escalation was deliberately not claimed here without current-run host command-execution evidence.

Additional Notes

  • The final script passed twice consecutively in the current runtime. Each invocation itself performs two vulnerable and two fixed process attempts.
  • The script is self-contained apart from declared source helpers and standard network/build prerequisites. It recompiles helpers and rebuilds runsc if compatible cached binaries are unavailable.
  • It bounds every runsc invocation with timeout, isolates each attempt with a fresh bundle/runsc root/tmpfs/backing image/loop mapping, and restores caller ownership of bind-mounted result paths.
  • The fixture is intentionally an unattached loop device rather than a live system disk. This safely proves host block read/write without risking corruption of the worker host.
  • runtime_manifest.json is rewritten on success and on premature failure; proof artifacts are finalized before they are hashed.

CVE-2026-96812 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:006:22
0:00
session startedaccounts/fireworks/models/kimi-k3 · GVISOR-DIRECTFS-OPENHANDLE-TOCTOU · REPRO-20
0:10
0:12
web search
1:05
1:06
extract_facts
no facts extracted
1:08
1:08
supportclaim_contract
1:15
1:15
1:15
1:20
1:20
1:20
1:27
1:27
1:27
$ls -la /dev/kvm /dev/cuse 2>&1; cat /proc/sys/kernel/randomize_va_space 2>/dev/null; uname -a; docker ps 2>&1 | head -3; which bazel bazelisk go 2>&1; nproc; free -g | head -2
0.3s✓
crw------- 1 root root 10, 203 Oct  6 21:08 /dev/cuse
crw-rw---- 1 root kvm  10, 232 Oct  6 21:08 /dev/kvm
2
Linux pruva-beef-01 6.8.0-142-generic #142-Ubuntu SMP PREEMPT_DYNAMIC Wed Sep  2 14:24:27 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
WARNING: Error loading config file: open /home/pruva/.docker/config.json: permission denied
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
8
               total        used        free      shared  buff/cache   available
1:36
1:36
$ls -la /data/pruva/project-cache/.run-views/c9464895c4fab7bb76237d97a86fc2a24c4f1cc928905770ac96a8f412e4c837/ 2>&1; echo ---; ls -la /data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/.pruva /data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/learning /data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/support /data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/repro 2>&1
✓
{"cwd":"/data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93","duration_ms":6,"exit_code":0,"stderr":"","stdout":"total 16\ndrwx------ 4 pruva pruva 4096 Oct  9 07:11 .\ndrwx------ 5 pruva pruva 4096 Oct  9 07:11 ..\ndrwx------ 2 pruva pruva 4096 Oct  9 07:11 .pruva\ndrwx------ 2 pruva pruva 4096 Oct  9 07:11 repo-mirrors\n---\n/data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/.pruva:\ntotal 12\ndrwx------ 2 pruva pruva 4096 Oct  9 07:11 .\ndrwx------ 8 pruva pruva 4096 Oct  9 07:12 ..\n-rw------- 1 pruva pruva  228 Oct  9 07:11 run_attempt.json\n\n/data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/learning:\ntotal 28\ndrwx------ 2 pruva pruva 4096 Oct  9 07:12 .\ndrwx------ 8 pruva pruva 4096 Oct  9 07:12 ..\n-rw------- 1 pruva pruva  853 Oct  9 07:12 exploit_knowledge_preflight.json\n-rw------- 1 pruva pruva 5683 Oct  9 07:11 policy_inputs.json\n-rw------- 1 pruva pruva 4473 Oct  9 07:11 policy_result.json\n\n/data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/repro:\ntotal 8\ndrwx------ 2 pruva pruva 4096 Oct  9 07:12 .\ndrwx------ 8 pruva pruva 4096 Oct  9 07:12 ..\n\n/data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/support:\ntotal 8\n… [truncated]
4:18
4:19
$sudo -n true && echo SUDO_OK; for r in 20260928 20261005; do echo "== $r =="; curl -sI "https://storage.googleapis.com/gvisor/releases/release/$r/x86_64/runsc" | head -5; done
0.4s✓
== 20260928 ==
HTTP/2 404 
content-type: application/xml; charset=UTF-8
x-guploader-uploadid: AP6rU81Jss3YkkUy8mteKk75MHGIfQZ2VWz9pJyN5Lb8QxoV5p9oleqYxs4DMAohlHq852F7
content-length: 207
date: Fri, 09 Oct 2026 07:15:50 GMT
== 20261005 ==
HTTP/2 404 
4:54
4:55
$id; echo ---; curl -sI https://github.com/google/gvisor | head -3; echo ---; git ls-remote --tags https://github.com/google/gvisor 'refs/tags/release-20260928*' 'refs/tags/release-20261005*' 2>&1
1.1s✓
uid=1000(pruva) gid=1001(pruva) groups=1001(pruva),27(sudo),993(kvm),1000(docker)
---
HTTP/2 200 
date: Fri, 09 Oct 2026 07:16:27 GMT
content-type: text/html; charset=utf-8
---
6882e7c944eedfeac97f0663a583c159b8f127a2	refs/tags/release-20260928.0
6485c3fbdfe28172ced5d6aed49554cf494967db	refs/tags/release-20260928.0^{}
5:48
5:48
6:01
$docker images 2>&1 | head -10; echo ---; docker run --rm --privileged --device /dev/kvm debian:bookworm-slim bash -c 'id; ls -l /dev/kvm /dev/cuse 2>&1' 2>&1 | tail -8
12.4s✓
{"cwd":"/data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93","duration_ms":12324,"exit_code":0,"stderr":"","stdout":"WARNING: Error loading config file: open /home/pruva/.docker/config.json: permission denied\nWARNING: This output is designed for human readability. For machine-readable output, please use --format.\nIMAGE                                                                                                   ID             DISK USAGE   CONTENT SIZE   EXTRA\nalpine:3.22                                                                                             14358309a308       12.8MB         3.88MB        \ndocker:27-dind-rootless@sha256:e2ac8e8f66ae21a060b0a8e3005c70f6ed9441aabf409434463d1f6eecd38026         e2ac8e8f66ae        607MB          159MB        \nghcr.io/n3mes1s/pruva-sandbox@sha256:8096b2518d6022e13d68f885c3b8ded6b4fe607098b1a1ccbfb99abc004d1dc1   8096b2518d60       2.16GB          553MB        \ngradle:4.10.3-jdk8                                                                                      393cd6c24d69        1.1GB          324MB        \nhermes-r4-repro:1                                                                                       b34f5cb… [truncated]
6:21
6:22
$mkdir -p /data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/repro/src; cd /data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93/bundle/repro/src; for t in release-20260928.0 release-20261005.0; do curl -sf "https://raw.githubusercontent.com/google/gvisor/$t/pkg/sentry/fsimpl/gofer/directfs_inode.go" -o "directfs_inode.$t.go" && echo "fetched $t"; done; echo ---; sed -n '215,275p' directfs_inode.release-20260928.0.go
0.5s✓
{"cwd":"/data/pruva/runs/cd137c5d-1a98-4ab9-a1cf-0989f9cb6d93","duration_ms":461,"exit_code":0,"stderr":"","stdout":"fetched release-20260928.0\nfetched release-20261005.0\n---\n\n\ttemp.d.init()\n\t// If this dentry adopted a cached inode that already carries a bound-socket\n\t// endpoint (a hard link to, or re-walk of, an existing bound socket), hold\n\t// the extra reference that dentry.refs keeps for endpoint-bearing dentries.\n\t// The bind path takes this reference itself, over a fresh inode.\n\tif temp.d.inode.endpoint != nil {\n\t\ttemp.d.IncRef()\n\t}\n\tfs.syncMu.Lock()\n\tfs.syncableDentries.PushBack(&temp.d.syncableListEntry)\n\tfs.syncMu.Unlock()\n\treturn &temp.d, nil\n\n}\n\n// Precondition: fs.renameMu is locked.\nfunc (i *directfsInode) openHandle(ctx context.Context, flags uint32, d *dentry) (handle, error) {\n\tparent := d.parent.Load()\n\tif parent == nil {\n\t\t// This is a mount point. We don't have parent. Fallback to using lisafs.\n\t\tif !i.controlFDLisa.Ok() {\n\t\t\tpanic(\"directfsInode.controlFDLisa is not set for mount point dentry\")\n\t\t}\n\t\topenFD, hostFD, err := i.controlFDLisa.OpenAt(ctx, flags)\n\t\tif err != nil {\n\t\t\treturn noHandle, err\… [truncated]

Artifacts and Evidence for CVE-2026-96812

Scripts, logs, diffs, and output captured during the reproduction.

bundle/repro/rca_report.md11.0 KB
bundle/repro/reproduction_steps.sh10.4 KB
bundle/repro/results/backing-sha-fixed-1.txt0.1 KB
bundle/repro/results/backing-sha-fixed-2.txt0.1 KB
bundle/repro/results/backing-sha-vuln-1.txt0.1 KB
bundle/repro/results/backing-sha-vuln-2.txt0.1 KB
bundle/repro/results/cuse-swapper-fixed.log0.0 KB
bundle/repro/results/cuse-swapper-vuln.log0.0 KB
bundle/repro/results/fdwatch-fixed-1.log0.0 KB
bundle/repro/results/fdwatch-fixed-2.log0.0 KB
bundle/repro/results/fdwatch-vuln-1.log0.0 KB
bundle/repro/results/fdwatch-vuln-2.log0.0 KB
bundle/repro/results/guest-fixed-1.exit0.0 KB
bundle/repro/results/guest-fixed-2.exit0.0 KB
bundle/repro/results/guest-vuln-1.exit0.0 KB
bundle/repro/results/guest-vuln-2.exit0.0 KB
bundle/repro/results/host-marker-fixed-1.bin0.1 KB
bundle/repro/results/host-marker-fixed-2.bin0.1 KB
bundle/repro/results/host-observation-vuln-1.log0.3 KB
bundle/repro/results/host-observation-vuln-2.log0.3 KB
bundle/repro/results/racer-fixed-1.log0.1 KB
bundle/repro/results/racer-vuln-1.log0.2 KB
bundle/repro/results/racer-vuln-3.log45.5 KB
bundle/repro/results/runsc-version-fixed.txt0.0 KB
bundle/repro/results/runsc-version-vuln.txt0.0 KB
bundle/repro/results/setup-fixed-1.log0.2 KB
bundle/repro/results/setup-fixed-2.log0.2 KB
bundle/repro/results/setup-vuln-1.log0.2 KB
bundle/repro/results/setup-vuln-2.log0.2 KB
bundle/repro/results/source-identity.log0.2 KB
bundle/repro/results/swapper-fixed-1.log0.0 KB
bundle/repro/results/swapper-fixed-2.log0.0 KB
bundle/repro/results/swapper-vuln-1.log0.0 KB
bundle/repro/results/swapper-vuln-2.log0.0 KB
bundle/repro/runtime_manifest.json7.0 KB
bundle/repro/src/Dockerfile.builder0.4 KB
bundle/repro/src/cuse_identity_inside.sh1.6 KB
bundle/repro/src/guest_block_racer.c2.5 KB
bundle/repro/src/guest_cuse_identity.c1.8 KB
bundle/repro/src/guest_racer.c5.9 KB
bundle/repro/src/host_block_swapper.c2.0 KB
bundle/repro/src/host_cuse_swapper.c1.2 KB
bundle/repro/src/host_swapper.c2.4 KB
bundle/repro/src/race_block_inside.sh6.7 KB
bundle/repro/src/race_inside.sh4.7 KB
bundle/repro/validation_verdict.json1.5 KB
08 · How to Fix

How to Fix CVE-2026-96812

Upgrade google/gvisor · github to release-20261005.0 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-96812 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-96812

Is CVE-2026-96812 exploitable?

Yes. Pruva independently reproduced CVE-2026-96812 in google/gvisor and verified the exploit fires end-to-end in a sandboxed environment. A runnable proof-of-concept script and the full agent transcript are on this page (reproduction REPRO-2026-00382).

How severe is CVE-2026-96812?

CVE-2026-96812 is rated high severity.

What type of vulnerability is CVE-2026-96812?

CVE-2026-96812 is classified as CWE-367.

Is there a fix for CVE-2026-96812?

Yes. CVE-2026-96812 is fixed in google/gvisor release-20261005.0. Upgrading to the fixed version remediates the issue.

How can I reproduce CVE-2026-96812?

Pruva provides a verified reproduction script on this page. Download it and run it inside an isolated environment such as a container or virtual machine — never against production. The reproduction was confirmed end-to-end by Pruva's automated agents.

Is the CVE-2026-96812 reproduction verified?

Yes. Pruva reproduced CVE-2026-96812 with high confidence in a sandboxed environment, capturing the full agent transcript and artifacts as evidence.
11 · References

References for CVE-2026-96812

Authoritative sources for CVE-2026-96812 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.