VULNARCHIVE

GCVE-1988-2026-0098

OpenZFS Linux open zpool manipulation and escapes via unprivileged userns

Description (en)

I am hopeful that upstream patches and remediation guidance will be
available soon. I have been sitting on these for a bit, and have run this
through AI services hosted in Singapore and the United States, and had
notified CERT on 8/12/2026. In order to minimize the risk of asymmetric
knowledge of these threats being used against defenders, I am opting for
full-disclosure.

Cheers from HOPE

--Bird

## Report metadata

- **Product:** OpenZFS on Linux (`spl.ko` and `zfs.ko`; out-of-tree and not
  part of the Linux kernel source tree)
- **OpenZFS revision audited:** `9b7642df931a765509403318553f2910daf71305`
  (development version `2.4.99-1`, commit title "Harden recv record
validation")
- **Linux validation kernel:** `7.2.0-rc3-00275-gaf5e34a41cd6`
- **Validation environments:** disposable QEMU guest with generic KASAN and
  `CONFIG_KASAN_VMALLOC=y`; a stock IncusOS appliance guest for
  deployment-level authorization/volume-swap validation; disposable QEMU
  appliance VMs for Proxmox VE, TrueNAS SCALE, and Unraid dynamic
reachability
  testing. Release-mode OpenZFS modules unless stated otherwise.
- **Research dates:** 2026-07-17 through 2026-07-25
- **Report updated:** 2026-07-25
- **Reporter:** Erica Windisch
- **Tracker umbrella:** [issue #26](
https://github.com/ewindisch/linux-research-tracker/issues/26)

All kernel execution used disposable QEMU/cloud-hypervisor guests — the
KASAN
research guest or the stock IncusOS appliance guest. Host-side work was
limited
to building, offline image construction, and driving those guests.

### Revision notes

- **2026-07-25 (validation-chain results):** OZ-3c and OZ-6 move from
  **LIKELY** to **VALIDATED** with dynamic triggers in the KASAN guest
  (OZ-3c: UBSAN array-index-out-of-bounds at `zfs_replay.c:115`; OZ-6: KASAN
  null-ptr-deref in `vdev_is_concrete` and slab-out-of-bounds in
  `spa_ld_log_sm_cb`). QNAP QZFS static analysis validates
Z1/Z2/dnode-bonus S3
  and gang overrun, and BLOCKS log-spacemap S4 (feature absent). The
upstream
  patch audit confirms every OZ finding remains **UNFIXED** at upstream
master
  HEAD `3020c18c` (2026-07-24); only OZ-7 has an open, contested PR
(#18620).
  Full audit:
[`research/upstream-patch-audit.md`](../research/upstream-patch-audit.md).
- **2026-07-25 (OZ-4 on Proxmox VE):** the Proxmox VE 8.x OZ-4 cell is
upgraded
  from provisional to a confirmed dynamic verdict. On `6.8.12-37-pve` /
  OpenZFS `2.2.10-pve1`, importing the armed dnode-bonus pool (`dn_bonuslen=
  0x400`, `zfs-77-d77-s3v2.img`) **from inside the delegated LXC container**
  (CT100 with the OZ-1 verified `/dev/zfs` passthrough) fired the
  `dbuf_read_bonus` overflow on `spa_tryimport → spa_load →
  spa_ld_trusted_config` and crashed the kernel (NULL-deref in `strcmp`
during
  `vdev_open_children_impl`; host-side corroboration showed SLUB
`LIST_POISON`
  heap corruption in `dbuf_sync_list`). OZ-4 is therefore **VIABLE from the
  delegated/privileged container** and **BLOCKED by default** (default
  unprivileged LXC has no `/dev/zfs`). A container→root shell was not
  reproduced on the stock appliance (release kernel faults
deterministically;
  no KASLR leak). Full verdict and evidence:
  `linux-research/.fleet-coord/oz4-proxmox-verdict.md`;

`linux-research/appliance-harness/proxmox-ve/runs/20260725T150254Z/evidence/`.
- **2026-07-25 (OZ-4 on Unraid):** the Unraid 7.3.0 OZ-4 cell is upgraded
from
  provisional to a confirmed dynamic verdict. On `6.18.29-Unraid` / OpenZFS
  `2.4.1-1`, importing the inflated-bonus pool (`dn_bonuslen=0x1000`,
  `zfs-77-d77-s3v3.img`) from a `--privileged` Docker container fails
  `insufficient replicas` while the structurally identical clean control
  imports ONLINE; the kernel survives (silent heap corruption, no
panic/Oops).
  OZ-4 is therefore **VIABLE from `--privileged`** and **BLOCKED** by
default
  and `--device /dev/zfs` (no `/dev/zfs` / no `CAP_SYS_ADMIN`). A
container→root
  shell was not pursued (requires heap grooming + KASLR bypass). Full
verdict
  and evidence: `linux-research/.fleet-coord/oz4-unraid-verdict.md`;
  `linux-research/appliance-harness/unraid/runs/20260725T150925Z/evidence/`.
- **2026-07-25 (OZ-4 OCI delivery on IncusOS):** an OCI image
  (`oz4-delivery:latest`) carrying the armed pool (`d77.img`) was built with
  podman, repacked as an Incus image, and launched as a default unprivileged
  Incus container on IncusOS `202607192224` (OpenZFS `2.4.3-1`). The
container
  received `/dev/zfs` and the ioctls were authorized (OZ-1 reachability
  **VIABLE**), but the host kernel could not open the file vdev at the
  container-relative path (`/opt/d77.img`), so the OZ-4 overflow never fired
  (**BLOCKED** for the in-container E2E fire). IncusOS's shell-less design
  removes the host-side bind-mount escape hatch that made the fire possible
on
  Proxmox VE. Full verdict and evidence:
  `linux-research/.fleet-coord/oz4-oci-incusos-verdict.md`;
  `linux-research/incusos-spike/runs/20260725-oz4-oci/evidence/`.
- **2026-07-25 (OZ-4 OCI delivery on TrueNAS SCALE):** the same OCI image
  (`oz4-delivery:latest`) was launched as a default unprivileged Incus
  container on TrueNAS SCALE 25.04.2.4. The entrypoint auto-fired the import
  ioctl, but the host kernel could not open the container-relative file vdev
  (`/opt/d77.img`), so the OZ-4 overflow never fired (**BLOCKED**). This
  refines the prior TrueNAS host-side **VIABLE** verdict: the overflow is
  reachable from a host path, but not from a self-contained OCI image in a
  default container. Full verdict and evidence:
  `linux-research/.fleet-coord/oz4-oci-truenas-verdict.md`;

`linux-research/appliance-harness/truenas-scale/runs/20260725T190000Z/evidence/`.
- **2026-07-25 (OZ-4 on TrueNAS):** the Dynamically tested appliances table
  gains an **OZ-4 column**. TrueNAS SCALE 25.04.2.4 (running OpenZFS
  `2.3.0-1`) is **VIABLE** for OZ-4 from the default unprivileged container:
  the armed dnode-bonus pool imported ONLINE with no error erevent
(oversized
  `dn_bonuslen` accepted, not rejected) on the production non-KASAN kernel,
  and the same image fired `Write of size 1024 in dbuf_read_impl` via
  `spa_tryimport` under KASAN. The kernel survives the corruption; a
  container→root shell is not demonstrated (neighbor-lottery + KASLR, as in
  the 77b campaign). Proxmox VE and Unraid OZ-4 cells are marked
**BLOCKED** by
  default pending their sibling fleet validation tasks. Full verdict and
  evidence path: `linux-research/.fleet-coord/oz4-truenas-verdict.md`.
- **2026-07-25 (OZ-4 OCI delivery, round 2 — VALIDATED on TrueNAS SCALE and
  Unraid):** the malicious-OCI-image vector is upgraded from **BLOCKED** to
  **VALIDATED** on two appliances. The round-1 blocker was that the host
  kernel's `vdev_file_open` resolves vdev paths in the host mount namespace,
  so a container-internal `/opt/d77.img` is never opened. Round 2 defeats
this
  with an **identical-path host bind mount** (the image entrypoint stages
its
  embedded armed pool onto a bind-mounted host path visible at the same
  absolute path in both namespaces, then imports from that path). On
**TrueNAS
  SCALE 25.04.2.4** the vector fires from a **default unprivileged** Incus
  container (no `security.privileged`, no explicit device add — only the
  default `/dev/zfs`, an identical-path `disk` bind, and a `1777` host
staging
  path): the armed import **panicked the production kernel** (GPF in
  `__kmalloc` on the `spa_tryimport → spa_config_generate` path, crashing
task
  `Comm: zpool` as the container's mapped uid in `ZFS_IOC_POOL_TRYIMPORT`),
  while the structurally identical clean control imported ONLINE. On
**Unraid
  7.3.0** the image-carried payload fires via `docker run --privileged` (the
  required and sufficient capability); the negative control showed the bind
  mount is not even required under Unraid's `vfs` storage driver. The Unraid
  result is **expected behavior** — a `--privileged` container holds full
host
  capabilities by design — and is retained for matrix completeness only; it
is
  not scored as a finding. The TrueNAS round-2 fire is the significant
result,
  but note its two deployment concessions: an identical-path host bind and a
  world-writable host staging path must be granted to the container (as an
app
  manifest's hostPath grant would provide). The Unraid kernel survives
(silent
  corruption → `insufficient replicas`); the TrueNAS
  crash is a **reliable image-delivered container→host-kernel DoS** — no
heap
  grooming required. IncusOS remains **BLOCKED** for this vector (shell-less
  appliance; no host bind-mount escape hatch). Full verdicts and evidence:
  `linux-research/.fleet-coord/oz4-oci-truenas2-verdict.md`,
  `linux-research/.fleet-coord/oz4-oci-unraid-verdict.md`;

`linux-research/appliance-harness/truenas-scale/runs/20260725T193000Z/evidence/`,
  `linux-research/appliance-harness/unraid/runs/20260725T194343Z/evidence/`.
- **2026-07-26 (OZ-4 OCI on IncusOS, round 2 — VALIDATED with ZERO host-side
  setup):** IncusOS flips from the fleet's only **BLOCKED** to
**VALIDATED**,
  and the malicious-OCI-image vector now has a no-setup fire. The round-1
  blocker (host kernel resolves vdev paths in the host mount namespace;
  shell-less appliance precludes an admin bind mount) is defeated **without
  any bind**: the container's own rootfs necessarily exists on the host at
the
  predictable path
`/var/lib/incus/storage-pools/local/containers/<ct>/rootfs/`,
  so the image's payload at `/opt/d77.img` is host-resolvable by
construction.
  A malicious OCI image launched as a **default unprivileged** container
  (default profile only — no `security.privileged`, no device add, no bind)
  carries a static raw `ZFS_IOC_POOL_TRYIMPORT` PoC (hand-packed nvlist,
  libzfs bypassed; `linux-research/incusos-spike/oz4-tryimport.c`,
zg-poolop.c
  lineage) pointed at that host path; the ioctl is issued by **non-root uid
  1000**, authorized via an image-controlled file capability
  (`cap_sys_admin+ep` on the payload binary — an attacker image property,
not
  an admin concession; verified differentially: cap cleared → `EPERM`). The
  armed import **wedges the host kernel's ZFS load path and storage stack**
  (`incusd` unresponsive, ioctl never returns; reproduced on a fresh
kernel),
  while the structurally identical clean control imports in <1s. Negative
  controls (wrong path, nonexistent path, cleared cap) all fail as expected.
  On this kernel the overflow surfaces as a **wedge/storage-DoS** rather
than
  TrueNAS's instant GPF-panic (heap-layout dependent); no root shell is
  claimed. Attacker preconditions: get the victim to launch the image as a
  default container; knowledge of the container name; nothing else. Full
  verdict and evidence:
  `linux-research/.fleet-coord/oz4-oci-incusos2-verdict.md`;
  `linux-research/incusos-spike/runs/20260726-oz4-oci2/evidence/`.
- **2026-07-26 (OZ-4 OCI on TrueNAS SCALE, round 3 — VALIDATED with ZERO
  host-side setup, kernel panic):** the zero-wire rootfs-path vector fires
on
  TrueNAS SCALE 25.04.2.4 as well, upgrading round 2's concession-laden
fire.
  A malicious OCI image launched as a **default unprivileged** Incus
container
  (dir storage backend, default profile only — no privileged flag, no device
  add, no bind, no host shell) carries the armed pool at `/opt/d77.img`, a
  static raw-ioctl PoC (`oz4ti`, zg-poolop/xpl-107-poolop lineage), and a
  **NATIVE-encoded** config nvlist naming the host-side rootfs path

(`/var/lib/incus/storage-pools/default/containers/<name>/rootfs/opt/d77.img`,
  fully derivable from appliance defaults + the attacker-chosen container
  name). The import is issued by a **non-root** nested-userns user (host
  `UID: 2147001001`). The armed import **panicked the production kernel**
  (GPF in `__kmalloc` on `spa_tryimport → spa_load →
  spa_ld_load_special_directories`, corrupted SLUB freelist; crashing task
  `Comm: oz4ti`), while the structurally identical clean control imported
  `rc=

References

Raw JSON
{
  "containers": {
    "cna": {
      "affected": [
        {
          "product": "Linux open",
          "vendor": "Openzfs",
          "versions": [
            {
              "status": "affected",
              "version": "unknown"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Erica Windisch"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "I am hopeful that upstream patches and remediation guidance will be\navailable soon. I have been sitting on these for a bit, and have run this\nthrough AI services hosted in Singapore and the United States, and had\nnotified CERT on 8/12/2026. In order to minimize the risk of asymmetric\nknowledge of these threats being used against defenders, I am opting for\nfull-disclosure.\n\nCheers from HOPE\n\n--Bird\n\n## Report metadata\n\n- **Product:** OpenZFS on Linux (`spl.ko` and `zfs.ko`; out-of-tree and not\n  part of the Linux kernel source tree)\n- **OpenZFS revision audited:** `9b7642df931a765509403318553f2910daf71305`\n  (development version `2.4.99-1`, commit title \"Harden recv record\nvalidation\")\n- **Linux validation kernel:** `7.2.0-rc3-00275-gaf5e34a41cd6`\n- **Validation environments:** disposable QEMU guest with generic KASAN and\n  `CONFIG_KASAN_VMALLOC=y`; a stock IncusOS appliance guest for\n  deployment-level authorization/volume-swap validation; disposable QEMU\n  appliance VMs for Proxmox VE, TrueNAS SCALE, and Unraid dynamic\nreachability\n  testing. Release-mode OpenZFS modules unless stated otherwise.\n- **Research dates:** 2026-07-17 through 2026-07-25\n- **Report updated:** 2026-07-25\n- **Reporter:** Erica Windisch\n- **Tracker umbrella:** [issue #26](\nhttps://github.com/ewindisch/linux-research-tracker/issues/26)\n\nAll kernel execution used disposable QEMU/cloud-hypervisor guests — the\nKASAN\nresearch guest or the stock IncusOS appliance guest. Host-side work was\nlimited\nto building, offline image construction, and driving those guests.\n\n### Revision notes\n\n- **2026-07-25 (validation-chain results):** OZ-3c and OZ-6 move from\n  **LIKELY** to **VALIDATED** with dynamic triggers in the KASAN guest\n  (OZ-3c: UBSAN array-index-out-of-bounds at `zfs_replay.c:115`; OZ-6: KASAN\n  null-ptr-deref in `vdev_is_concrete` and slab-out-of-bounds in\n  `spa_ld_log_sm_cb`). QNAP QZFS static analysis validates\nZ1/Z2/dnode-bonus S3\n  and gang overrun, and BLOCKS log-spacemap S4 (feature absent). The\nupstream\n  patch audit confirms every OZ finding remains **UNFIXED** at upstream\nmaster\n  HEAD `3020c18c` (2026-07-24); only OZ-7 has an open, contested PR\n(#18620).\n  Full audit:\n[`research/upstream-patch-audit.md`](../research/upstream-patch-audit.md).\n- **2026-07-25 (OZ-4 on Proxmox VE):** the Proxmox VE 8.x OZ-4 cell is\nupgraded\n  from provisional to a confirmed dynamic verdict. On `6.8.12-37-pve` /\n  OpenZFS `2.2.10-pve1`, importing the armed dnode-bonus pool (`dn_bonuslen=\n  0x400`, `zfs-77-d77-s3v2.img`) **from inside the delegated LXC container**\n  (CT100 with the OZ-1 verified `/dev/zfs` passthrough) fired the\n  `dbuf_read_bonus` overflow on `spa_tryimport → spa_load →\n  spa_ld_trusted_config` and crashed the kernel (NULL-deref in `strcmp`\nduring\n  `vdev_open_children_impl`; host-side corroboration showed SLUB\n`LIST_POISON`\n  heap corruption in `dbuf_sync_list`). OZ-4 is therefore **VIABLE from the\n  delegated/privileged container** and **BLOCKED by default** (default\n  unprivileged LXC has no `/dev/zfs`). A container→root shell was not\n  reproduced on the stock appliance (release kernel faults\ndeterministically;\n  no KASLR leak). Full verdict and evidence:\n  `linux-research/.fleet-coord/oz4-proxmox-verdict.md`;\n\n`linux-research/appliance-harness/proxmox-ve/runs/20260725T150254Z/evidence/`.\n- **2026-07-25 (OZ-4 on Unraid):** the Unraid 7.3.0 OZ-4 cell is upgraded\nfrom\n  provisional to a confirmed dynamic verdict. On `6.18.29-Unraid` / OpenZFS\n  `2.4.1-1`, importing the inflated-bonus pool (`dn_bonuslen=0x1000`,\n  `zfs-77-d77-s3v3.img`) from a `--privileged` Docker container fails\n  `insufficient replicas` while the structurally identical clean control\n  imports ONLINE; the kernel survives (silent heap corruption, no\npanic/Oops).\n  OZ-4 is therefore **VIABLE from `--privileged`** and **BLOCKED** by\ndefault\n  and `--device /dev/zfs` (no `/dev/zfs` / no `CAP_SYS_ADMIN`). A\ncontainer→root\n  shell was not pursued (requires heap grooming + KASLR bypass). Full\nverdict\n  and evidence: `linux-research/.fleet-coord/oz4-unraid-verdict.md`;\n  `linux-research/appliance-harness/unraid/runs/20260725T150925Z/evidence/`.\n- **2026-07-25 (OZ-4 OCI delivery on IncusOS):** an OCI image\n  (`oz4-delivery:latest`) carrying the armed pool (`d77.img`) was built with\n  podman, repacked as an Incus image, and launched as a default unprivileged\n  Incus container on IncusOS `202607192224` (OpenZFS `2.4.3-1`). The\ncontainer\n  received `/dev/zfs` and the ioctls were authorized (OZ-1 reachability\n  **VIABLE**), but the host kernel could not open the file vdev at the\n  container-relative path (`/opt/d77.img`), so the OZ-4 overflow never fired\n  (**BLOCKED** for the in-container E2E fire). IncusOS's shell-less design\n  removes the host-side bind-mount escape hatch that made the fire possible\non\n  Proxmox VE. Full verdict and evidence:\n  `linux-research/.fleet-coord/oz4-oci-incusos-verdict.md`;\n  `linux-research/incusos-spike/runs/20260725-oz4-oci/evidence/`.\n- **2026-07-25 (OZ-4 OCI delivery on TrueNAS SCALE):** the same OCI image\n  (`oz4-delivery:latest`) was launched as a default unprivileged Incus\n  container on TrueNAS SCALE 25.04.2.4. The entrypoint auto-fired the import\n  ioctl, but the host kernel could not open the container-relative file vdev\n  (`/opt/d77.img`), so the OZ-4 overflow never fired (**BLOCKED**). This\n  refines the prior TrueNAS host-side **VIABLE** verdict: the overflow is\n  reachable from a host path, but not from a self-contained OCI image in a\n  default container. Full verdict and evidence:\n  `linux-research/.fleet-coord/oz4-oci-truenas-verdict.md`;\n\n`linux-research/appliance-harness/truenas-scale/runs/20260725T190000Z/evidence/`.\n- **2026-07-25 (OZ-4 on TrueNAS):** the Dynamically tested appliances table\n  gains an **OZ-4 column**. TrueNAS SCALE 25.04.2.4 (running OpenZFS\n  `2.3.0-1`) is **VIABLE** for OZ-4 from the default unprivileged container:\n  the armed dnode-bonus pool imported ONLINE with no error erevent\n(oversized\n  `dn_bonuslen` accepted, not rejected) on the production non-KASAN kernel,\n  and the same image fired `Write of size 1024 in dbuf_read_impl` via\n  `spa_tryimport` under KASAN. The kernel survives the corruption; a\n  container→root shell is not demonstrated (neighbor-lottery + KASLR, as in\n  the 77b campaign). Proxmox VE and Unraid OZ-4 cells are marked\n**BLOCKED** by\n  default pending their sibling fleet validation tasks. Full verdict and\n  evidence path: `linux-research/.fleet-coord/oz4-truenas-verdict.md`.\n- **2026-07-25 (OZ-4 OCI delivery, round 2 — VALIDATED on TrueNAS SCALE and\n  Unraid):** the malicious-OCI-image vector is upgraded from **BLOCKED** to\n  **VALIDATED** on two appliances. The round-1 blocker was that the host\n  kernel's `vdev_file_open` resolves vdev paths in the host mount namespace,\n  so a container-internal `/opt/d77.img` is never opened. Round 2 defeats\nthis\n  with an **identical-path host bind mount** (the image entrypoint stages\nits\n  embedded armed pool onto a bind-mounted host path visible at the same\n  absolute path in both namespaces, then imports from that path). On\n**TrueNAS\n  SCALE 25.04.2.4** the vector fires from a **default unprivileged** Incus\n  container (no `security.privileged`, no explicit device add — only the\n  default `/dev/zfs`, an identical-path `disk` bind, and a `1777` host\nstaging\n  path): the armed import **panicked the production kernel** (GPF in\n  `__kmalloc` on the `spa_tryimport → spa_config_generate` path, crashing\ntask\n  `Comm: zpool` as the container's mapped uid in `ZFS_IOC_POOL_TRYIMPORT`),\n  while the structurally identical clean control imported ONLINE. On\n**Unraid\n  7.3.0** the image-carried payload fires via `docker run --privileged` (the\n  required and sufficient capability); the negative control showed the bind\n  mount is not even required under Unraid's `vfs` storage driver. The Unraid\n  result is **expected behavior** — a `--privileged` container holds full\nhost\n  capabilities by design — and is retained for matrix completeness only; it\nis\n  not scored as a finding. The TrueNAS round-2 fire is the significant\nresult,\n  but note its two deployment concessions: an identical-path host bind and a\n  world-writable host staging path must be granted to the container (as an\napp\n  manifest's hostPath grant would provide). The Unraid kernel survives\n(silent\n  corruption → `insufficient replicas`); the TrueNAS\n  crash is a **reliable image-delivered container→host-kernel DoS** — no\nheap\n  grooming required. IncusOS remains **BLOCKED** for this vector (shell-less\n  appliance; no host bind-mount escape hatch). Full verdicts and evidence:\n  `linux-research/.fleet-coord/oz4-oci-truenas2-verdict.md`,\n  `linux-research/.fleet-coord/oz4-oci-unraid-verdict.md`;\n\n`linux-research/appliance-harness/truenas-scale/runs/20260725T193000Z/evidence/`,\n  `linux-research/appliance-harness/unraid/runs/20260725T194343Z/evidence/`.\n- **2026-07-26 (OZ-4 OCI on IncusOS, round 2 — VALIDATED with ZERO host-side\n  setup):** IncusOS flips from the fleet's only **BLOCKED** to\n**VALIDATED**,\n  and the malicious-OCI-image vector now has a no-setup fire. The round-1\n  blocker (host kernel resolves vdev paths in the host mount namespace;\n  shell-less appliance precludes an admin bind mount) is defeated **without\n  any bind**: the container's own rootfs necessarily exists on the host at\nthe\n  predictable path\n`/var/lib/incus/storage-pools/local/containers/<ct>/rootfs/`,\n  so the image's payload at `/opt/d77.img` is host-resolvable by\nconstruction.\n  A malicious OCI image launched as a **default unprivileged** container\n  (default profile only — no `security.privileged`, no device add, no bind)\n  carries a static raw `ZFS_IOC_POOL_TRYIMPORT` PoC (hand-packed nvlist,\n  libzfs bypassed; `linux-research/incusos-spike/oz4-tryimport.c`,\nzg-poolop.c\n  lineage) pointed at that host path; the ioctl is issued by **non-root uid\n  1000**, authorized via an image-controlled file capability\n  (`cap_sys_admin+ep` on the payload binary — an attacker image property,\nnot\n  an admin concession; verified differentially: cap cleared → `EPERM`). The\n  armed import **wedges the host kernel's ZFS load path and storage stack**\n  (`incusd` unresponsive, ioctl never returns; reproduced on a fresh\nkernel),\n  while the structurally identical clean control imports in <1s. Negative\n  controls (wrong path, nonexistent path, cleared cap) all fail as expected.\n  On this kernel the overflow surfaces as a **wedge/storage-DoS** rather\nthan\n  TrueNAS's instant GPF-panic (heap-layout dependent); no root shell is\n  claimed. Attacker preconditions: get the victim to launch the image as a\n  default container; knowledge of the container name; nothing else. Full\n  verdict and evidence:\n  `linux-research/.fleet-coord/oz4-oci-incusos2-verdict.md`;\n  `linux-research/incusos-spike/runs/20260726-oz4-oci2/evidence/`.\n- **2026-07-26 (OZ-4 OCI on TrueNAS SCALE, round 3 — VALIDATED with ZERO\n  host-side setup, kernel panic):** the zero-wire rootfs-path vector fires\non\n  TrueNAS SCALE 25.04.2.4 as well, upgrading round 2's concession-laden\nfire.\n  A malicious OCI image launched as a **default unprivileged** Incus\ncontainer\n  (dir storage backend, default profile only — no privileged flag, no device\n  add, no bind, no host shell) carries the armed pool at `/opt/d77.img`, a\n  static raw-ioctl PoC (`oz4ti`, zg-poolop/xpl-107-poolop lineage), and a\n  **NATIVE-encoded** config nvlist naming the host-side rootfs path\n\n(`/var/lib/incus/storage-pools/default/containers/<name>/rootfs/opt/d77.img`,\n  fully derivable from appliance defaults + the attacker-chosen container\n  name). The import is issued by a **non-root** nested-userns user (host\n  `UID: 2147001001`). The armed import **panicked the production kernel**\n  (GPF in `__kmalloc` on `spa_tryimport → spa_load →\n  spa_ld_load_special_directories`, corrupted SLUB freelist; crashing task\n  `Comm: oz4ti`), while the structurally identical clean control imported\n  `rc="
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-09-11T11:49:48Z",
        "orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
        "shortName": "VULNARCHIVE"
      },
      "references": [
        {
          "tags": [
            "technical-description",
            "exploit"
          ],
          "url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Aug/40"
        },
        {
          "tags": [
            "technical-description"
          ],
          "url": "https://seclists.org/fulldisclosure/2026/Aug/40"
        },
        {
          "url": "https://docs.qnap.com/operating-system/quts-hero/5.1.x/en-us/about-quts-hero-CAAE5DD0.html"
        },
        {
          "url": "https://documentation.ubuntu.com/lxd/latest/howto/initialize/"
        },
        {
          "url": "https://documentation.ubuntu.com/lxd/latest/reference/storage_zfs/"
        },
        {
          "url": "https://github.com/ewindisch/linux-research-tracker/issues/26"
        },
        {
          "url": "https://kernel.org/doc/html/next/process/threat-model.html"
        },
        {
          "url": "https://linuxcontainers.org/incus/docs/main/reference/devices_unix_char/"
        },
        {
          "url": "https://man7.org/linux/man-pages/man7/udev.7.html"
        },
        {
          "url": "https://nixos.org/manual/nixos/stable/"
        },
        {
          "url": "https://nixos.org/manual/nixos/stable/options"
        },
        {
          "url": "https://nmap.org/mailman/listinfo/fulldisclosure"
        },
        {
          "url": "https://openzfs.github.io/openzfs-docs/Getting%20Started/Alpine%20Linux/index.html"
        },
        {
          "url": "https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/index.html"
        },
        {
          "url": "https://openzfs.github.io/openzfs-docs/Getting%20Started/index.html"
        },
        {
          "url": "https://packages.debian.org/trixie/zfs-dkms"
        },
        {
          "url": "https://pbs.proxmox.com/docs/installation.html"
        },
        {
          "url": "https://pbs.proxmox.com/docs/sysadmin.html#zfs-on-linux"
        },
        {
          "url": "https://raw.githubusercontent.com/openzfs/zfs/master/udev/rules.d/90-zfs.rules.in"
        },
        {
          "url": "https://seclists.org/fulldisclosure/"
        },
        {
          "url": "https://wiki.alpinelinux.org/wiki/ZFS"
        },
        {
          "url": "https://wiki.ubuntu.com/Kernel/Reference/ZFS"
        },
        {
          "url": "https://www.first.org/cvss/v3.1/specification-document"
        },
        {
          "url": "https://www.first.org/cvss/v4.0/specification-document"
        },
        {
          "url": "https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#device-controller"
        },
        {
          "url": "https://www.kernel.org/doc/html/latest/process/cve.html"
        },
        {
          "url": "https://www.qnap.com/en-us/how-to/faq/article/why-should-i-avoid-using-raw-zfs-cli-commands-on-my-quts-hero-nas"
        }
      ],
      "source": {
        "defect": [
          "https://seclists.org/fulldisclosure/2026/Aug/40"
        ],
        "discovery": "EXTERNAL"
      },
      "title": "OpenZFS Linux open zpool manipulation and escapes via unprivileged userns",
      "x_gcve": [
        {
          "recordType": "advisory",
          "relationships": [],
          "vulnId": "GCVE-1988-2026-0098",
          "x_vulnarchive": {
            "archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Aug/40",
            "automated": true,
            "contentSha256": "3e93a580885da758a6b60cad4fcaddf02d82917807680d207d1ed45e0a793d55",
            "evidenceScore": 10,
            "messageId": "",
            "originalUrl": "https://seclists.org/fulldisclosure/2026/Aug/40",
            "policy": "vulnarchive-1",
            "sourceFormat": "text/html",
            "sourcePublishedAt": "2026-08-16T18:31:49Z"
          }
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
    "assignerShortName": "VULNARCHIVE",
    "datePublished": "2026-09-07T13:20:22Z",
    "dateUpdated": "2026-09-11T11:49:48Z",
    "state": "PUBLISHED",
    "vulnId": "GCVE-1988-2026-0098"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}