# DF-5135 — TUNABLE_bool stores 4 bytes into 1-byte _Bool i915 params,
# silently corrupting the neighbouring parameters

`sys/dev/drm/include/linux/moduleparam.h:41`:

```c
#define TUNABLE_bool(name, var)		TUNABLE_INT( _TUNABLE_VAR(.name), (int *)&(var))
```

`bool` is `_Bool` — **1 byte** (sys/sys/stdint.h:58). `TUNABLE_INT` +
`tunable_int_init()` → `kgetenv_int()` performs `*data = (int)tmp` — a
**4-byte store** through that cast (kern_environment.c:379-389, 527-533).
Every `i915_param_named(..., bool, ...)` in `sys/dev/drm/i915/i915_params.c`
instantiates this macro on a member of `struct i915_params`, so setting one
bool tunable overwrites the three following struct members (all further
bools; the layout keeps bools at the tail, and the last bool's write ends in
the struct's padding, so the corruption stays inside the object — a
correctness/security-configuration bug and a latent landmine, not a past-the-
object overflow on this struct).

Bonus discovery (guest-verified): the registered tunable *names* are
mangled. The shipped i915.ko registers bool tunables as
`KBUILD_MODNAME.<name>` (and the `module_param_named_unsafe` ones as
`KBUILD_MODNAME.(<name>)` — with parentheses), because `-DKBUILD_MODNAME`
never reaches i915_params.c. The int params dodge this because
i915_params.c:43-127 adds explicit `TUNABLE_INT("drm.i915.*")` lines; the
bools (and the charp paths, whose `TUNABLE_charp` shim is a no-op) have no
working name at all except the mangled ones.

## Live reproduction (audit guest, stock i915.ko)

```
kenv KBUILD_MODNAME.verbose_state_checks=1
kldload i915                    # tunable fetch happens at module SYSINIT
kldload ./i915probe.ko          # dumps the real i915_modparams tail bytes
sysctl hw.i915probe.params
```

`verbose_state_checks` sits at offset 112; `enable_dp_mst` (default **true**)
at 114. The 4-byte store of `1` writes bytes 112..115 → `enable_dp_mst` is
silently flipped 1→0:

```
dmabug:   error_capture=1  disable_display=0  verbose_state_checks=1  nuclear_pageflip=0
dmabug:   enable_dp_mst=0 enable_dpcd_backlight=0 enable_gvt=0   <-- dp_mst corrupted (default is 1)
```

Baseline (no kenv var): `enable_dp_mst=1`.

Layout proof (`cc -o layout layout.c; ./layout`):

```
sizeof(bool)=1 sizeof(struct i915_params)=120
offsets: error_capture=110 disable_display=111 verbose_state_checks=112
         nuclear_pageflip=113 enable_dp_mst=114 enable_gvt=116(last)
after 'i915.error_capture=1': error_capture=1 disable_display=0
         verbose_state_checks=0 nuclear_pageflip=0  (0xAA bytes overwritten to 0)
```

## Fix validation

`fix.diff` replaces `TUNABLE_bool` with a SYSINIT helper that fetches into
an `int` and narrows the store (`(var) = !!__tv`). Rebuilt i915.ko on the
guest, rebooted, re-ran the exact kenv sequence:

```
dmabug:   verbose_state_checks=1  ...
dmabug:   enable_dp_mst=1 enable_dpcd_backlight=0 enable_gvt=0   <-- intact
```
