⬢ DragonFlyBSD Kernel Audit
DF-5630 / df_osrel.c
← back to finding ↓ download raw
/*
 * DF-5630 KLD harness (root-assisted observability only).
 *
 * sysctl debug.df_osrel_pid=<pid>  — select a process
 * sysctl -n debug.df_osrel_val     — read its struct proc::p_osrel, the
 *                                    field filled from the ELF ABI-note
 *                                    descriptor by bsd_trans_osrel().
 * This makes the (otherwise silent) 4-byte OOB read observable: run the
 * crafted binaries as an unprivileged user, then read p_osrel as root.
 */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
#include <sys/types.h>

static int target_pid = 0;
SYSCTL_INT(_debug, OID_AUTO, df_osrel_pid, CTLFLAG_RW, &target_pid, 0,
    "pid whose p_osrel to expose");

struct osrel_arg {
	int pid;
	int found;
	int val;
};

static int
osrel_cb(struct proc *p, void *data)
{
	struct osrel_arg *a = data;

	if (p->p_pid == (pid_t)a->pid) {
		a->found = 1;
		a->val = p->p_osrel;
		return (-1);
	}
	return (0);
}

static int
sysctl_df_osrel(SYSCTL_HANDLER_ARGS)
{
	struct osrel_arg a;
	int val;

	a.pid = target_pid;
	a.found = 0;
	a.val = -1;
	if (a.pid > 0)
		allproc_scan(osrel_cb, &a, 0);
	val = a.found ? a.val : -1;

	return (SYSCTL_OUT(req, &val, sizeof(val)));
}

SYSCTL_PROC(_debug, OID_AUTO, df_osrel_val, CTLTYPE_INT | CTLFLAG_RD,
    0, 0, sysctl_df_osrel, "I", "p_osrel of debug.df_osrel_pid");