# DF-0165 — PoC evidence pack

## What this is

Demonstrates that `caps_priv_check()` in `sys/kern/kern_caps.c:333-340`
mutates its `cap` argument from the specific capability (e.g.
`SYSCAP_NONET_RAW = 0x61`) to its group-master number (`SYSCAP_NONET = 6`)
before forwarding it to `prison_priv_check()`, which has
`case SYSCAP_NONET: return 0` and `case SYSCAP_NOMOUNT: return 0`. The
per-capability switch arms that actually consult the jail policy flags
are dead code on this path. Result: a jailed root can do raw socket
creation and tmpfs/nullfs/devfs/procfs mounts that the jail policy
explicitly forbids.

See `VERDICT.md` for the full mechanism walkthrough and the line-by-line
trace.

## Reproduce

```sh
./build.sh        # cc -O2 -Wall -o bypass bypass.c
./run.sh          # creates jail with default policy, tries gated actions
```

Must be run as **root** on the guest (the test creates+enters a jail).
`run.sh` first echoes the jail default-policy sysctls (proving they are
all 0 / restrictive), then runs `./bypass`.

## Expected output

```
jail() ok: jid=N  (now jailed as uid=0)
=== DF-0165 demo: cap-gated actions inside jail ===
    (jail default policy: allow_raw_sockets=0,
     vfs_mount_{nullfs,tmpfs,devfs,procfs}=0 -> all should EPERM)
  socket(AF_INET, SOCK_RAW, IPPROTO_RAW)  [SYSCAP_NONET_RAW]
      -> OK fd=3   *** BYPASS ***
  mount("tmpfs",  ...)  [SYSCAP_NOMOUNT_TMPFS]   -> OK   *** BYPASS ***
  mount("null",   ...)  [SYSCAP_NOMOUNT_NULLFS]  -> OK   *** BYPASS ***
  mount("devfs",  ...)  [SYSCAP_NOMOUNT_DEVFS]   -> OK   *** BYPASS ***
  mount("procfs", ...)  [SYSCAP_NOMOUNT_PROCFS]  -> OK   *** BYPASS ***
=== end: 5 cap-gated action(s) bypassed jail policy ===
```

On a **fixed** kernel every action returns `EPERM` instead of `OK`.

## Why the PoC was rewritten

The original (per-finding) PoC snippet was a 4-line shell pseudocode
("from jailed root, run mount/socket"). I implemented it as a real C
program (`bypass.c`) that:

- creates the jail itself (no separate `jail(8)` setup needed),
- attaches via `jail(2)` (which auto-attaches per
  `kern_jail_attach` at `sys/kern/kern_jail.c:227`),
- drives each gated action and reports `OK / EPERM` per action.

Notable gotcha worth recording: the kernel's nullfs fstype is `"null"`,
not `"nullfs"` — `get_fscap()`'s `strncmp("null", fsname, 5)` only matches
the bare name. Using `mount("nullfs", ...)` makes the syscall hit a
different (default) cap and fail for an unrelated reason; using
`mount("null", ...)` exercises the actual `SYSCAP_NOMOUNT_NULLFS` path
and demonstrates the bypass cleanly.
