# DF-0337 PoC — tcp_pcblist info leak

## Build
```
cc -o leak_pcblist leak_pcblist.c
```

## Run (as unprivileged user)
```
./leak_pcblist
```

## Expected output (bug present)
```
pcblist total bytes: 5480
records: 5
LEAK: 113 kernel-pointer-sized words in pcblist output
VERDICT: LEAK CONFIRMED (113 kernel pointers exposed to unpriv user)
```

## Expected output (after fix)
```
pcblist total bytes: 5480
records: 5
LEAK: 0 kernel-pointer-sized words in pcblist output
VERDICT: no kernel pointers found
```

## How it works

The PoC opens a TCP socket (to ensure at least one inpcb is live),
calls `sysctlbyname("net.inet.tcp.pcblist", ...)` to fetch the raw
`struct xtcpcb` array, then scans every 8-byte word for values that
fall in the DragonFly kernel pointer range
(`0xffffffff80000000+` text/data, `0xfffff80000000000+` heap).

The `struct xtcpcb` contains `struct inpcb` + `struct tcpcb` +
`struct xsocket` which together hold ~30 kernel pointer fields.
`tcp_pcblist()` `bcopy()`s the raw structs without sanitization,
leaking all of them to any user.

## Files
- `leak_pcblist.c` — the PoC source
- `offsets.c` — struct field offset helper (used during analysis)
- `fix.diff` — the verified fix (pointer sanitization)
