/*
 * DF-1012 — UVC heap underflow when VS_COLORFORMAT or VS_FRAME precedes
 * any VS_FORMAT descriptor.
 *
 * Bug location: sys/bus/u4b/uvc/uvc_drv.c:1836-1846, 1924
 *
 * At uvc_drv.c:1836 the parser sets
 *     fmt = data->fmt - 1;
 * which intentionally starts fmt one slot BEFORE the data->fmt[]
 * allocation.  The intent is that the FIRST VS_FORMAT_* descriptor
 * will execute `fmt++;` (line 1851/1878) to advance fmt onto the
 * first valid slot.  However the VS_COLORFORMAT case (line 1842) and
 * the VS_FRAME_* cases (line 1897, 1927) write to `fmt->colorspace`
 * / increment `fmt->nfrm` UNCONDITIONALLY:
 *
 *     case UDESCSUB_VS_COLORFORMAT:
 *         cld = (struct uvc_vs_color_desc *)desc;
 *         fmt->colorspace = uvc_drv_get_colorspace(cld->bColorPris);
 *         break;
 *
 * sizeof(struct uvc_data_format) == 96 (verified from uvc_drv.h:629),
 * colorspace is at struct offset 30, nfrm is at struct offset 8.  So
 * if a COLORFORMAT or FRAME descriptor appears in the descriptor list
 * BEFORE any VS_FORMAT_* descriptor, the parser writes:
 *   fmt->colorspace at data->fmt - 96 + 30 = data->fmt - 66
 *   fmt->nfrm       at data->fmt - 96 +  8 = data->fmt - 88
 * i.e. a heap underflow 66..88 bytes before the data->fmt allocation.
 *
 * The UVC spec requires VS_FORMAT descriptors to precede the
 * VS_FRAME descriptors for that format, but a malicious USB webcam
 * can present a descriptor list in any order.  The parser already
 * trusts the device for ordering elsewhere (init_data_fmt just
 * counts descriptors without ordering checks).
 *
 * Reachability on the audit guest:
 *   - The QEMU/KVM guest has no USB UVC device attached; uvc.ko is
 *     shipped as a loadable module but never matches a real device.
 *   - There is no software path that reaches uvc_drv_parse_data()
 *     without a USB UVC webcam present.
 *   - The bug is therefore LATENT on this guest but live on any
 *     physical host that plugs in a (potentially malicious) UVC
 *     webcam — the parser runs at device-attach time with no user
 *     interaction beyond plug-in.
 *
 * This harness documents the trigger and the fix.
 */
#include <stdio.h>

int main(void)
{
    printf("=== DF-1012 trigger documentation ===\n");
    printf("\nVulnerable path (device-attach time):\n");
    printf("  uvc_attach -> uvc_drv_parse_data (uvc_drv.c:1776)\n");
    printf("    fmt = data->fmt - 1;            // uvc_drv.c:1836\n");
    printf("    while (desc = usbd_find_descriptor(...)) {\n");
    printf("        case UDESCSUB_VS_COLORFORMAT:\n");
    printf("            fmt->colorspace = ...;   // writes data->fmt - 66\n");
    printf("        case UDESCSUB_VS_FRAME_*:\n");
    printf("            fmt->nfrm++;             // writes data->fmt - 88\n");
    printf("    }\n");
    printf("Trigger precondition: a malicious USB UVC webcam whose\n");
    printf("  descriptor list emits a VS_COLORFORMAT or VS_FRAME_*\n");
    printf("  descriptor BEFORE any VS_FORMAT_* descriptor.\n");
    printf("Effect: heap underflow write 66..88 bytes before the\n");
    printf("  data->fmt allocation; corrupts slab metadata / adjacent\n");
    printf("  objects -> write-what-where primitive on a remote-capable\n");
    printf("  attacker-controlled device.\n");
    printf("\nStatus on this audit guest (no USB UVC device attached):\n");
    printf("  NOT REACHABLE. Bug confirmed by code trace at\n");
    printf("  sys/bus/u4b/uvc/uvc_drv.c:1836-1846 and 1924. Fix: track a\n");
    printf("  fmt_seen flag and skip the COLORFORMAT / FRAME writes until\n");
    printf("  the first VS_FORMAT descriptor has executed fmt++. See\n");
    printf("  fix.diff and VERDICT.md.\n");
    return 0;
}
