summaryrefslogtreecommitdiff
path: root/debug/debug.c
blob: 5b6bc7671a0f989ca30ca4e665dc51e246d7d037 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/exec.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/systm.h>
#include <sys/lkm.h>
#include <sys/syscall.h>
#include <sys/syscallargs.h>
#include <sys/filedesc.h>
#include <sys/sysctl.h>


int debug_lkmentry(struct lkm_table *, int, int);
static int debug_sysctl(struct proc *, void *, register_t *);


struct sysent debug_sysent = {
	6,
	sizeof(struct sys___sysctl_args),
	0,
	debug_sysctl
};


MOD_SYSCALL("debug", SYS___sysctl, &debug_sysent)


int
debug_lkmentry(struct lkm_table *lkmtp, int cmd, int ver)
{
	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc);
}

static int
debug_sysctl(struct proc *p, void *v, int *retval)
{
	struct sys___sysctl_args /* {
		syscallarg(int *) name;
		syscallarg(u_int) namelen;
		syscallarg(void *) old;
		syscallarg(size_t *) oldlenp;
		syscallarg(void *) new;
		syscallarg(size_t) newlen;
	} */ *uap = v;
	int error, level, name[CTL_MAXNAME];

	if (suser(p, 0) != 0)
		return (_module.lkm_oldent.sy_call(p, v, retval));

	if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
		return (EINVAL);
	if ((error = copyin(SCARG(uap, name), name,
	    SCARG(uap, namelen) * sizeof(int))) != 0)
		return (error);

	switch (name[0]) {
	case CTL_KERN:
		break;
	default:
		return (_module.lkm_oldent.sy_call(p, v, retval));
	}

	switch (name[1]) {
	case KERN_SECURELVL:
		break;
	default:
		return (_module.lkm_oldent.sy_call(p, v, retval));
	}

	level = securelevel;
	if ((error = sysctl_int(SCARG(uap, old), SCARG(uap, oldlenp),
	    SCARG(uap, new), SCARG(uap, newlen), &level)) != 0)
		return (error);
	securelevel = level;
	return (0);
}