β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-5716

sys/libkern/flsl.c is dead, unlistable, and shadowed code (find-LAST-set, long)

Summary

Shadowed by the bsrq-based cpufunc.h inline used by all live consumers (incl. kern_slaballoc powerof2_size, which guards size==0/powerof2 before calling - no shift-by-64 misuse). In-kernel compile fails redefinition. Latent body 0/58.45M vs the byte-faithful inline AND 64-__builtin_clzl. gate-or-delete fix validated.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-5716 Β· 17 files
FileTypeDescriptionSize
README.md β€” 2.2 KB ↓ raw
VERDICT.md β€” 4.1 KB ↓ raw
verdict.json β€” 5.4 KB view raw
manifest.json β€” 1.1 KB view raw
p2_harness.c β€” 5.7 KB view raw
build.sh β€” 127 B view raw
run.sh β€” 90 B view raw
k_flsl.c β€” 1.8 KB view raw
f_flsl_gated.c β€” 1.9 KB view raw
build.log β€” 1.8 KB view raw
run.log β€” 463 B view raw
dead_compile_flsl.log β€” 633 B view raw
fix_compile_flsl.log β€” 277 B view raw
fix_build.log β€” 904 B view raw
fix_run.log β€” 454 B view raw
env.txt β€” 212 B view raw
fix.diff β€” 237 B view raw

DF-5716 β€” sys/libkern/flsl.c dead-file status + latent-correctness proof

Pass-2 (GLM 5.3) verification of the flsl (find-LAST-set, long) member of the ffs/fls family (family context established by DF-5714 for ffs.c; rig pattern identical).

What was machine-proven on the DragonFly guest

  1. Dead file: libkern/flsl.c has no entry in sys/conf/files (libkern block 2195–2237; grep -c = 0 on host and guest). Every kernel TU gets flsl as static __inline from sys/cpu/x86_64/include/cpufunc.h:290-296 (HAVE_INLINE_FLSL, bsrq-based).
  2. Cannot compile in-kernel as committed: #include <sys/libkern.h> (flsl.c:32) pulls libkern.h:51 β†’ systm.h:50 β†’ machine/cpufunc.h, and the out-of-line definition at flsl.c:37-47 collides with the static __inline flsl: gcc 8.3 error: redefinition of 'flsl' (dead_compile_flsl.log, kernel-style -nostdinc -D_KERNEL compile).
  3. Latent body is arithmetically perfect: verbatim body vs the live cpufunc.h inline (bsrq asm copied verbatim) and vs 64 - __builtin_clzl: 58,454,211 structure-complete cases (0, ~0, sign word, all 64 single bits, exhaustive low-22 and top-22 patterns, MSB-position sweep Γ—1024, 50M randoms) β€” 0 mismatches (run.log T2).
  4. Fix validated at compile level: fix.diff = #if !defined(HAVE_INLINE_FLSL) gate. Gated file compiles kernel-style and defines no global flsl symbol on x86_64. Deletion equally valid.

Reproduce

Copy this directory to the guest and, as root:

sh build.sh   # identity pin (cksum), conf/files census, verbatim renamed
              # compiles, kernel-style deadproof, fix validation
sh run.sh     # differential harness (~3 s)

Expected decisive lines:

DEADPROOF-OK: flsl.c cannot compile in-kernel as committed: ... error: redefinition of 'flsl'
T2 flsl :   58454211 cases,          0 mism vs live-inline,          0 mism vs clz-ref
HARNESS-PASS: ...
FIXCOMPILE-OK: gated flsl.c compiles kernel-style; global flsl symbols in object: 0

build.sh expects the guest sources at /usr/src/sys (override with S=...). Host/guest source identity: flsl.c cksum 2802750667 1878.

VERDICT.md
↓ download raw

VERDICT β€” DF-5716: sys/libkern/flsl.c dead-file status + latent-correctness proof

Status: reproduced (impact: none β€” dead code, Info-severity hygiene finding). Confidence: certain. Attempts: 2. All claims machine-demonstrated on the DragonFly guest (uname in env.txt; guest source cksum-identical to the audit tree: flsl.c 2802750667 1878, ffsl.c 1444671719 1875, flsll.c 1445885582 1884).

