# DF-2773 — `link_elf_obj_unload_file` NULL-deref when load aborts between scan and allocation

## Build (host)
```
python3 gen_module.py df2773.ko nrel-nullderef
```

## Run (guest, root — kldload is SYSCAP_NOKLD-gated)
```
scp -F dfbsd-qemu/config df2773.ko dfbsd:/tmp/
dfbsd-qemu/vm.sh run_root 'kldload /tmp/df2773.ko'
```

## Expected — stock kernel (baseline, reproduced)
Serial console (panic.txt):
```
kldload: /tmp/df2773.ko: file has no contents
Fatal trap 12: page fault while in kernel mode
fault virtual address = 0x0
fault code = supervisor read data, page not present
Stopped at link_elf_obj_unload_file+0x6e: movq (%rax),%rdi
```
The scan loop (link_elf_obj.c:517-539) increments `ef->nreltab`/`nrelatab`
*before* the tracking arrays are allocated (:557-572). A module with zero
PROGBITS/NOBITS sections (or `nsym != 1`, or bad symstrindex) takes
`goto out` (:540/:545/:551) → `linker_file_unload` tears the fresh file down
through `ops->unload` (kern_linker.c:549) → `link_elf_obj_unload_file`
executes `for (i = 0; i < ef->nrelatab; i++) if (ef->relatab[i].rela)`
(:890-892) with `relatab == NULL` → read at address 0x0 → panic.

## Expected — patched kernel (fix.diff applied, kernel #1 Sep 1 2026)
```
kldload: an error occurred while loading module /tmp/df2773.ko ...
RC=1
dmesg: linker_load_file: Unsupported file type
```
(The module now dies even earlier — scan-time sh_info validation — and the
unload guard `if (ef->reltab)`/`if (ef->relatab)` closes the NULL-deref for
every other abort path.)

## Threat model
Root-supplied-input class (SYSCAP_NOKLD), like DF-0040/0041/0042.
