# DF-5700 — libkern/bcmp.c by-design longword over-read (dead code on DFly; page-contained)

## What the finding is

`sys/libkern/bcmp.c` compares with full `unsigned long` loads that are NOT
bounded by the caller's length:

- tail loads `*(culp)p1` / `*(culp)p2` at bcmp.c:110-111 and bcmp.c:128-129
  read up to `8 - (len % 8)` = up to **7 bytes past the end** of both
  buffers (the exact case admitted by the 1994 comment at bcmp.c:53-56);
- the misaligned-streaming loop's `vb = *(culp)p2` at bcmp.c:89 reads up to
  `8 - shr` bytes past the point where 8 compared bytes end;
- the down-alignment `p2 -= shr; va = *(culp)p2` at bcmp.c:81-85 reads up to
  **7 bytes below the start** of the b2 region.

All over-read bytes are masked/discarded (they never affect the result), so
there is no disclosure — but the loads happen, which matters under object-
granularity sanitizers and for any future caller relying on `bcmp` staying
inside its stated arguments.

## Why it is only Low / impact `none` here

1. **The file is not compiled into any DragonFlyBSD kernel.**
   - `sys/conf/files:2199-2237` (the libkern list) does not include
     `libkern/bcmp.c`;
   - `sys/platform/pc64/conf/files:131` builds `platform/pc64/x86_64/bcmp.s`
     instead (the mjg-macro `MEMCMP` — verified below);
   - `sys/platform/vkernel64/conf/files` has no bcmp/memcmp entry (the
     vkernel is a userland binary that links host libc).
2. **In-guest proof** (`logs/kernel_bcmp_disasm.txt`): the running
   X86_64_GENERIC kernel's `bcmp` at `0xffffffff80bcb800` disassembles to
   the first/last overlapping-load pattern (`cmp $0x10,%rdx`;
   `mov (%rdi),%r8`; `mov -0x8(%rdi,%rdx,1),%r8`) — every load strictly
   inside `[base, base+len)`. The shipped kernel bcmp has **zero** over-read;
   the C file's property is latent only.
3. **Page-containment (the property DF-5676 leaned on) holds and is proven**
   both analytically and empirically — see below.

## Containment proof (why "bounded OOB read, page-contained" is correct)

Analytic: every longword load in the file is naturally 8-byte aligned, and
8 divides 4096, so an 8-byte load can never straddle a page boundary. Each
such load starts at an address that holds at least one in-bounds byte
(`p2 -= shr` stays in the first byte's page; loop and tail loads start
strictly below the region end). Hence every out-of-region load lies in the
same page as a valid byte of its buffer: the over-read can read adjacent
slab data in the same page but **can never fault and never crosses into a
neighboring page**.

Empirical (this rig): 512,496 calls with each buffer placed inside a single
page flanked by `PROT_NONE` guard pages — including buffers that *end on
the last byte of the page* and *start on the first byte of the page*, all
`off1/off2 ∈ [0,7]` misalignment combinations, lengths 1..4096, and 500k
randomized placements — **zero faults** (`logs/guard.out`).

Measurement (that the over-read is real, not theoretical): a load-instrumented
copy of the exact algorithm (`bcmp_instr.c`, identical control flow, every
load wrapped) counts over the exhaustive alignment/length sweep:
`buf1: below-start loads=11554 (max 7 B); past-end loads=2434 (max 7 B)`
and `buf0: past-end loads=2436 (max 7 B)` (`logs/instr.out`). ASAN would
show the same but the guest has no libasan (`asan_harness.c` included for
hosts that do).

## Build & run (on the DFly guest or any LP64 host with a C compiler)

```sh
./build.sh          # compiles the pristine bcmp.c + harnesses
./run.sh            # containment sweep + instrumented measurement + fix check
```

Expected decisive output:

```
RESULT: PASS — no load escaped the buffer's valid pages (12288 + 208 + 500000 cases)
buf0: ... past-end loads=2436 (max 7 B ...)
buf1: ... below-start loads=11554 (max 7 B) past-end loads=2434 (max 7 B ...)
RESULT: OVERREAD-CONFIRMED — longword loads DO read outside [ptr,ptr+len)
```

## Fix validation

`fix.diff` rewrites the body to provably in-bounds loads (align BOTH
pointers bytewise first; full-longword loop only while ≥8 bytes remain on
both; bytewise tail) — also removing the DF-5701 truncation. Validated on
the same rig: 2,304,192 differential cases 0 failures, instrumented
out-of-region loads drop to **0/0 with max excursion 0 B**
(`logs/fixed.out`), guard sweep still passes (`logs/guardfix.out`).
Kernel-level rebuild validation is not applicable (the file is not part of
any DFly kernel build); rig-level validation is exact because the kernel
would compile this very source verbatim if a platform ever re-added it.
