# DF-2812 — elf_lookup() STB_LOCAL branch returns the resolved address as the int error code; *result never written → local-symbol relocations always fail (or write an uninitialized stack value)

## Build
```
python3 gen_exec_ko.py globalsym.ko globalsym   # control: STB_GLOBAL symbol
python3 gen_exec_ko.py localsym.ko  localsym    # test:    STB_LOCAL symbol
```
The two modules are byte-identical except for one field: the st_info bind
of the single in-module symbol "s" (defined: st_shndx=1, st_value=0x80)
referenced by one R_X86_64_64 relocation.

## Run
```
scp -F dfbsd-qemu/config globalsym.ko localsym.ko dfbsd:/tmp/
dfbsd-qemu/vm.sh run_root 'kldload /tmp/globalsym.ko; echo GLOBAL_RC=$?; kldunload -n /tmp/globalsym.ko'
dfbsd-qemu/vm.sh run_root 'kldload /tmp/localsym.ko; echo LOCAL_RC=$?'
dfbsd-qemu/vm.sh log 10       # console shows the failure message
```

## Expected / observed (stock kernel, verified 2026-09-01)
```
globalsym: GLOBAL_RC=0  (loads; kldstat shows mapsize 0x1000; unloads fine)
localsym : link_elf: symbol s undefined      <- console
           kldload: an error occurred while loading module ... (RC=1)
```

## Expected (patched kernel)
```
localsym : LOCAL_RC=0   (the defined local symbol now resolves)
```

## Why (root cause, sys/kern/link_elf.c)
`elf_lookup_fn` (sys/sys/linker.h:327) is
`typedef int elf_lookup_fn(linker_file_t, Elf_Size, int, Elf_Addr *)` —
int return = error code, address delivered via *result. The machine
relocation engine (sys/cpu/x86_64/misc/elf_machdep.c:123) does:

```c
if (lookup(lf, symidx, 1, &addr))
        return -1;
val = addr + addend;        /* addr only set on the 0-return path */
```

link_elf.c's elf_lookup honors that contract on the global path (:1022)
but the STB_LOCAL branch is a fossil of the pre-elf_machdep API:

```c
1003:  if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
1005:      if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0)
1006:          return (ENOENT);
1007:      return ((Elf_Addr) ef->address + sym->st_value);   /* address as errno */
1008:  }
```

Consequences:
- kernel-heap pointer truncated to int != 0 → elf_reloc_internal treats it
  as an error → every relocation against a defined STB_LOCAL symbol fails
  → "link_elf: symbol <name> undefined" and the module cannot load
  (this is what the PoC demonstrates);
- on the 1-in-2^32 chance the low 32 bits of (ef->address + st_value) are
  zero, lookup "succeeds" without setting *result, and `val = addr +
  addend` in elf_machdep.c:125 writes an UNINITIALIZED STACK VALUE into
  the relocated word of the module image.

The sibling loader is correct: link_elf_obj.c's elf_obj_lookup
(:1134-1166) writes `*result = ...; return (0);` and its relocate_file
skips locals entirely because link_elf_obj_reloc_local handles them via
the same correctly-converted helper.
