DF-2931 / uuidoff.c
/* * DF-2931 proof module: show exactly what if_getanyethermac() reads * for the first IFT_ETHER interface, versus that interface's real MAC, * plus the offsets that decide in-struct vs out-of-bounds. */ #include <sys/param.h> #include <sys/module.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/bus.h> #include <net/if.h> #include <net/if_var.h> #include <net/if_arp.h> #include <net/if_dl.h> #include <net/if_types.h> #include <net/if_media.h> #include <net/ifq_var.h> #include <sys/eventhandler.h> #include "virtio_net.h" #include "if_vtnetvar.h" static void uuidoff_dump(void) { struct ifnet *ifp; size_t off = __offsetof(struct arpcom, ac_enaddr); int n = 0; kprintf("uuidoff: sizeof(struct ifnet) = %zu\n", sizeof(struct ifnet)); kprintf("uuidoff: offsetof(struct arpcom,ac_enaddr)= %zu\n", off); kprintf("uuidoff: sizeof(struct vtnet_softc) = %zu\n", sizeof(struct vtnet_softc)); TAILQ_FOREACH(ifp, &ifnetlist, if_link) { uint8_t *p; struct sockaddr_dl *sdl; uint8_t *mac; if (ifp->if_type != IFT_ETHER) continue; p = (uint8_t *)ifp->if_softc + off; sdl = IF_LLSOCKADDR(ifp); mac = (uint8_t *)LLADDR(sdl); kprintf("uuidoff: ether[%d] %s if_softc=%p\n", n, ifp->if_xname, ifp->if_softc); kprintf("uuidoff: bytes at if_softc+%zu (what " "if_getanyethermac copies into UUID node): " "%02x:%02x:%02x:%02x:%02x:%02x\n", off, p[0], p[1], p[2], p[3], p[4], p[5]); kprintf("uuidoff: real MAC from sdl (sdl_alen=%u): " "%02x:%02x:%02x:%02x:%02x:%02x\n", sdl->sdl_alen, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); n++; } kprintf("uuidoff: %d IFT_ETHER interface(s); " "if_getanyethermac uses the FIRST\n", n); } static int uuidoff_modevent(module_t mod, int type, void *data) { switch (type) { case MOD_LOAD: uuidoff_dump(); return (0); case MOD_UNLOAD: kprintf("uuidoff: unloaded\n"); return (0); } return (EOPNOTSUPP); } static moduledata_t uuidoff_mod = { "uuidoff", uuidoff_modevent, NULL }; DECLARE_MODULE(uuidoff, uuidoff_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); MODULE_VERSION(uuidoff, 1); |