⬢ DragonFlyBSD Kernel Audit
DF-5789 / walker.c
← back to finding ↓ download raw
/*
 * DF-5789 walker — dump the flat device tree via hw.bus.devices exactly
 * the way libdevctl/devd does, and flag zombie devices: still parented
 * (present in the tree) but with state < DS_ATTACHED and no driver.
 * This is what an UNPRIVILEGED user can observe.
 */
#include <sys/types.h>
#include <sys/sysctl.h>
#include <err.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct u_businfo {
	int ub_version;
	int ub_generation;
};

struct u_device {
	uintptr_t dv_handle;
	uintptr_t dv_parent;
	char dv_name[32];
	char dv_desc[32];
	char dv_drivername[32];
	char dv_pnpinfo[128];
	char dv_location[128];
	uint32_t dv_devflags;
	uint16_t dv_flags;
	int dv_state;
};

#define DS_NOTPRESENT 0
#define DS_ALIVE 1
#define DS_INPROGRESS 2
#define DS_ATTACHED 3
#define DS_BUSY 4

static const char *statename[] = { "NOTPRESENT", "ALIVE", "INPROGRESS",
	"ATTACHED", "BUSY" };

int
main(void)
{
	struct u_businfo ubus;
	struct u_device udev;
	int mib[16], genmib[16], gmib[16];
	size_t len, glen;
	int gen, idx, nz;

	len = sizeof(genmib);
	if (sysctlnametomib("hw.bus.info", genmib, &len) < 0)
		err(1, "sysctlnametomib(hw.bus.info)");
	glen = sizeof(ubus);
	if (sysctl(genmib, len, &ubus, &glen, NULL, 0) < 0)
		err(1, "sysctl(hw.bus.info)");
	gen = ubus.ub_generation;
	printf("generation %d (version %d)\n", gen, ubus.ub_version);

	len = sizeof(mib);
	if (sysctlnametomib("hw.bus.devices", mib, &len) < 0)
		err(1, "sysctlnametomib(hw.bus.devices)");

	memcpy(gmib, mib, (len + 2) * sizeof(int));
	gmib[len] = gen;

	nz = 0;
	for (idx = 0; idx < 4096; idx++) {
		size_t sz = sizeof(udev);

		gmib[len + 1] = idx;
		if (sysctl(gmib, len + 2, &udev, &sz, NULL, 0) < 0)
			break;
		if (idx < 3 || udev.dv_state < DS_ATTACHED ||
		    strcmp(udev.dv_drivername, "") == 0) {
			printf("[%3d] %-12s drv=%-10s state=%-11s parent=%#lx\n",
			    idx, udev.dv_name, udev.dv_drivername,
			    udev.dv_state <= DS_BUSY ? statename[udev.dv_state] : "?",
			    (unsigned long)udev.dv_parent);
			if (udev.dv_state < DS_ATTACHED &&
			    strcmp(udev.dv_drivername, "") == 0)
				nz++;
		}
	}
	printf("total listed (capped 4096): %d; ZOMBIES (no driver, state<ATTACHED): %d\n",
	    idx, nz);
	return (0);
}