⬢ DragonFlyBSD Kernel Audit
DF-5378 / manifest.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5378",
  "title": "Use-after-free of the UVC control graph in uvc_query_v4l2_ctrl()/uvc_query_v4l2_menu(): detach frees sc->ctrl before destroy_dev, giving an unprivileged racing VIDIOC_QUERYCTRL/QUERYMENU a 1-byte write into freed kernel heap and a 31-byte-per-query kernel-heap disclosure",
  "file": "sys/bus/u4b/uvc/uvc_ctrls.c",
  "verdict": "reproduced",
  "impact": "memcorrupt (UAF write + kheap leak; panic variant); userspace-visible artifact recorded as leak",
  "confidence": "certain",
  "reproduce": {
    "build": "see build.sh (KLD harness on guest /root/build, #includes real uvc sources from /usr/src, make with -Werror)",
    "run": "see run.sh (kldload /root/build/uvcharness.ko -> mode 1 controlled UAF proof at load; sysctl hw.uvcharness=2 -> wild-pointer panic)",
    "expected": "mode 1: all 11 freed chunks reclaimed at original addresses; q.name = 31x 0x5A; controls[1].cached_sub_info_idx 0xAA -> 0x01 (uvc_ctrls.c:1065 write); qm.name = 31x 0x5B (uvc_ctrls.c:1150). mode 2: Fatal trap 9, Stopped at uvc_search_control+0x20 movl 0x70(%rax),%ecx, guest down. Post-fix (fix.diff): mode 3 returns ENODEV, guest up"
  },
  "kernel_refs": [
    "sys/bus/u4b/uvc/uvc_ctrls.c:1065",
    "sys/bus/u4b/uvc/uvc_ctrls.c:1090",
    "sys/bus/u4b/uvc/uvc_ctrls.c:1102",
    "sys/bus/u4b/uvc/uvc_ctrls.c:1107",
    "sys/bus/u4b/uvc/uvc_ctrls.c:1001",
    "sys/bus/u4b/uvc/uvc_ctrls.c:1150",
    "sys/bus/u4b/uvc/uvc_drv.c:2507",
    "sys/bus/u4b/uvc/uvc_drv.c:2453",
    "sys/bus/u4b/uvc/uvc_drv.c:2511",
    "sys/bus/u4b/uvc/uvc_v4l2.c:783"
  ],
  "artifacts": [
    "README.md", "VERDICT.md", "uvcharness.c", "Makefile", "build.sh", "run.sh",
    "build.log", "fix_build.log", "run.log", "fix.log", "panic.txt",
    "leak_sample.txt", "env.txt", "fix.diff", "manifest.json", "verdict.json"
  ]
}