⬢ DragonFlyBSD Kernel Audit
DF-5596 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5596",
  "status": "reproduced",
  "reproduced": true,
  "impact": "none",
  "confidence": "certain",
  "verdict": "genassym.c never emits GD_CURRENTLDT although struct mdglobaldata still has gd_currentldt (globaldata.h:78) and the standard-built global.s:66-67 consumes it via .globl/.set. Proven on the shipped kernel: global.o and /boot/kernel/kernel both carry an undefined GD_CURRENTLDT, the promised gd_currentldt export silently does not exist, zero relocations consume the dangling symbol, and the build never failed -- the genassym C<->asm contract guard is silently defeated for .set-consumed macros under this link configuration. No runtime memory-safety impact today (nothing references the missing symbol); the security relevance is the demonstrated silent-failure mode of the offset-contract enforcement itself. One-line fix validated with the exact kernel build rules: regenerated assym.s gains #define GD_CURRENTLDT 0x42d4 and the consumer probe resolves to an absolute symbol 0x42d4.",
  "exploit_chain": "",
  "evidence": "shipped_kernel_evidence.txt (nm global.o + kernel: U GD_CURRENTLDT, gd_currentldt absent, 0 relocs); nm_probe_unpatched.txt (bug under controlled build); nm_probe_fixed.txt (00000000000042d4 A gd_currentldt_probe); diff.fix_delta.txt (exactly one added define); diff.buildtree_vs_regen.txt (empty: regen identical to build tree); diff.assym_vs_checker.txt (176/176 offsets match independent TU)",
  "kernel_refs": [
    "sys/platform/pc64/x86_64/genassym.c:230-239",
    "sys/platform/pc64/x86_64/global.s:66-67",
    "sys/platform/pc64/include/globaldata.h:78",
    "sys/platform/pc64/conf/files:129",
    "sys/conf/kern.post.mk:73-79",
    "sys/kern/genassym.sh:10-44"
  ],
  "poc_changes": "seed had no runnable PoC; authored probe_gdcl.s (mirrors global.s consumption shape), genassym_fixed.c (one added ASSYM line), offset_check.c (mechanically generated from genassym.c, separate-TU value cross-check). First runner attempt failed (-I. must resolve the kernel build dir; -nostdinc forbids stdio.h) -- fixed by cd $BD and a manual printf declaration; attempts=2.",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 1500,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh  (cc -c $(make -V CFLAGS minus -fno-common) -fcommon genassym.c; sh /usr/src/sys/kern/genassym.sh genassym.o > assym.s; cc -x assembler-with-cpp $(make -V ASM_CFLAGS) -c probe_gdcl.s)",
  "run_cmd": "sh run.sh",
  "code_hash": "b97bf4f254e9d56fdda936519b19f61cdbbb3f9fe12c61d1c9d4aaac6aaa1db8",
  "notes": "Non-corruption finding: targeted same-flags rebuild + probe assemble is the fix validation (full kernel reboot not required). Same silent-vanish mechanism leaves 7 more dangling undefined symbols from locore.s:41-47 (loc_PTmap..loc_PML4pml4e, dmapbase, dmapend -- pmap.h externs nothing defines); that cleanup belongs to locore.s/pmap.h, not genassym.c. vkernel64 global.s:65 has the identical dangling use. Checklist resolved: TF_R10/TF_R11 ARE defined (genassym.c:152-153, consumed exception.S:305-306); all 176 emitted offsets match an independent kernel-CFLAGS TU; zero hardcoded numeric struct displacements in any pc64/cpu .s consumer; MDGLOBALDATA_BASEALLOC_PAGES derives from sizeof in the same header so it cannot drift.",
  "recommended_fix": "Add ASSYM(GD_CURRENTLDT, offsetof(struct mdglobaldata, gd_currentldt)); to genassym.c (fix.diff); optionally also audit-remove the dead locore.s:41-47 aliases.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": true,
  "fix_verdict": "Baseline: probe.o carries U GD_CURRENTLDT and no gd_currentldt definition (assembly+link succeed). Patched (one ASSYM line, identical build flags): assym.s gains exactly #define GD_CURRENTLDT 0x42d4 and probe.o defines absolute gd_currentldt_probe=0x42d4. Bad behavior gone; contract restored.",
  "fix_evidence": "diff.fix_delta.txt, fix_gdcl_value.txt, nm_probe_unpatched.txt, nm_probe_fixed.txt"
}