DF-5378 / manifest.json
{ "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" ] } |