DragonFly's linux/hash.h hash_64() shim returns identically 0 for every bits <= 32, collapsing the chash (amdgpu retry-fault hash) so all keys probe from slot 0
Summary
chash.c is byte-identical to Linux v4.19 and sound, but the DFly hash_64 shim casts a 32-bit hash32_buf result to u64 then shifts >>(64-bits) - identically 0 for every bits<=32, so the amdgpu retry-fault chash (bits=8) always probes from slot 0 and drm_hashtab degrades the same way. Correctness preserved (linear probing, 50% fill cap) - perf-only today, latent for future consumers. Fix the shim: hash twice with different seeds and concatenate. [VERIFIED pass2: reproduced via KMOD with real DRM header - hash_64 x 8 returns 0 identically collapsing the amdgpu retry-fault chash to slot-0 probing; fixed tree returns distinct nonzero values A/B]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4747 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 240 B | β raw | |
| fix.diff | β | 681 B | view raw | |
| hash4747.c | β | 1.3 KB | view raw | |
| manifest.json | β | 424 B | view raw | |
| run.log | β | 292 B | view raw | |
| verdict.json | β | 2.0 KB | view raw |
DF-4747 evidence pack
What
DRM hash_64 shim returns identically 0 for bits <= 32, collapsing chash
Verdict
status=reproduced impact=none confidence=certain
See VERDICT.md for the full narrative and fix.diff for the verified fix.
Fix verification
fixedA/B complete: the KMOD rebuilt against the patched header returns distinct nonzero values for bits=8 (0xe3/0x49/0x90) and 40 (0x72d3778c97); stock returned identically 0 for bits<=32.
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md with path:line citations; run.log where a live demo exists; fix.diff
PoC changes
KMOD needed local u64/u32 typedefs + BITS_PER_LONG before including the DRM header (its include chain pulls kernel-only headers)
Verified recommended fix
hash twice with different seeds and concatenate (real 64-bit mix)
Verdict
Reproduced on the stock INVARIANTS guest with a KMOD that includes the real shim header (linux/hash.h): hash_64(x, 8) returns 0x0 for every input tested (0x1122334455667788, 0xdeadbeefcafebabe, 1) - the shim casts the 32-bit hash32_buf result to u64 and shifts right by (64 - bits) >= 32, which is identically zero (hash.h:32-38). chash.c (byte-identical to Linux v4.19, itself sound) calls hash_64(key, bits) at :398/:433 for 64-bit keys, so the amdgpu retry-fault chash (bits=8, amdgpu_vm.c) always probes slot 0 - linear-probe degradation, correctness preserved by the 50% fill cap. Post-fix A/B: the KMOD rebuilt against the patched tree returns nonzero, well-distributed values for bits=8 and 40. Fix = two independent 32-bit hashes concatenated; compile-validated via the KMOD rebuild (drm itself is module-built; the header is DRM-internal).
No comments yet.