DF-3978 / df3978_rig.c
/* * df3978_rig.c -- DF-3978 in-kernel verification rig (KLD, root-only). * * Duties: * MOD_LOAD : print offsetof() constants for the CPL0 payload. * kern.df3978_msrs : live rdmsr() of IA32_SYSENTER_{CS,ESP,EIP} -- the * hardware state the finding says is left * guest-controlled after each NVMM VCPU_RUN. * kern.df3978_pid=N : resolve pid via the kernel's own pfind() and dump * the proc and ucred pointers plus uid fields * (validates the offsets against real data). */ #include <sys/param.h> #include <sys/types.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/systm.h> #include <sys/proc.h> #include <sys/ucred.h> #include <sys/sysctl.h> #include <machine/cpufunc.h> #include <machine/specialreg.h> static int g_pid = 1; static int df3978_msrs_handler(SYSCTL_HANDLER_ARGS) { uint64_t cs, esp, eip; char buf[160]; cs = rdmsr(MSR_SYSENTER_CS); esp = rdmsr(MSR_SYSENTER_ESP); eip = rdmsr(MSR_SYSENTER_EIP); ksnprintf(buf, sizeof(buf), "cs=%#jx esp=%#jx eip=%#jx", (uintmax_t)cs, (uintmax_t)esp, (uintmax_t)eip); return SYSCTL_OUT(req, buf, strlen(buf) + 1); } SYSCTL_PROC(_kern, OID_AUTO, df3978_msrs, CTLTYPE_STRING | CTLFLAG_RD, 0, 0, df3978_msrs_handler, "A", "live SYSENTER MSRs"); static int df3978_pid_handler(SYSCTL_HANDLER_ARGS) { int error, t = g_pid; struct proc *p; error = sysctl_handle_int(oidp, &t, 0, req); if (error == 0 && req->newptr != NULL) { g_pid = t; p = pfind(g_pid); if (p == NULL) { kprintf("DF3978RIG: pid=%d NOT FOUND\n", g_pid); } else { kprintf("DF3978RIG: pid=%d proc=%p ucred=%p uid=%d " "ruid=%d comm=%s OFFp_ucred=%zu OFFcr_uid=%zu " "OFFcr_ruid=%zu OFFcr_svuid=%zu\n", (int)p->p_pid, p, p->p_ucred, (int)p->p_ucred->cr_uid, (int)p->p_ucred->cr_ruid, p->p_comm, (size_t)offsetof(struct proc, p_ucred), (size_t)offsetof(struct ucred, cr_uid), (size_t)offsetof(struct ucred, cr_ruid), (size_t)offsetof(struct ucred, cr_svuid)); } } return (error); } SYSCTL_PROC(_kern, OID_AUTO, df3978_pid, CTLTYPE_INT | CTLFLAG_RW, 0, 0, df3978_pid_handler, "I", "resolve pid via pfind"); static int df3978_modev(module_t mod, int type, void *data) { switch (type) { case MOD_LOAD: kprintf("DF3978RIG: loaded. OFFp_pid=%zu OFFp_ucred=%zu " "OFFp_list=%zu OFFcr_uid=%zu OFFcr_ruid=%zu " "OFFcr_svuid=%zu sizeof_ucred=%zu sizeof_proc=%zu\n", (size_t)offsetof(struct proc, p_pid), (size_t)offsetof(struct proc, p_ucred), (size_t)offsetof(struct proc, p_list), (size_t)offsetof(struct ucred, cr_uid), (size_t)offsetof(struct ucred, cr_ruid), (size_t)offsetof(struct ucred, cr_svuid), (size_t)sizeof(struct ucred), (size_t)sizeof(struct proc)); break; case MOD_UNLOAD: kprintf("DF3978RIG: unloaded\n"); break; default: break; } return 0; } static moduledata_t df3978_mod = { "df3978rig", df3978_modev, NULL }; DECLARE_MODULE(df3978rig, df3978_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); |