DragonFlyBSD Kernel Audit
DF-0547 / df0547.c
← back to finding ↓ download raw
/*
 * DF-0547 -- conceptual PoC skeleton for netmap ring-cleanup buf_idx trust.
 *
 * CANNOT RUN on this audit guest because:
 *   1. /boot/kernel/netmap.ko is NOT shipped (default X86_64_GENERIC
 *      has no NETMAP option).
 *   2. Building netmap.ko from /usr/src/sys/net/netmap currently fails
 *      with `struct ifnet has no member named 'if_unused7'` -- the
 *      netmap source is stale relative to the current struct ifnet
 *      layout (sys/net/if_var.h has only if_unused2 and if_unused4).
 *
 * If netmap source were brought up to date and loaded, this PoC would:
 *   1. open /dev/netmap
 *   2. NIOCREGIF a NIC or VALE port
 *   3. mmap the rings (shared-memory access to slot[].buf_idx)
 *   4. rewrite slot[i].buf_idx to attacker-chosen values:
 *      - all same index -> objfree inflation via netmap_obj_free
 *      - index owned by another adapter -> cross-adapter free
 *   5. close the fd -> netmap_mem_rings_delete frees each rewritten
 *      buf_idx (no per-ring ownership check) -> corruption
 */

#include <stdio.h>

int main(void) {
    fprintf(stderr,
        "[DF-0547] PoC skeleton -- netmap.ko not loadable on this guest\n"
        "(module not shipped AND source does not compile due to stale\n"
        "struct ifnet.if_unused7 reference at netmap_kern.h:747).\n\n"
        "Trigger if netmap were loadable:\n"
        "  1. open /dev/netmap\n"
        "  2. NIOCREGIF a NIC or VALE port (needs admin to grant access)\n"
        "  3. mmap the rings\n"
        "  4. rewrite slot[i].buf_idx to all-equal or to a victim index\n"
        "  5. close -> netmap_mem_rings_delete frees the rewritten indices\n"
        "     -> objfree inflation / cross-adapter buffer aliasing\n\n"
        "Fix: fix.diff adds a defense-in-depth double-free check in\n"
        "netmap_obj_free. Complete fix needs per-ring ownership tracking\n"
        "(kernel-private buf_idx array per kring).\n");
    return 0;
}