DragonFlyBSD Kernel Audit
DF-1048 / fix_run.log
← back to finding ↓ download raw
# DF-1048 fix-validation run on the PATCHED single-fix kernel
# kern.version: DragonFly 6.5-DEVELOPMENT #1: Tue Jul 14 11:15:55 UTC 2026
# kernel sha256: 94a607c1a71a1ea538b7f04ad81dfeb2dc3b12c3ab0f48f3147c1ffc234e102d
# umcs.ko sha256: fe64ed0362abd931de0f2b7cc4edcf709ee022b6cbbcfc502312ae31d8a45fa3
#
# NOTE: the live tcsetattr(B0) path is NOT runtime-triggerable on this guest
# (no USB host controller / MCS7840 device). Validation was therefore done by:
#   (1) confirming the fixed source compiles (nativekernel rc=0),
#   (2) booting the #1 kernel cleanly,
#   (3) disassembling the installed umcs.ko to prove the rate==0 guard is
#       compiled in (umcs7840_pre_param returns EINVAL before reaching
#       calc_baudrate's `div` instruction), and
#   (4) re-running the arithmetic harness on the fixed kernel (below) showing
#       the buggy branch still traps while the fixed branch returns -1.

$ ./harness_O0   (run on FIXED kernel #1, as maxx)
DF-1048 harness: umcs7840_calc_baudrate divide-by-zero proof
array umcs7840_baudrate_divisors has 9 elements (len-1 = 8)
On x86-64, integer /0 raises #DE -> kernel panic (trap 17); userspace analog is SIGFPE.

== BUGGY version (mirrors umcs.c:1056-1070 as shipped) ==
  rate=0          -> *** DIVIDE BY ZERO (SIGFPE / #DE trap) ***
  rate=115200     -> returned rc=0 divisor=0x0001 clk=0x00
  rate=921600     -> returned rc=0 divisor=0x0001 clk=0x50

== FIXED version (mirrors fix.diff: rate==0 guard) ==
  rate=0          -> returned rc=-1 divisor=0xdead clk=0xff
  rate=115200     -> returned rc=0 divisor=0x0001 clk=0x00
  rate=921600     -> returned rc=0 divisor=0x0001 clk=0x50

CONCLUSION: buggy version faults on rate==0 (kernel #DE panic, trap 17);
            fixed version returns -1 cleanly (-> EINVAL propagates to tcsetattr).
RUN_EXIT=0

=== installed /boot/kernel/umcs.ko disassembly (FIXED) — proof the guard is compiled in ===
0000000000000b00 <umcs7840_pre_param>:
     b00:   8b 7e 28                mov    0x28(%rsi),%edi      # edi = t->c_ospeed
     b03:   8d 47 ff                lea    -0x1(%rdi),%eax      # eax = rate - 1
     b06:   3d ff ff 2f 00          cmp    $0x2fffff,%eax       # (unsigned)(rate-1) vs 3145727
     b0b:   77 33                   ja     b40 <...+0x40>       # rate==0 (underflow) OR rate>3145728
     ...
     b1d:   e8 7e ff ff ff          callq  aa0 <umcs7840_calc_baudrate.part.0>   # only reached if 1<=rate<=3145728
     ...
0000000000000b40 <umcs7840_pre_param+0x40>:        # <-- the ja target for rate==0
     b40:   b8 16 00 00 00          mov    $0x16,%eax           # EINVAL (22)
     b45:   c3                      retq

# The `div %edi` sink at umcs7840_calc_baudrate.part.0+0x4a (offset aea) is
# NEVER reached for rate==0 — pre_param returns EINVAL first.