⬢ DragonFlyBSD Kernel Audit
DF-3879 / kmemprobe.c
← back to finding ↓ download raw
/*
 * DF-3879 root-side oracle: probe whether kernel VAs are mapped, safely,
 * by pread()ing /dev/kmem (unmapped KVA yields an error, not a panic).
 * Used to pick the attack t so that wild = b->buf + 0xFFFFF000 + t lands
 * on mapped kernel memory (kmem band measured via hw.snd.verbose=4 dmesg).
 *
 * usage: kmemprobe <base_va_hex> <pages>
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char **argv)
{
	if (argc < 3) { printf("usage: %s base_va_hex pages\n", argv[0]); return 2; }
	uint64_t base = strtoull(argv[1], NULL, 0);
	int pages = atoi(argv[2]);
	int fd = open("/dev/kmem", O_RDONLY);
	if (fd < 0) { printf("[-] open /dev/kmem: %s\n", strerror(errno)); return 2; }
	for (int i = 0; i < pages; i++) {
		uint64_t va = base + (uint64_t)i * 4096;
		char buf[16];
		ssize_t n = pread(fd, buf, sizeof(buf), (off_t)va);
		if (n == sizeof(buf))
			printf("%016llx MAPPED  %02x %02x %02x %02x %02x %02x %02x %02x\n",
			       (unsigned long long)va,
			       (unsigned char)buf[0],(unsigned char)buf[1],
			       (unsigned char)buf[2],(unsigned char)buf[3],
			       (unsigned char)buf[4],(unsigned char)buf[5],
			       (unsigned char)buf[6],(unsigned char)buf[7]);
		else
			printf("%016llx unmapped (pread=%zd errno=%d)\n",
			       (unsigned long long)va, n, errno);
	}
	return 0;
}