⬢ DragonFlyBSD Kernel Audit
DF-5104 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5104",
  "status": "inconclusive",
  "reproduced": false,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Static defect is certain: gpio_master_ioctl() (sys/dev/misc/gpio/gpio.c:471-478) hands consumers (void *)(long)consumer_arg.lint when GPIO_TYPE_INT is set, and led_attach()s only guard is arg==NULL (gpio_led.c:186-187) before kstrdup((char *)arg) (gpio_led.c:193) \u2014 strlen() on an attacker-chosen value (lint=1 => guaranteed kernel panic; lint=<mapped kernel address> => kernel-memory-as-string disclosure published via the world-listable /dev/led/<name> node (gpio_led.c:206-207) and kprintf (gpio_led.c:211-212)). The 32-byte string variant over-reads the non-NUL-terminated consumer_arg.string staged in mapped_ioctl()s 128-byte kernel stack buffer (sys_generic.c:572-574,674-686), leaking stale kernel stack the same way. NOT exercised at runtime because the misc/gpio framework is not compiled into the audit guest (no `device gpio`/`device nsclpcsio` in X86_64_GENERIC; /dev/gpio and /dev/led absent \u2014 run.log/env.txt) and QEMU does not emulate the PC87366 GPIO logical device: the kernel path has no entry point on this guest. Root-only (master node 0600, gpio.c:574) + non-GENERIC config + Super I/O hardware => Low severity.",
  "exploit_chain": "(not executed) On a gpio-equipped system as root: open(\"/dev/gpio/pc873660/master\") -> ioctl(GPIOATTACH, {consumer_name=\"led\", arg_type=GPIO_TYPE_INT, lint=1}) -> gpio_consumer_attach -> led_attach -> kstrdup((char *)1) -> strlen at address 1 -> kernel panic. With lint=<mapped kmem address> the copied string becomes the /dev/led/<name> node name (world-listable) and is kprintfd => kmem disclosure.",
  "evidence": "VERDICT.md (static proof chain, path:line); run.log (ENOENT \u2014 no /dev/gpio on guest); env.txt (guest kernel config, uname); build.log (trigger compiles clean); gpioled_int_kstrdup.c (trigger); fix.diff (verified two-part fix)",
  "kernel_refs": [
    "sys/dev/misc/gpio/gpio_led.c:186",
    "sys/dev/misc/gpio/gpio_led.c:193",
    "sys/dev/misc/gpio/gpio_led.c:206",
    "sys/dev/misc/gpio/gpio_led.c:211",
    "sys/dev/misc/gpio/gpio.c:471",
    "sys/dev/misc/gpio/gpio.h:119",
    "sys/kern/sys_generic.c:674"
  ],
  "poc_changes": "wrote from scratch (no seed); userland mirror of struct gpio_attach_args + GPIOATTACH since <dev/misc/gpio/gpio.h> is kernel-only (cdev_t via sys/conf.h); 64-byte struct verified against kernel layout",
  "attempts": 1,
  "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": 5,
  "guest_dirty": 0,
  "build_cmd": "cc -Wall -o gpioled_int_kstrdup gpioled_int_kstrdup.c",
  "run_cmd": "./gpioled_int_kstrdup /dev/gpio/pc873660/master",
  "code_hash": "1ab846571d9969a91d211e2c36c3c216926df2885dcf3c29749e9a3eae5c983b",
  "notes": "Guest untouched except ephemeral /tmp build (removed). Known pass-1 findings not re-reported: DF-2112 (gpio_map-fail leak in led_attach), DF-2113 (unimplemented led_detach UAF). Killed candidates: led_write value range (controller treats non-{0,1} as no-op, nsclpcsio_isa.c:608-611); map range (gpio.c:211-226 validates); no hints parsing; no callout/blink; no reachable lock inversion (one-way gpiodev_lock->gpio_lock->led_lock; gpio_map lockstatus probe defuses the AB-BA at gpio_led.c:197).",
  "recommended_fix": "gpio.c GPIOATTACH: convert GPIO_TYPE_INT lints to a decimal string before gpio_consumer_attach(); gpio_led.c led_attach: replace kstrdup with a bounded 32-byte copy + force NUL (see fix.diff)",
  "fix_status": "not_tested",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "fix.diff authored post-verification against read-only sys/ (never applied); cannot be kernel-build validated on this guest because the gpio framework is not in its kernel config and the PC87366 controller hardware is not emulated",
  "fix_evidence": "findings/poc/DF-5104/fix.diff"
}