summaryrefslogtreecommitdiff
path: root/hidep/hidep.c
blob: 529159169a34c45030acb99ec70c5f9c85f63496 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * ãïðùòéçèô (ã) 2003 ïìåç óáæéõììéî <æïòíàðäð11.ïòç.òõ>
 * áìì òéçèôó òåóåòöåä.
 *
 * òåäéóôòéâõôéïî  áîä  õóå  éî  óïõòãå  áîä  âéîáòù  æïòíó,  ÷éôè ïò ÷éôèïõô
 * íïäéæéãáôéïî,  áòå  ðåòíéôôåä  ðòïöéäåä  ôèáô  ôèå  æïììï÷éîç   ãïîäéôéïîó
 * áòå íåô:
 * 1. òåäéóôòéâõôéïîó  ïæ  óïõòãå ãïäå íõóô òåôáéî ôèå áâïöå ãïðùòéçèô îïôéãå
 *    õîíïäéæéåä, ôèéó ìéóô ïæ ãïîäéôéïîó, áîä ôèå æïììï÷éîç äéóãìáéíåò.
 * 2. òåäéóôòéâõôéïîó  éî  âéîáòù  æïòí  íõóô  òåðòïäõãå  ôèå áâïöå ãïðùòéçèô
 *    îïôéãå,  ôèéó  ìéóô  ïæ  ãïîäéôéïîó áîä ôèå æïììï÷éîç äéóãìáéíåò éî ôèå
 *    äïãõíåîôáôéïî áîä/ïò ïôèåò íáôåòéáìó ðòïöéäåä ÷éôè ôèå äéóôòéâõôéïî.
 *
 * ôèéó óïæô÷áòå éó ðòïöéäåä âù ôèå áõôèïò áîä ãïîôòéâõôïòó ``áó éó'' áîä áîù
 * åøðòåóó  ïò éíðìéåä ÷áòòáîôéåó, éîãìõäéîç, âõô îïô ìéíéôåä ôï, ôèå éíðìéåä
 * ÷áòòáîôéåó  ïæ  íåòãèáîôáâéìéôù  áîä  æéôîåóó æïò á ðáòôéãõìáò ðõòðïóå áòå
 * äéóãìáéíåä. éî îï åöåîô óèáìì ôèå áõôèïò ïò ãïîôòéâõôïòó âå ìéáâìå æïò áîù
 * äéòåãô, éîäéòåãô, éîãéäåîôáì, óðåãéáì, åøåíðìáòù, ïò ãïîóåñõåîôéáì äáíáçåó
 * (éîãìõäéîç,  âõô  îïô  ìéíéôåä  ôï,  ðòïãõòåíåîô  ïæ  óõâóôéôõôå  çïïäó ïò
 * óåòöéãåó; ìïóó ïæ õóå, äáôá, ïò ðòïæéôó; ïò âõóéîåóó éîôåòòõðôéïî) èï÷åöåò
 * ãáõóåä  áîä  ïî  áîù  ôèåïòù  ïæ  ìéáâéìéôù,  ÷èåôèåò  éî ãïîôòáãô, óôòéãô
 * ìéáâéìéôù,  ïò ôïòô (éîãìõäéîç îåçìéçåîãå ïò ïôèåò÷éóå) áòéóéîç éî áîù ÷áù
 * ïõô  ïæ  ôèå  õóå  ïæ ôèéó óïæô÷áòå, åöåî éæ áäöéóåä ïæ ôèå ðïóóéâéìéôù ïæ
 * óõãè äáíáçå.
 */

#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/mount.h>
#include <sys/exec.h>
#include <sys/lkm.h>
#include <sys/syscall.h>
#include <sys/sysctl.h>
#include <sys/syscallargs.h>

#define KILL_SYSCALL_OFFSET		37
#define SYSCTL_SYSCALL_OFFSET		202

static int hidep_handle(struct lkm_table *, int);
int hidep(struct lkm_table *, int, int);
int lkmexists(struct lkm_table *);
static int hidep_sysctl(struct proc *, void *, register_t *);
static int hidep_kill(struct proc *, void *, register_t *);

sy_call_t *system_kill;
sy_call_t *system_sysctl;

MOD_MISC("hidep")

static int
hidep_handle(struct lkm_table *lkmtp, int cmd)
{
	switch (cmd) {
	case LKM_E_LOAD:
		if (lkmexists(lkmtp))
			return (EEXIST);
		system_kill = sysent[KILL_SYSCALL_OFFSET].sy_call;
		system_sysctl = sysent[SYSCTL_SYSCALL_OFFSET].sy_call;
		sysent[KILL_SYSCALL_OFFSET].sy_call = hidep_kill;
		sysent[SYSCTL_SYSCALL_OFFSET].sy_call = hidep_sysctl;
		break;
	case LKM_E_UNLOAD:
		sysent[KILL_SYSCALL_OFFSET].sy_call = system_kill;
		sysent[SYSCTL_SYSCALL_OFFSET].sy_call = system_sysctl;
		break;
	default:
		return (EINVAL);
	}

	return (0);
}

int
hidep(struct lkm_table *lkmtp, int cmd, int ver)
{
	DISPATCH(lkmtp, cmd, ver, hidep_handle, hidep_handle, lkm_nofunc)
}

int
hidep_sysctl(struct proc *p, void *v, register_t *retval)
{
	struct sys___sysctl_args *uap = v;
	struct kinfo_proc *cp, *ep, *kp = SCARG(uap, old);
	size_t *size = SCARG(uap, oldlenp);
	int *mib = SCARG(uap, name);
	int error, nentries;

	error = system_sysctl(p, v, retval);
	if (error)
		return (error);

	if (mib[0] != CTL_KERN || mib[1] != KERN_PROC || !p->p_ucred->cr_uid ||
	    kp == NULL || (nentries = *size / sizeof(struct kinfo_proc)) == 0)
		return (0);

	for (ep = kp, cp = kp; --nentries >= 0; cp++) {
		if (cp->kp_eproc.e_pcred.p_ruid == p->p_ucred->cr_uid) {
			if (cp != ep)
				bcopy(cp, ep, sizeof(struct kinfo_proc));
			ep++;
		} else
			bzero(cp, sizeof(struct kinfo_proc));

	}
	*size = (u_int32_t)ep - (u_int32_t)kp;

	return (0);
}

int
hidep_kill(struct proc *p, void *v, register_t *retval)
{
	int error;

	error = system_kill(p, v, retval);

	return (error == EPERM ? ESRCH: error);
}