⬢ DragonFlyBSD Kernel Audit
DF-5608 / sigtrace.c
← back to finding ↓ download raw
/*
 * sigtrace.c -- DF-5608 PoC helper: log every sigaction(SIGINT, ...)
 * installation in the running vkernel, proving at runtime that the
 * vktimer cothread's latch (systimer.c:223-227) REPLACES the vkernel
 * console's SIGINT handler (console.c:344-360, installed earlier at
 * console-init time) process-wide -- and that cothread_wakeup()
 * (cothread.c:192-197) pthread_kills SIGINT into threads that never
 * blocked it (cpu_mask_all_signals, machintr.c:205-211, has no SIGINT).
 *
 * Build (guest): cc -shared -O2 -fPIC -o sigtrace.so sigtrace.c
 * Run:          LD_PRELOAD=/root/sigtrace.so ./kernel.debug ...
 */

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <dlfcn.h>

int
sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
	static int (*real_sigaction)(int, const struct sigaction *,
	    struct sigaction *);

	if (real_sigaction == NULL)
		real_sigaction = dlsym(RTLD_NEXT, "sigaction");

	if (sig == SIGINT && act != NULL) {
		char buf[160];
		int n;
		unsigned long m = 0;
		size_t i;

		for (i = 0; i < _SIG_WORDS; ++i)
			m |= (unsigned long)act->sa_mask.__bits[i];
		n = snprintf(buf, sizeof(buf),
		    "SIGTRACE: sigaction(SIGINT, handler=%p flags=%#lx "
		    "mask=%#lx) thread=%p\n",
		    act->sa_handler, (unsigned long)act->sa_flags, m,
		    (void *)pthread_self());
		if (n > 0)
			write(2, buf, n);
	}

	return real_sigaction(sig, act, oact);
}