The claim, and how each part was proven

  1. flsl.c is not compiled into any DragonFly kernel or module. - sys/conf/files libkern block (lines 2195–2237) has no flsl.c entry (census in build.log: grep -c = 0, host and guest). - Every kernel TU gets flsl as static __inline from sys/cpu/x86_64/include/cpufunc.h:290-296 (#define HAVE_INLINE_FLSL, body mask == 0 ? mask : (int)bsrq((u_long)mask) + 1); the prototype in sys/sys/libkern.h:111-112 is gated by #ifndef HAVE_INLINE_FLSL.
  2. The file cannot compile in-kernel as committed. flsl.c:32 includes <sys/libkern.h> β†’ libkern.h:51 β†’ systm.h:50 β†’ machine/cpufunc.h brings the static __inline flsl into the TU, and the out-of-line definition (flsl.c:37-47) collides: flsl.c:38:1: error: redefinition of 'flsl' / cpufunc.h:293:1: note: previous definition (dead_compile_flsl.log, kernel-style -nostdinc -D_KERNEL compile per sys/conf/kern.pre.mk:61). Re-adding the file to conf/files would break the x86_64 kernel build.
  3. The latent body is arithmetically perfect β€” find-LAST-set semantics machine-checked. Verbatim kernel body vs (a) the live cpufunc.h inline implementation copied verbatim (bsrq asm from cpufunc.h:119-126 + the :292-296 body) and (b) the 64 - __builtin_clzl reference: 0 / 58,454,211 mismatches (run.log T2). The domain is structure-complete for the fls family (output depends only on the MSB position): 0, ~0, 1<<63, all 64 single-bit words, exhaustive low-22-bit words, exhaustive top-22-bit words, every MSB position h∈[0,64) Γ—1024 random words with highest set bit exactly h, and 50,000,000 splitmix64 randoms. This proves flsl(x) = index_of_highest_set_bit + 1 (= 64 - clz(x) for xβ‰ 0, 0 for x=0) for the whole 64-bit domain structure, including the loop-termination path at flsl.c:44 (mask != 1) and the unsigned refill at flsl.c:45.
  4. Consumer census (why this is Info, not higher). Live consumers all resolve to the inline, none to the dead object: - sys/kern/kern_slaballoc.c:784 β€” i = flsl(size) inside powerof2_size() (:775-785): the size == 0 and powerof2(size) guards (:781-782) ensure flsl is only called with size β‰₯ 2 non-power-of-2, so the returned index ∈ [1, 63] and 1UL << i cannot shift by 64 β€” no misuse. - sys/dev/disk/nata/chipsets/ata-ahci.c:102, sys/sys/bitops.h:162 (ilog2 macro), sys/dev/drm/include/linux/bitops.h:79, sys/dev/drm/include/linux/log2.h:40,52. No memory operands β€” guard-page/overflow classes vacuous.
  5. Fix. fix.diff: #if !defined(HAVE_INLINE_FLSL) gate. Validated: gated file compiles kernel-style, 0 global flsl symbols in the object on x86_64 (build.log "FIXCOMPILE-OK", fix_run.log). Deletion equally valid; consistent with DF-5714's ffs.c fix.

Why no further escalation was pursued

Pure register function, no pointers, linked nowhere β€” no runtime kernel behavior to attack. The pass-2 deliverable is the dead-file status plus the machine-checked find-last-set correctness proof (precedent: DF-5714, DF-5700, same class).

Rig honesty notes

  • Same rig as DF-5715/DF-5717 (shared build.sh/run.sh/p2_harness.c); first-shot success, no intermediate failed artifacts. See DF-5715's VERDICT for the scratch-file note.

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched reproduced

Validation is at the compile level, which is exactly the level where the defect manifests (the file is linked nowhere, so there is no runtime behavior to A/B and no kernel rebuild to do). Baseline reproduced: the committed flsl.c fails kernel-style compile with 'redefinition of flsl' against cpufunc.h:293's static __inline (DEADPROOF-OK, dead_compile_flsl.log). Patched (fix.diff = HAVE_INLINE_FLSL gate around the body): compiles kernel-style with zero errors (fix_compile_flsl.log contains only the pre-existing harmless 'conflicting types for built-in log' warning from systm.h:216) and the nm census shows 0 global flsl symbols in the object β€” the body compiles away on x86_64 exactly as the live tree expects (FIXCOMPILE-OK, fix_run.log).

dead_compile_flsl.log (baseline failure: error: redefinition of 'flsl', previous definition at cpufunc.h:293); fix_compile_flsl.log (gated compile, error-free); fix_run.log (baseline symbol k_flsl present vs patched census 0); build.log sections '== dead-file proof' / '== fix validation'; fix.diff
↓ fix.diffper-fix-DF-5716

Confirmed kernel references

Detail

Evidence (decisive lines)

build.log sections '== conf/files census' (libkern/flsl.c in conf/files: 0) and '== dead-file proof' (DEADPROOF-OK: flsl.c ... error: redefinition of 'flsl'; cpufunc.h:293 previous definition) with full gcc output in dead_compile_flsl.log; run.log 'T2 flsl : 58454211 cases, 0 mism vs live-inline, 0 mism vs clz-ref' + HARNESS-PASS; 'FIXCOMPILE-OK: gated flsl.c compiles kernel-style; global flsl symbols in object: 0' (fix validation); env.txt pins guest cksums == audit tree (flsl.c 2802750667 1878).

PoC changes

No seed PoC existed (pass 1 filed nothing). Rig authored per the DF-5714 pattern (same shared rig as DF-5715/DF-5717): verbatim bodies compiled from the guest's own /usr/src with only the kernel-only include line stripped and identifiers renamed via -D; the fls-family reference is the cpufunc.h inline implementation copied byte-faithfully (bsrq asm from :119-126). First-shot success.

Verified recommended fix

Adopt fix.diff (#if !defined(HAVE_INLINE_FLSL) gate around the body), or simply delete sys/libkern/flsl.c β€” it is unreferenced by conf/files and cannot compile in-kernel as committed.

Verdict

sys/libkern/flsl.c is dead code with a latent build hazard, same class as DF-5714 (ffs.c): absent from sys/conf/files (libkern block 2195-2237; grep -c = 0 verified on host and guest), superseded on the only supported arch by the cpufunc.h:290-296 static __inline flsl (HAVE_INLINE_FLSL, bsrq-based; the libkern.h:111-112 prototype is itself gated), and non-compilable in-kernel as committed: the #include at flsl.c:32 pulls libkern.h:51 -> systm.h:50 -> machine/cpufunc.h, so the out-of-line definition at flsl.c:37-47 collides with the static __inline β€” gcc 8.3 'error: redefinition of flsl' vs 'previous definition' at cpufunc.h:293 (dead_compile_flsl.log, kernel-style -nostdinc -D_KERNEL compile per kern.pre.mk:61). The latent find-LAST-set body was proven arithmetically correct: verbatim body vs the live cpufunc.h inline (bsrq asm copied verbatim from cpufunc.h:119-126) and vs the 64-__builtin_clzl reference, 0 mismatches over 58,454,211 structure-complete cases (0, ~0, sign word, all 64 single bits, exhaustive low-22 and top-22 bit patterns, every MSB position x1024 randoms below it, 50M splitmix64 randoms) β€” i.e. flsl(x) = 64-clz(x) for x!=0 and 0 for x==0 across the whole 64-bit domain structure, clearing the loop termination (flsl.c:44) and unsigned refill (flsl.c:45). Consumer census: the live call sites (kern_slaballoc.c:784 inside powerof2_size, guarded size==0/powerof2 at :781-782 so 1UL<<i can never shift by 64; ata-ahci.c:102; bitops.h:162 ilog2; drm linux/bitops.h:79, linux/log2.h:40,52) all resolve to the inline. Impact none (nothing links the file); Info hygiene finding, same class as DF-5714/DF-5700.