⬢ DragonFlyBSD Kernel Audit
DF-4297 / kbdrel.c
← back to finding ↓ download raw
/*
 * kbdrel.c - DF-4297 PoC helper: release the vkbd child from kbdmux so the
 * fresh keyboard is not KBD_IS_BUSY and can be opened via /dev/kbdN.
 *
 * syscons owns the kbdmux keyboard, so the KBRELKBD ioctl is issued through
 * the console device /dev/ttyv0 (sc_ioctl -> kbd_ioctl(mux, KBRELKBD)),
 * exactly like kbdcontrol(1) does.
 *
 * usage: kbdrel <name> <unit>   e.g. kbdrel vkbd 0
 */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/kbio.h>

int
main(int argc, char **argv)
{
	keyboard_info_t ki;
	int fd, error;

	if (argc != 3) {
		fprintf(stderr, "usage: %s <name> <unit>\n", argv[0]);
		return (2);
	}
	memset(&ki, 0, sizeof(ki));
	strlcpy(ki.kb_name, argv[1], sizeof(ki.kb_name));
	ki.kb_unit = atoi(argv[2]);

	fd = open("/dev/ttyv0", O_RDWR);
	if (fd < 0) {
		perror("open /dev/ttyv0");
		return (2);
	}
	error = ioctl(fd, KBRELKBD, &ki);
	fprintf(stderr, "kbdrel(%s%d): ioctl KBRELKBD -> %d errno=%d (%s)\n",
		ki.kb_name, ki.kb_unit, error, errno, strerror(errno));
	close(fd);
	return (error == 0 ? 0 : 1);
}