DF-0136 — varsym_list(VARSYM_SYS) jail isolation breach
========================================================

## Verdict: REPRODUCED (jail info-leak / isolation breach)

## Mechanism

`sys_varsym_list()` (`sys/kern/kern_varsym.c:225`) selects the varsym set to
enumerate based on `uap->level`. For `VARSYM_SYS` it unconditionally picks the
**host-global** `varsymset_sys` with **no jail check** (`kern_varsym.c:263-264`):

```c
case VARSYM_SYS:
    vss = &varsymset_sys;          /* <-- host-global, no jail redirect */
    break;
```

This is inconsistent with the two sibling paths, which DO scope a jailed
process to its prison varsymset:

* `sys_varsym_set()` (`:152-156`): redirects `VARSYM_SYS -> VARSYM_PRISON`
  (`level = VARSYM_PRISON`) when `td->td_ucred->cr_prison != NULL`.
* `varsymfind()` (`:400-408`, used by `varsym_get` / namei): for the
  `VARSYM_SYS_MASK` lookup, if jailed it searches
  `td->td_ucred->cr_prison->pr_varsymset` instead of `varsymset_sys`.

So `varsym_list` is the **only** varsym path where a jailed process reaches the
host-global `varsymset_sys`.

## Proof

A process placed inside a jail (via the `jail` command) enumerates the host's
system varsyms — including a marker `DF0136_HOSTSECRET=secretvalue` set on the
host by root — via `varsym_list(VARSYM_SYS)`, while the jail-scoped
`varsym_get(VARSYM_SYS_MASK)` correctly does NOT find it:

```
[*] jail.jailed = 1
[*] varsym_list(VARSYM_SYS) enumeration:
  *** LEAKED: DF0136_HOSTSECRET=secretvalue ***
[*] varsym_list(VARSYM_SYS) enumerated 126 system varsyms from inside the jail
[*] varsym_get(DF0136_HOSTSECRET) not found (rc=-1, No such file or directory) — get-path correctly jail-scoped
RESULT: LEAK_CONFIRMED — host system varsyms are enumerable from inside a jail via varsym_list(VARSYM_SYS)
```

## Impact / realism

* Realistic precondition: an admin sets system varsyms (e.g. `rcng_*` already
  populate them on this guest) and runs a jail. The jailed tenant — even an
  unprivileged user inside the jail — enumerates **all** host system varsym
  names and values. This is a host->jail information-disclosure / jail
  isolation breach.
* Non-corruption class (info leak / isolation). No privesc chain.

## Fix

`fix.diff`: in `sys_varsym_list`, redirect `VARSYM_SYS` to the prison
varsymset when jailed, mirroring `varsymfind()` `:400-408` / `sys_varsym_set()`
`:153-155`. Supersedes (specifies) the finding's proposal — same intent, exact
patch.

## Reproduce

* host:   `varsym -s DF0136_HOSTSECRET=secretvalue`
* build:  `cc -o leak_check leak_check.c`
* run:    `jail <path> <host> <ip> /path/to/leak_check`
* scripts: `./build.sh && ./run.sh` (run.sh does setup + jail as root)
