/[linux-patches]/hardened/2.6/trunk/2.6.17/6001_systrace-2.6.16.patch
Gentoo

Contents of /hardened/2.6/trunk/2.6.17/6001_systrace-2.6.16.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 555 - (show annotations) (download)
Sun Jul 16 14:08:30 2006 UTC (8 years ago) by phreak
File size: 74002 byte(s)
Fixing remaining reject in 6001_systrace-2.6.16.patch, thanks dragonheart for the headsup
1 Index: linux-2.6.17/arch/i386/kernel/entry.S
2 ===================================================================
3 --- linux-2.6.17.orig/arch/i386/kernel/entry.S
4 +++ linux-2.6.17/arch/i386/kernel/entry.S
5 @@ -1,6 +1,6 @@
6 /*
7 * linux/arch/i386/entry.S
8 - *
9 +. *
10 * Copyright (C) 1991, 1992 Linus Torvalds
11 */
12
13 @@ -233,8 +233,23 @@ sysenter_past_esp:
14 jnz syscall_trace_entry
15 cmpl $(nr_syscalls), %eax
16 jae syscall_badsys
17 +#ifdef CONFIG_SYSTRACE
18 + movl %esp,%eax
19 + call systrace_intercept
20 + cmpl $0,%eax
21 + jl ret1
22 + movl ORIG_EAX(%esp),%eax
23 +#endif /* CONFIG_SYSTRACE */
24 call *sys_call_table(,%eax,4)
25 +#ifdef CONFIG_SYSTRACE
26 + ret1:
27 +#endif /* CONFIG_SYSTRACE */
28 movl %eax,EAX(%esp)
29 +#ifdef CONFIG_SYSTRACE
30 + movl %esp,%eax # pass in stack
31 + call systrace_result
32 + movl EAX(%esp),%eax # XXX: ?to be on the safe side
33 +#endif /* CONFIG_SYSTRACE */
34 cli
35 movl TI_flags(%ebp), %ecx
36 testw $_TIF_ALLWORK_MASK, %cx
37 @@ -282,9 +297,25 @@ no_singlestep:
38 jnz syscall_trace_entry
39 cmpl $(nr_syscalls), %eax
40 jae syscall_badsys
41 +#ifdef CONFIG_SYSTRACE
42 + movl %esp,%eax
43 + call systrace_intercept
44 + cmpl $0,%eax
45 + jl ret
46 + movl ORIG_EAX(%esp),%eax
47 +#endif /* CONFIG_SYSTRACE */
48 syscall_call:
49 call *sys_call_table(,%eax,4)
50 +#ifdef CONFIG_SYSTRACE
51 + ret:
52 +#endif /* CONFIG_SYSTRACE */
53 movl %eax,EAX(%esp) # store the return value
54 +#ifdef CONFIG_SYSTRACE
55 + movl %esp,%eax # pass in stack
56 + call systrace_result
57 + movl EAX(%esp),%eax # XXX: ?to be on the safe side
58 +#endif /* CONFIG_SYSTRACE */
59 +
60 syscall_exit:
61 cli # make sure we don't miss an interrupt
62 # setting need_resched or sigpending
63 Index: linux-2.6.17/drivers/Makefile
64 ===================================================================
65 --- linux-2.6.17.orig/drivers/Makefile
66 +++ linux-2.6.17/drivers/Makefile
67 @@ -66,6 +66,7 @@ obj-$(CONFIG_EDAC) += edac/
68 obj-$(CONFIG_MCA) += mca/
69 obj-$(CONFIG_EISA) += eisa/
70 obj-$(CONFIG_CPU_FREQ) += cpufreq/
71 +obj-$(CONFIG_SYSTRACE) += systrace/
72 obj-$(CONFIG_MMC) += mmc/
73 obj-$(CONFIG_NEW_LEDS) += leds/
74 obj-$(CONFIG_INFINIBAND) += infiniband/
75 Index: linux-2.6.17/drivers/systrace/Kconfig
76 ===================================================================
77 --- /dev/null
78 +++ linux-2.6.17/drivers/systrace/Kconfig
79 @@ -0,0 +1,7 @@
80 +config SYSTRACE
81 + bool "Systrace support"
82 + help
83 + This enables systrace support. See http://www.systrace.org/ for details.
84 +
85 + Also enable Default Linux Capabilites (CONFIG_SECURITY_CAPABILITIES)!
86 +
87 Index: linux-2.6.17/drivers/systrace/Makefile
88 ===================================================================
89 --- /dev/null
90 +++ linux-2.6.17/drivers/systrace/Makefile
91 @@ -0,0 +1 @@
92 +obj-y := systrace.o policy.o linux_sysent.o
93 Index: linux-2.6.17/drivers/systrace/linux_sysent.c
94 ===================================================================
95 --- /dev/null
96 +++ linux-2.6.17/drivers/systrace/linux_sysent.c
97 @@ -0,0 +1,296 @@
98 +/*
99 + * file taken from openbsd's compat/linux/linux_sysent.c
100 + */
101 +
102 +/* $OpenBSD: linux_sysent.c,v 1.36 2002/06/05 19:43:44 jasoni Exp $ */
103 +
104 +
105 +#include <linux/sched.h>
106 +#include <linux/smp_lock.h>
107 +#include <linux/mm.h>
108 +#include <linux/pagemap.h>
109 +#include <linux/fs.h>
110 +#include <linux/wait.h>
111 +#include <linux/queue.h>
112 +
113 +#include <asm/uaccess.h>
114 +#include <asm/ptrace.h>
115 +#include <asm/semaphore.h>
116 +
117 +#include <linux/systrace.h>
118 +
119 +/* #define s(type) sizeof(type) */
120 +#define s(type) 0
121 +
122 +struct sysent linux_sysent[] = {
123 + { 0, 0 }, /* 0 = syscall */
124 + { 1, s(struct sys_exit_args) }, /* 1 = exit */
125 + { 0, 0 }, /* 2 = fork */
126 + { 3, s(struct sys_read_args) }, /* 3 = read */
127 + { 3, s(struct sys_write_args) }, /* 4 = write */
128 + { 3, s(struct linux_sys_open_args) }, /* 5 = open */
129 + { 1, s(struct sys_close_args) }, /* 6 = close */
130 + { 3, s(struct linux_sys_waitpid_args) }, /* 7 = waitpid */
131 + { 2, s(struct linux_sys_creat_args) }, /* 8 = creat */
132 + { 2, s(struct sys_link_args) }, /* 9 = link */
133 + { 1, s(struct linux_sys_unlink_args) }, /* 10 = unlink */
134 + { 3, s(struct linux_sys_execve_args) }, /* 11 = execve */
135 + { 1, s(struct linux_sys_chdir_args) }, /* 12 = chdir */
136 + { 1, s(struct linux_sys_time_args) }, /* 13 = time */
137 + { 3, s(struct linux_sys_mknod_args) }, /* 14 = mknod */
138 + { 2, s(struct linux_sys_chmod_args) }, /* 15 = chmod */
139 + { 3, s(struct linux_sys_lchown16_args) }, /* 16 = lchown16 */
140 + { 1, s(struct linux_sys_break_args) }, /* 17 = break */
141 + { 0, 0 }, /* 18 = ostat */
142 + { 3, s(struct compat_43_sys_lseek_args) }, /* 19 = lseek */
143 + { 0, 0 }, /* 20 = getpid */
144 + { 5, s(struct linux_sys_mount_args) }, /* 21 = mount */
145 + { 1, s(struct linux_sys_umount_args) }, /* 22 = umount */
146 + { 1, s(struct sys_setuid_args) }, /* 23 = linux_setuid16 */
147 + { 0, 0 }, /* 24 = linux_getuid16 */
148 + { 1, s(struct linux_sys_stime_args) }, /* 25 = stime */
149 + { 0, 0 }, /* 26 = unimplemented ptrace */
150 + { 1, s(struct linux_sys_alarm_args) }, /* 27 = alarm */
151 + { 0, 0 }, /* 28 = ofstat */
152 + { 0, 0 }, /* 29 = pause */
153 + { 2, s(struct linux_sys_utime_args) }, /* 30 = utime */
154 + { 0, 0 }, /* 31 = stty */
155 + { 0, 0 }, /* 32 = gtty */
156 + { 2, s(struct linux_sys_access_args) }, /* 33 = access */
157 + { 1, s(struct linux_sys_nice_args) }, /* 34 = nice */
158 + { 0, 0 }, /* 35 = ftime */
159 + { 0, 0 }, /* 36 = sync */
160 + { 2, s(struct linux_sys_kill_args) }, /* 37 = kill */
161 + { 2, s(struct linux_sys_rename_args) }, /* 38 = rename */
162 + { 2, s(struct linux_sys_mkdir_args) }, /* 39 = mkdir */
163 + { 1, s(struct linux_sys_rmdir_args) }, /* 40 = rmdir */
164 + { 1, s(struct sys_dup_args) }, /* 41 = dup */
165 + { 1, s(struct linux_sys_pipe_args) }, /* 42 = pipe */
166 + { 1, s(struct linux_sys_times_args) }, /* 43 = times */
167 + { 0, 0 }, /* 44 = prof */
168 + { 1, s(struct linux_sys_brk_args) }, /* 45 = brk */
169 + { 1, s(struct sys_setgid_args) }, /* 46 = linux_setgid16 */
170 + { 0, 0 }, /* 47 = linux_getgid16 */
171 + { 2, s(struct linux_sys_signal_args) }, /* 48 = signal */
172 + { 0, 0 }, /* 49 = linux_geteuid16 */
173 + { 0, 0 }, /* 50 = linux_getegid16 */
174 + { 1, s(struct sys_acct_args) }, /* 51 = acct */
175 + { 0, 0 }, /* 52 = phys */
176 + { 0, 0 }, /* 53 = lock */
177 + { 3, s(struct linux_sys_ioctl_args) }, /* 54 = ioctl */
178 + { 3, s(struct linux_sys_fcntl_args) }, /* 55 = fcntl */
179 + { 0, 0 }, /* 56 = mpx */
180 + { 2, s(struct sys_setpgid_args) }, /* 57 = setpgid */
181 + { 0, 0 }, /* 58 = ulimit */
182 + { 1, s(struct linux_sys_oldolduname_args) }, /* 59 = oldolduname */
183 + { 1, s(struct sys_umask_args) }, /* 60 = umask */
184 + { 1, s(struct sys_chroot_args) }, /* 61 = chroot */
185 + { 0, 0 }, /* 62 = ustat */
186 + { 2, s(struct sys_dup2_args) }, /* 63 = dup2 */
187 + { 0, 0 }, /* 64 = getppid */
188 + { 0, 0 }, /* 65 = getpgrp */
189 + { 0, 0 }, /* 66 = setsid */
190 + { 3, s(struct linux_sys_sigaction_args) }, /* 67 = sigaction */
191 + { 0, 0 }, /* 68 = siggetmask */
192 + { 1, s(struct linux_sys_sigsetmask_args) }, /* 69 = sigsetmask */
193 + { 2, s(struct linux_sys_setreuid16_args) }, /* 70 = setreuid16 */
194 + { 2, s(struct linux_sys_setregid16_args) }, /* 71 = setregid16 */
195 + { 3, s(struct linux_sys_sigsuspend_args) }, /* 72 = sigsuspend */
196 + { 1, s(struct linux_sys_sigpending_args) }, /* 73 = sigpending */
197 + { 2, s(struct compat_43_sys_sethostname_args) }, /* 74 = sethostname */
198 + { 2, s(struct linux_sys_setrlimit_args) }, /* 75 = setrlimit */
199 + { 2, s(struct linux_sys_getrlimit_args) }, /* 76 = getrlimit */
200 + { 2, s(struct sys_getrusage_args) }, /* 77 = getrusage */
201 + { 2, s(struct sys_gettimeofday_args) }, /* 78 = gettimeofday */
202 + { 2, s(struct sys_settimeofday_args) }, /* 79 = settimeofday */
203 + { 2, s(struct sys_getgroups_args) }, /* 80 = linux_getgroups */
204 + { 2, s(struct sys_setgroups_args) }, /* 81 = linux_setgroups */
205 + { 1, s(struct linux_sys_oldselect_args) }, /* 82 = oldselect */
206 + { 2, s(struct linux_sys_symlink_args) }, /* 83 = symlink */
207 + { 2, s(struct compat_43_sys_lstat_args) }, /* 84 = olstat */
208 + { 3, s(struct linux_sys_readlink_args) }, /* 85 = readlink */
209 + { 1, s(struct linux_sys_uselib_args) }, /* 86 = uselib */
210 + { 1, s(struct sys_swapon_args) }, /* 87 = swapon */
211 + { 1, s(struct sys_reboot_args) }, /* 88 = reboot */
212 + { 3, s(struct linux_sys_readdir_args) }, /* 89 = readdir */
213 + { 1, s(struct linux_sys_mmap_args) }, /* 90 = mmap */
214 + { 2, s(struct sys_munmap_args) }, /* 91 = munmap */
215 + { 2, s(struct linux_sys_truncate_args) }, /* 92 = truncate */
216 + { 2, s(struct compat_43_sys_ftruncate_args) }, /* 93 = ftruncate */
217 + { 2, s(struct sys_fchmod_args) }, /* 94 = fchmod */
218 + { 3, s(struct linux_sys_fchown16_args) }, /* 95 = fchown16 */
219 + { 2, s(struct sys_getpriority_args) }, /* 96 = getpriority */
220 + { 3, s(struct sys_setpriority_args) }, /* 97 = setpriority */
221 + { 4, s(struct sys_profil_args) }, /* 98 = profil */
222 + { 2, s(struct linux_sys_statfs_args) }, /* 99 = statfs */
223 + { 2, s(struct linux_sys_fstatfs_args) }, /* 100 = fstatfs */
224 +#ifdef __i386__
225 + { 3, s(struct linux_sys_ioperm_args) }, /* 101 = ioperm */
226 +#else
227 + { 0, 0 }, /* 101 = ioperm */
228 +#endif
229 + { 2, s(struct linux_sys_socketcall_args) }, /* 102 = socketcall */
230 + { 0, 0 }, /* 103 = klog */
231 + { 3, s(struct sys_setitimer_args) }, /* 104 = setitimer */
232 + { 2, s(struct sys_getitimer_args) }, /* 105 = getitimer */
233 + { 2, s(struct linux_sys_stat_args) }, /* 106 = stat */
234 + { 2, s(struct linux_sys_lstat_args) }, /* 107 = lstat */
235 + { 2, s(struct linux_sys_fstat_args) }, /* 108 = fstat */
236 + { 1, s(struct linux_sys_olduname_args) }, /* 109 = olduname */
237 +#ifdef __i386__
238 + { 1, s(struct linux_sys_iopl_args) }, /* 110 = iopl */
239 +#else
240 + { 0, 0 }, /* 110 = iopl */
241 +#endif
242 + { 0, 0 }, /* 111 = vhangup */
243 + { 0, 0 }, /* 112 = idle */
244 + { 0, 0 }, /* 113 = vm86old */
245 + { 4, s(struct linux_sys_wait4_args) }, /* 114 = wait4 */
246 + { 0, 0 }, /* 115 = swapoff */
247 + { 0, 0 }, /* 116 = sysinfo */
248 + { 5, s(struct linux_sys_ipc_args) }, /* 117 = ipc */
249 + { 1, s(struct sys_fsync_args) }, /* 118 = fsync */
250 + { 1, s(struct linux_sys_sigreturn_args) }, /* 119 = sigreturn */
251 + { 2, s(struct linux_sys_clone_args) }, /* 120 = clone */
252 + { 2, s(struct compat_09_sys_setdomainname_args) }, /* 121 = setdomainname */
253 + { 1, s(struct linux_sys_uname_args) }, /* 122 = uname */
254 +#ifdef __i386__
255 + { 3, s(struct linux_sys_modify_ldt_args) }, /* 123 = modify_ldt */
256 +#else
257 + { 0, 0 }, /* 123 = modify_ldt */
258 +#endif
259 + { 0, 0 }, /* 124 = adjtimex */
260 + { 3, s(struct sys_mprotect_args) }, /* 125 = mprotect */
261 + { 3, s(struct linux_sys_sigprocmask_args) }, /* 126 = sigprocmask */
262 + { 0, 0 }, /* 127 = create_module */
263 + { 0, 0 }, /* 128 = init_module */
264 + { 0, 0 }, /* 129 = delete_module */
265 + { 0, 0 }, /* 130 = get_kernel_syms */
266 + { 0, 0 }, /* 131 = quotactl */
267 + { 1, s(struct linux_sys_getpgid_args) }, /* 132 = getpgid */
268 + { 1, s(struct sys_fchdir_args) }, /* 133 = fchdir */
269 + { 0, 0 }, /* 134 = bdflush */
270 + { 0, 0 }, /* 135 = sysfs */
271 + { 1, s(struct linux_sys_personality_args) }, /* 136 = personality */
272 + { 0, 0 }, /* 137 = afs_syscall */
273 + { 1, s(struct linux_sys_setfsuid_args) }, /* 138 = linux_setfsuid16 */
274 + { 0, 0 }, /* 139 = linux_getfsuid16 */
275 + { 5, s(struct linux_sys_llseek_args) }, /* 140 = llseek */
276 + { 3, s(struct linux_sys_getdents_args) }, /* 141 = getdents */
277 + { 5, s(struct linux_sys_select_args) }, /* 142 = select */
278 + { 2, s(struct sys_flock_args) }, /* 143 = flock */
279 + { 3, s(struct sys_msync_args) }, /* 144 = msync */
280 + { 3, s(struct sys_readv_args) }, /* 145 = readv */
281 + { 3, s(struct sys_writev_args) }, /* 146 = writev */
282 + { 1, s(struct linux_sys_getsid_args) }, /* 147 = getsid */
283 + { 1, s(struct linux_sys_fdatasync_args) }, /* 148 = fdatasync */
284 + { 1, s(struct linux_sys___sysctl_args) }, /* 149 = __sysctl */
285 + { 2, s(struct sys_mlock_args) }, /* 150 = mlock */
286 + { 2, s(struct sys_munlock_args) }, /* 151 = munlock */
287 + { 0, 0 }, /* 152 = mlockall */
288 + { 0, 0 }, /* 153 = munlockall */
289 + { 2, s(struct linux_sys_sched_setparam_args) }, /* 154 = sched_setparam */
290 + { 2, s(struct linux_sys_sched_getparam_args) }, /* 155 = sched_getparam */
291 + { 3, s(struct linux_sys_sched_setscheduler_args) }, /* 156 = sched_setscheduler */
292 + { 1, s(struct linux_sys_sched_getscheduler_args) }, /* 157 = sched_getscheduler */
293 + { 0, 0 }, /* 158 = sched_yield */
294 + { 1, s(struct linux_sys_sched_get_priority_max_args) }, /* 159 = sched_get_priority_max */
295 + { 1, s(struct linux_sys_sched_get_priority_min_args) }, /* 160 = sched_get_priority_min */
296 + { 0, 0 }, /* 161 = sched_rr_get_interval */
297 + { 2, s(struct sys_nanosleep_args) }, /* 162 = nanosleep */
298 + { 4, s(struct linux_sys_mremap_args) }, /* 163 = mremap */
299 + { 3, s(struct linux_sys_setresuid16_args) }, /* 164 = setresuid16 */
300 + { 3, s(struct linux_sys_getresuid_args) }, /* 165 = linux_getresuid16 */
301 + { 0, 0 }, /* 166 = vm86 */
302 + { 0, 0 }, /* 167 = query_module */
303 + { 3, s(struct sys_poll_args) }, /* 168 = poll */
304 + { 0, 0 }, /* 169 = nfsservctl */
305 + { 3, s(struct linux_sys_setresgid16_args) }, /* 170 = setresgid16 */
306 + { 3, s(struct linux_sys_getresgid16_args) }, /* 171 = getresgid16 */
307 + { 0, 0 }, /* 172 = prctl */
308 + { 1, s(struct linux_sys_rt_sigreturn_args) }, /* 173 = rt_sigreturn */
309 + { 4, s(struct linux_sys_rt_sigaction_args) }, /* 174 = rt_sigaction */
310 + { 4, s(struct linux_sys_rt_sigprocmask_args) }, /* 175 = rt_sigprocmask */
311 + { 2, s(struct linux_sys_rt_sigpending_args) }, /* 176 = rt_sigpending */
312 + { 0, 0 }, /* 177 = rt_sigtimedwait */
313 + { 0, 0 }, /* 178 = rt_queueinfo */
314 + { 2, s(struct linux_sys_rt_sigsuspend_args) }, /* 179 = rt_sigsuspend */
315 + { 4, s(struct linux_sys_pread_args) }, /* 180 = pread */
316 + { 4, s(struct linux_sys_pwrite_args) }, /* 181 = pwrite */
317 + { 3, s(struct linux_sys_chown16_args) }, /* 182 = chown16 */
318 + { 2, s(struct linux_sys_getcwd_args) }, /* 183 = getcwd */
319 + { 0, 0 }, /* 184 = capget */
320 + { 0, 0 }, /* 185 = capset */
321 + { 2, s(struct linux_sys_sigaltstack_args) }, /* 186 = sigaltstack */
322 + { 0, 0 }, /* 187 = sendfile */
323 + { 0, 0 }, /* 188 = getpmsg */
324 + { 0, 0 }, /* 189 = putpmsg */
325 + { 0, 0 }, /* 190 = vfork */
326 + { 2, s(struct linux_sys_ugetrlimit_args) }, /* 191 = ugetrlimit */
327 + { 0, 0 }, /* 192 = mmap2 */
328 + { 2, s(struct linux_sys_truncate64_args) }, /* 193 = truncate64 */
329 + { 2, s(struct sys_ftruncate_args) }, /* 194 = linux_ftruncate64 */
330 + { 2, s(struct linux_sys_stat64_args) }, /* 195 = stat64 */
331 + { 2, s(struct linux_sys_lstat64_args) }, /* 196 = lstat64 */
332 + { 2, s(struct linux_sys_fstat64_args) }, /* 197 = fstat64 */
333 + { 0, 0 }, /* 198 = lchown */
334 + { 0, 0 }, /* 199 = getuid */
335 + { 0, 0 }, /* 200 = getgid */
336 + { 0, 0 }, /* 201 = geteuid */
337 + { 0, 0 }, /* 202 = getegid */
338 + { 0, 0 }, /* 203 = setreuid */
339 + { 0, 0 }, /* 204 = setregid */
340 + { 2, s(struct sys_getgroups_args) }, /* 205 = getgroups */
341 + { 2, s(struct sys_setgroups_args) }, /* 206 = setgroups */
342 + { 0, 0 }, /* 207 = fchown */
343 + { 0, 0 }, /* 208 = setresuid */
344 + { 3, s(struct linux_sys_getresuid_args) }, /* 209 = getresuid */
345 + { 0, 0 }, /* 210 = setresgid */
346 + { 0, 0 }, /* 211 = getresgid */
347 + { 0, 0 }, /* 212 = chown */
348 + { 1, s(struct sys_setuid_args) }, /* 213 = setuid */
349 + { 1, s(struct sys_setgid_args) }, /* 214 = setgid */
350 + { 1, s(struct linux_sys_setfsuid_args) }, /* 215 = setfsuid */
351 + { 0, 0 }, /* 216 = setfsgid */
352 + { 0, 0 }, /* 217 = pivot_root */
353 + { 0, 0 }, /* 218 = mincore */
354 + { 0, 0 }, /* 219 = madvise */
355 + { 0, 0 }, /* 220 = getdents64 */
356 + { 3, s(struct linux_sys_fcntl64_args) }, /* 221 = fcntl64 */
357 + /* XXX These need to be filled out */
358 + { 0, 0 }, /* 222 */
359 + { 0, 0 }, /* 223 */
360 + { 0, 0 }, /* 224 */
361 + { 0, 0 }, /* 225 */
362 + { 0, 0 }, /* 226 */
363 + { 0, 0 }, /* 227 */
364 + { 0, 0 }, /* 228 */
365 + { 0, 0 }, /* 229 */
366 + { 0, 0 }, /* 230 */
367 + { 0, 0 }, /* 231 */
368 + { 0, 0 }, /* 232 */
369 + { 0, 0 }, /* 233 */
370 + { 0, 0 }, /* 234 */
371 + { 0, 0 }, /* 235 */
372 + { 0, 0 }, /* 236 */
373 + { 0, 0 }, /* 237 */
374 + { 0, 0 }, /* 238 */
375 + { 0, 0 }, /* 239 */
376 + { 0, 0 }, /* 240 */
377 + { 0, 0 }, /* 241 */
378 + { 0, 0 }, /* 242 */
379 + { 0, 0 }, /* 243 */
380 + { 0, 0 }, /* 244 */
381 + { 0, 0 }, /* 245 */
382 + { 0, 0 }, /* 246 */
383 + { 0, 0 }, /* 247 */
384 + { 0, 0 }, /* 248 */
385 + { 0, 0 }, /* 249 */
386 + { 0, 0 }, /* 250 */
387 + { 0, 0 }, /* 251 */
388 + { 0, 0 }, /* 252 */
389 + { 0, 0 }, /* 253 */
390 + { 0, 0 }, /* 254 */
391 + { 0, 0 }, /* 255 */
392 + { 0, 0 }, /* 256 */
393 +};
394 Index: linux-2.6.17/drivers/systrace/policy.c
395 ===================================================================
396 --- /dev/null
397 +++ linux-2.6.17/drivers/systrace/policy.c
398 @@ -0,0 +1,159 @@
399 +/*
400 + * policy.c
401 + *
402 + * Copyright (c) 2002 Marius Aamodt Eriksen <marius@umich.edu>
403 + * Copyright (c) 2002 Niels Provos <provos@citi.umich.edu>
404 + *
405 + * Redistribution and use in source and binary forms, with or without
406 + * modification, are permitted provided that the following conditions
407 + * are met:
408 + *
409 + * 1. Redistributions of source code must retain the above copyright
410 + * notice, this list of conditions and the following disclaimer.
411 + * 2. Redistributions in binary form must reproduce the above copyright
412 + * notice, this list of conditions and the following disclaimer in the
413 + * documentation and/or other materials provided with the distribution.
414 + * 3. The names of the copyright holders may not be used to endorse or
415 + * promote products derived from this software without specific
416 + * prior written permission.
417 + *
418 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
419 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
420 + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
421 + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
422 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
423 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
424 + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
425 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
426 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
427 + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
428 + */
429 +
430 +#include <linux/sched.h>
431 +#include <linux/smp_lock.h>
432 +#include <linux/mm.h>
433 +#include <linux/pagemap.h>
434 +#include <linux/fs.h>
435 +#include <linux/wait.h>
436 +#include <linux/slab.h>
437 +#include <linux/queue.h>
438 +
439 +#include <asm/semaphore.h>
440 +#include <asm/uaccess.h>
441 +#include <asm/ptrace.h>
442 +
443 +#include <linux/queue.h>
444 +#include <linux/systrace.h>
445 +
446 +#include "systrace-private.h"
447 +
448 +extern int systrace_debug;
449 +
450 +int
451 +systrace_policy(struct fsystrace *fst, struct systrace_policy *pol)
452 +{
453 + struct str_policy *strpol;
454 + struct str_process *strp;
455 +
456 + switch(pol->strp_op) {
457 + case SYSTR_POLICY_NEW:
458 + DPRINTF(("%s: new, ents %d\n", __func__, pol->strp_maxents));
459 +
460 + if (pol->strp_maxents <= 0 || pol->strp_maxents > 1024)
461 + return (-EINVAL);
462 + strpol = systrace_newpolicy(fst, pol->strp_maxents);
463 + if (strpol == NULL)
464 + return (-ENOBUFS);
465 + pol->strp_num = strpol->nr;
466 + break;
467 + case SYSTR_POLICY_ASSIGN:
468 + DPRINTF(("%s: %d -> pid %d\n", __func__,
469 + pol->strp_num, pol->strp_pid));
470 +
471 + /* Find right policy by number */
472 + TAILQ_FOREACH(strpol, &fst->policies, next)
473 + if (strpol->nr == pol->strp_num)
474 + break;
475 + if (strpol == NULL)
476 + return (-EINVAL);
477 +
478 + strp = systrace_findpid(fst, pol->strp_pid);
479 + if (strp == NULL)
480 + return (-EINVAL);
481 +
482 + if (strp->policy != NULL)
483 + systrace_closepolicy(fst, strp->policy);
484 + strp->policy = strpol;
485 + strpol->refcount++;
486 + break;
487 + case SYSTR_POLICY_MODIFY:
488 + DPRINTF(("%s: %d: code %d -> policy %d\n", __func__,
489 + pol->strp_num, pol->strp_code, pol->strp_policy));
490 +
491 + if (!POLICY_VALID(pol->strp_policy) && pol->strp_policy >= 0)
492 + return (-EINVAL);
493 + TAILQ_FOREACH(strpol, &fst->policies, next)
494 + if (strpol->nr == pol->strp_num)
495 + break;
496 + if (strpol == NULL)
497 + return (-EINVAL);
498 + if (pol->strp_code < 0 || pol->strp_code >= strpol->nsysent)
499 + return (-EINVAL);
500 + strpol->sysent[pol->strp_code] = pol->strp_policy;
501 + break;
502 + default:
503 + return (-EINVAL);
504 + }
505 +
506 + return (0);
507 +}
508 +
509 +struct str_policy *
510 +systrace_newpolicy(struct fsystrace *fst, int maxents)
511 +{
512 + struct str_policy *pol;
513 + int i;
514 +
515 + if (fst->npolicies > SYSTR_MAX_POLICIES /* && !fst->issuser */)
516 + return (NULL);
517 +
518 + if ((pol = kmalloc(sizeof(*pol), GFP_KERNEL)) == NULL)
519 + return (NULL);
520 +
521 + DPRINTF(("%s: allocating %d -> %lu\n", __func__,
522 + maxents, (u_long)maxents * sizeof(int)));
523 +
524 + memset(pol, 0, sizeof(*pol));
525 +
526 + if ((pol->sysent = kmalloc(maxents * sizeof(short), GFP_KERNEL)) == NULL) {
527 + kfree(pol);
528 + return (NULL);
529 + }
530 + pol->nsysent = maxents;
531 + for (i = 0; i < maxents; i++)
532 + pol->sysent[i] = SYSTR_POLICY_ASK;
533 +
534 + fst->npolicies++;
535 + pol->nr = fst->npolicynr++;
536 + pol->refcount = 1;
537 +
538 + TAILQ_INSERT_TAIL(&fst->policies, pol, next);
539 +
540 + return (pol);
541 +}
542 +
543 +void
544 +systrace_closepolicy(struct fsystrace *fst, struct str_policy *policy)
545 +{
546 + if (--policy->refcount)
547 + return;
548 +
549 + fst->npolicies--;
550 +
551 + if (policy->nsysent)
552 + kfree(policy->sysent);
553 +
554 + TAILQ_REMOVE(&fst->policies, policy, next);
555 +
556 + kfree(policy);
557 +}
558 Index: linux-2.6.17/drivers/systrace/systrace-private.h
559 ===================================================================
560 --- /dev/null
561 +++ linux-2.6.17/drivers/systrace/systrace-private.h
562 @@ -0,0 +1,144 @@
563 +/*
564 + * systrace-private.h
565 + *
566 + * Copyright (c) 2002 Marius Aamodt Eriksen <marius@umich.edu>
567 + * Copyright (c) 2002 Niels Provos <provos@citi.umich.edu>
568 + *
569 + * Redistribution and use in source and binary forms, with or without
570 + * modification, are permitted provided that the following conditions
571 + * are met:
572 + *
573 + * 1. Redistributions of source code must retain the above copyright
574 + * notice, this list of conditions and the following disclaimer.
575 + * 2. Redistributions in binary form must reproduce the above copyright
576 + * notice, this list of conditions and the following disclaimer in the
577 + * documentation and/or other materials provided with the distribution.
578 + * 3. The names of the copyright holders may not be used to endorse or
579 + * promote products derived from this software without specific
580 + * prior written permission.
581 + *
582 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
583 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
584 + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
585 + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
586 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
587 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
588 + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
589 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
590 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
591 + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
592 + */
593 +
594 +#ifndef SYSTRACE_PRIVATE_H
595 +#define SYSTRACE_PRIVATE_H
596 +
597 +#define POLICY_VALID(x) ((x) == SYSTR_POLICY_PERMIT || \
598 + (x) == SYSTR_POLICY_ASK || \
599 + (x) == SYSTR_POLICY_NEVER)
600 +
601 +#define DPRINTF(x) if (systrace_debug) printk x
602 +
603 +struct str_policy {
604 + int nr;
605 + struct emul *emul; /* XXX */
606 + int refcount;
607 + int nsysent;
608 + short *sysent;
609 + TAILQ_ENTRY(str_policy) next;
610 +};
611 +
612 +#define STR_PROC_ONQUEUE 0x01
613 +#define STR_PROC_WAITANSWER 0x02
614 +#define STR_PROC_SYSCALLRES 0x04
615 +#define STR_PROC_REPORT 0x08 /* Report emulation */
616 +#define STR_PROC_FSCHANGE 0x10
617 +#define STR_PROC_SETEUID 0x20 /* Elevate privileges */
618 +#define STR_PROC_SETEGID 0x40
619 +
620 +struct str_process {
621 + TAILQ_ENTRY(str_process) next;
622 + TAILQ_ENTRY(str_process) msg_next;
623 + struct semaphore lock;
624 + struct task_struct *proc;
625 + pid_t pid;
626 + struct fsystrace *parent;
627 + struct str_policy *policy;
628 + wait_queue_head_t wqh;
629 + int flags;
630 + short answer;
631 + short error;
632 + u16 seqnr; /* XXX: convert to u_int16_t */
633 + struct str_message msg;
634 + struct systrace_replace *replace;
635 + int report;
636 + mm_segment_t oldfs;
637 + int maycontrol;
638 + int code;
639 + register_t args[8];
640 + uid_t oldeuid;
641 + gid_t oldegid;
642 + uid_t savedeuid;
643 + uid_t savedegid;
644 + uid_t seteuid;
645 + uid_t setegid;
646 + int issuser;
647 +};
648 +
649 +/* VFS interface */
650 +int systracef_ioctl(struct inode *, struct file *, unsigned int,
651 + unsigned long);
652 +ssize_t systracef_read(struct file *, char *, size_t, loff_t *);
653 +ssize_t systracef_write(struct file *, const char *, size_t, loff_t *);
654 +int systracef_open(struct inode *, struct file *);
655 +int systracef_release(struct inode *, struct file *);
656 +unsigned int systracef_poll(struct file *, struct poll_table_struct *);
657 +
658 +/* Policy handling */
659 +struct str_policy *systrace_newpolicy(struct fsystrace *, int);
660 +void systrace_closepolicy(struct fsystrace *, struct str_policy *);
661 +int systrace_policy(struct fsystrace *, struct systrace_policy *);
662 +struct str_policy *systrace_newpolicy(struct fsystrace *, int);
663 +
664 +/* Message utility functions */
665 +int systrace_msg_child(struct fsystrace *, struct str_process *, pid_t);
666 +int systrace_msg_result(struct fsystrace *, struct str_process *, int, int,
667 + size_t, register_t[]);
668 +int systrace_msg_ask(struct fsystrace *, struct str_process *, int, size_t, register_t[]);
669 +int systrace_msg_ugid(struct fsystrace *, struct str_process *);
670 +int systrace_msg_execve(struct fsystrace *, struct str_process *, register_t);
671 +int systrace_make_msg(struct str_process *, int);
672 +int systrace_make_msg(struct str_process *, int);
673 +
674 +int systrace_io(struct str_process *, struct systrace_io *);
675 +int systrace_getcwd(struct fsystrace *, struct str_process *);
676 +int systrace_rescwd(struct fsystrace *);
677 +int systrace_attach(struct fsystrace *, pid_t);
678 +int systrace_detach(struct str_process *);
679 +int systrace_answer(struct str_process *, struct systrace_answer *);
680 +int systrace_insert_process(struct fsystrace *, struct task_struct *);
681 +int systrace_processready(struct str_process *);
682 +struct str_process *systrace_findpid(struct fsystrace *, pid_t);
683 +struct task_struct *systrace_find(struct str_process *);
684 +
685 +int systrace_preprepl(struct str_process *, struct systrace_replace *);
686 +int systrace_replace(struct str_process *, size_t, register_t[]);
687 +uid_t systrace_seteuid(struct task_struct *, uid_t);
688 +gid_t systrace_setegid(struct task_struct *, gid_t);
689 +
690 +#if 0
691 +void systrace_lock(void);
692 +void systrace_unlock(void);
693 +#endif /* 0 */
694 +/*
695 + * Currently, disable the fine grained locking and use the big kernel
696 + * lock instead. The only thing keeping me from using the fine
697 + * grained locking is in systrace_make_msg(); when fst->lock is
698 + * relinquished, there is a race condition until we sleep on the strp;
699 + * it could have been detached in the mean time, causing nasty things
700 + * to happen. When using the kernel lock, it is automatically
701 + * relinquished when needed.
702 + */
703 +#define systrace_lock(...) lock_kernel();
704 +#define systrace_unlock(...) unlock_kernel();
705 +
706 +#endif /* SYSTRACE_PRIVATE_H */
707 Index: linux-2.6.17/drivers/systrace/systrace.c
708 ===================================================================
709 --- /dev/null
710 +++ linux-2.6.17/drivers/systrace/systrace.c
711 @@ -0,0 +1,1378 @@
712 +/*
713 + * systrace.c
714 + *
715 + * Copyright (c) 2002 Marius Aamodt Eriksen <marius@umich.edu>
716 + * Copyright (c) 2002 Niels Provos <provos@citi.umich.edu>
717 + *
718 + * Redistribution and use in source and binary forms, with or without
719 + * modification, are permitted provided that the following conditions
720 + * are met:
721 + *
722 + * 1. Redistributions of source code must retain the above copyright
723 + * notice, this list of conditions and the following disclaimer.
724 + * 2. Redistributions in binary form must reproduce the above copyright
725 + * notice, this list of conditions and the following disclaimer in the
726 + * documentation and/or other materials provided with the distribution.
727 + * 3. The names of the copyright holders may not be used to endorse or
728 + * promote products derived from this software without specific
729 + * prior written permission.
730 + *
731 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
732 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
733 + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
734 + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
735 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
736 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
737 + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
738 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
739 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
740 + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
741 + */
742 +
743 +/*
744 + * XXX clone()'s with same PID
745 + */
746 +
747 +#include <linux/sched.h>
748 +#include <linux/smp_lock.h>
749 +#include <linux/mm.h>
750 +#include <linux/pagemap.h>
751 +#include <linux/fs.h>
752 +#include <linux/wait.h>
753 +#include <linux/slab.h>
754 +#include <linux/sys.h>
755 +#include <linux/miscdevice.h>
756 +#include <linux/queue.h>
757 +#include <linux/mount.h>
758 +#include <linux/init.h>
759 +
760 +#include <asm/semaphore.h>
761 +#include <asm/uaccess.h>
762 +#include <asm/ptrace.h>
763 +#include <asm/unistd.h>
764 +
765 +#include <linux/queue.h>
766 +#include <linux/systrace.h>
767 +#include <linux/poll.h>
768 +
769 +#include "systrace-private.h"
770 +
771 +#define FIXARGS(argsize, args, regs) do { \
772 + switch (argsize) { \
773 + case 20: \
774 + args[4] = regs->edi; \
775 + case 16: \
776 + args[3] = regs->esi; \
777 + case 12: \
778 + args[2] = regs->edx; \
779 + case 8: \
780 + args[1] = regs->ecx; \
781 + case 4: \
782 + args[0] = regs->ebx; \
783 + case 0: \
784 + break; \
785 + default: \
786 + printk(KERN_ERR "systrace: (FIXARGS) Illegal argument size %d\n", argsize);\
787 + BUG(); \
788 + } \
789 +} while (0)
790 +
791 +#define SAVEARGS(argsize, args, regs) do { \
792 + switch (argsize) { \
793 + case 20: \
794 + regs->edi = args[4]; \
795 + case 16: \
796 + regs->esi = args[3]; \
797 + case 12: \
798 + regs->edx = args[2]; \
799 + case 8: \
800 + regs->ecx = args[1]; \
801 + case 4: \
802 + regs->ebx = args[0]; \
803 + case 0: \
804 + break; \
805 + default: \
806 + printk(KERN_ERR "systrace: Illegal argument size %d\n", argsize);\
807 + BUG(); \
808 + } \
809 +} while (0)
810 +
811 +#define PRINTARGS(argsize, regs) do { \
812 + switch (argsize) { \
813 + case 20: \
814 + printk(" edi: %lx\n", regs->edi); \
815 + case 16: \
816 + printk(" esi: %lx\n", regs->esi); \
817 + case 12: \
818 + printk(" edx: %lx\n", regs->edx); \
819 + case 8: \
820 + printk(" ecx: %lx\n", regs->ecx); \
821 + case 4: \
822 + printk(" ebx: %lx\n", regs->ebx); \
823 + case 0: \
824 + break; \
825 + default: \
826 + printk(KERN_ERR "systrace: Illegal argument size %d\n", argsize);\
827 + BUG(); \
828 + } \
829 +} while (0)
830 +
831 +#define SYSTRACE_MINOR 226
832 +
833 +spinlock_t str_lck = SPIN_LOCK_UNLOCKED;
834 +int systrace_debug = 0;
835 +
836 +
837 +/*
838 + * Pass by registers; we need the stack that the system call will see
839 + * in order to examine it and possibly modify.
840 + */
841 +
842 +int FASTCALL(systrace_intercept(struct pt_regs *));
843 +void FASTCALL(systrace_result(struct pt_regs *));
844 +
845 +static struct file_operations systrace_fops = {
846 + read: &systracef_read,
847 + write: &systracef_write,
848 + ioctl: &systracef_ioctl,
849 + release: &systracef_release,
850 + open: &systracef_open,
851 + poll: &systracef_poll
852 +};
853 +
854 +static struct miscdevice systrace_dev = {
855 + SYSTRACE_MINOR,
856 + "systrace",
857 + &systrace_fops
858 +};
859 +
860 +void
861 +_systrace_lock(void)
862 +{
863 + spin_lock(&str_lck);
864 +}
865 +
866 +void
867 +_systrace_unlock(void)
868 +{
869 + spin_unlock(&str_lck);
870 +}
871 +
872 +int
873 +init_systrace(void)
874 +{
875 + if (misc_register(&systrace_dev) < 0) {
876 + printk(KERN_INFO "systrace: unable to register device\n");
877 + return (-EIO);
878 + }
879 +
880 + printk(KERN_INFO "systrace: systrace initialized\n");
881 +
882 + return (0);
883 +}
884 +subsys_initcall(init_systrace);
885 +
886 +int
887 +systracef_open(struct inode *inode, struct file *file)
888 +{
889 + struct fsystrace *fst;
890 + int error = 0;
891 +
892 + if ((fst = kmalloc(sizeof(*fst), GFP_KERNEL)) == NULL) {
893 + printk(KERN_ERR "systrace: Failed to allocate kernel memory.\n");
894 + error = 0;
895 + goto out;
896 + }
897 +
898 + memset(fst, 0, sizeof(*fst));
899 +
900 + TAILQ_INIT(&fst->processes);
901 + TAILQ_INIT(&fst->policies);
902 + TAILQ_INIT(&fst->messages);
903 +
904 + init_MUTEX(&fst->lock);
905 + init_waitqueue_head(&fst->wqh);
906 +
907 + fst->euid = current->euid;
908 + fst->egid = current->egid;
909 + fst->issuser = capable(CAP_SYS_ADMIN);
910 + fst->pid = current->pid;
911 +
912 + file->private_data = fst;
913 +
914 + out:
915 + return (error);
916 +}
917 +
918 +int
919 +systracef_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
920 + unsigned long arg)
921 +{
922 + struct fsystrace *fst = (struct fsystrace *)file->private_data;
923 + pid_t pid = 0;
924 + struct str_process *strp = NULL;
925 + int error = 0;
926 + void *data = NULL;
927 +
928 + if (fst == NULL) {
929 + printk(KERN_ERR "systrace: in impossible state!\n");
930 + BUG();
931 + }
932 +
933 + /* Argument santizing */
934 + switch (cmd) {
935 + case STRIOCATTACH:
936 + case STRIOCANSWER:
937 + case STRIOCIO:
938 + case STRIOCGETCWD:
939 + case STRIOCDETACH:
940 + case STRIOCPOLICY:
941 + case STRIOCREPLACE:
942 + if ((void *)arg == NULL)
943 + error = -EINVAL;
944 + break;
945 + case STRIOCRESCWD:
946 + default:
947 + break;
948 + }
949 +
950 + if (error != 0)
951 + goto out;
952 +
953 + switch (cmd) {
954 + case STRIOCANSWER:
955 + if ((data = kmalloc(sizeof(struct systrace_answer),
956 + GFP_KERNEL)) == NULL) {
957 + error = -ENOSPC;
958 + break;
959 + }
960 + if (copy_from_user((struct systrace_answer *)data,
961 + (struct systrace_answer *)arg,
962 + sizeof(struct systrace_answer)) != 0) {
963 + kfree(data);
964 + error = -EFAULT;
965 + break;
966 + }
967 +
968 + pid = ((struct systrace_answer *)data)->stra_pid;
969 + break;
970 + case STRIOCIO:
971 + if ((data = kmalloc(sizeof(struct systrace_io),
972 + GFP_KERNEL)) == NULL) {
973 + error = -ENOSPC;
974 + break;
975 + }
976 + if (copy_from_user((struct systrace_io *)data,
977 + (struct systrace_io *)arg,
978 + sizeof(struct systrace_io)) != 0) {
979 + kfree(data);
980 + error = -EFAULT;
981 + break;
982 + }
983 +
984 + pid = ((struct systrace_io *)data)->strio_pid;
985 + break;
986 + case STRIOCGETCWD:
987 + case STRIOCDETACH:
988 + if (get_user(pid, (pid_t *)arg) != 0)
989 + error = -EFAULT;
990 +
991 + if (pid == 0)
992 + error = -EINVAL;
993 + break;
994 + case STRIOCATTACH:
995 + case STRIOCRESCWD:
996 + break;
997 + case STRIOCPOLICY:
998 + if ((data = kmalloc(sizeof(struct systrace_policy),
999 + GFP_KERNEL)) == NULL) {
1000 + error = -ENOSPC;
1001 + break;
1002 + }
1003 + if (copy_from_user((struct systrace_policy *)data,
1004 + (struct systrace_policy *)arg,
1005 + sizeof(struct systrace_policy)) != 0) {
1006 + kfree(data);
1007 + error = -EFAULT;
1008 + break;
1009 + }
1010 + break;
1011 + case STRIOCREPLACE:
1012 + if ((data = kmalloc(sizeof(struct systrace_replace),
1013 + GFP_KERNEL)) == NULL) {
1014 + error = -ENOSPC;
1015 + break;
1016 + }
1017 + if (copy_from_user((struct systrace_replace *)data,
1018 + (struct systrace_replace *)arg,
1019 + sizeof(struct systrace_replace)) != 0) {
1020 + kfree(data);
1021 + error = -EFAULT;
1022 + break;
1023 + }
1024 +
1025 + pid = ((struct systrace_replace *)data)->strr_pid;
1026 + break;
1027 + default:
1028 + error = -EINVAL;
1029 + }
1030 +
1031 + if (error != 0)
1032 + goto out;
1033 +
1034 + systrace_lock();
1035 + down(&fst->lock);
1036 + systrace_unlock();
1037 +
1038 + if (pid != 0)
1039 + if ((strp = systrace_findpid(fst, pid)) == NULL) {
1040 + error = -EINVAL;
1041 + goto unlock;
1042 + }
1043 +
1044 + switch (cmd) {
1045 + case STRIOCATTACH:
1046 + if (get_user(pid, (pid_t *)arg) != 0)
1047 + error = -EFAULT;
1048 +
1049 + if (pid == 0)
1050 + error = -EINVAL;
1051 + else
1052 + error = systrace_attach(fst, *(pid_t *)arg);
1053 + break;
1054 + case STRIOCDETACH:
1055 + error = systrace_detach(strp);
1056 + break;
1057 + case STRIOCANSWER:
1058 + error = systrace_answer(strp, (struct systrace_answer *)data);
1059 + break;
1060 + case STRIOCIO:
1061 + error = systrace_io(strp, (struct systrace_io *)data);
1062 + break;
1063 + case STRIOCGETCWD:
1064 + error = systrace_getcwd(fst, strp);
1065 + break;
1066 + case STRIOCRESCWD:
1067 + error = systrace_rescwd(fst);
1068 + break;
1069 + case STRIOCPOLICY:
1070 + error = systrace_policy(fst, (struct systrace_policy *)data);
1071 + if (copy_to_user((struct systrace_policy *)arg,
1072 + (struct systrace_policy *)data,
1073 + sizeof(struct systrace_policy)) != 0)
1074 + error = -EFAULT;
1075 + break;
1076 + case STRIOCREPLACE:
1077 + error = systrace_preprepl(strp, (struct systrace_replace *)data);
1078 + break;
1079 + default:
1080 + /* XXX */
1081 + break;
1082 + }
1083 +
1084 + if (data != NULL)
1085 + kfree(data);
1086 +
1087 + unlock:
1088 + up(&fst->lock);
1089 + out:
1090 + return (error);
1091 +}
1092 +
1093 +unsigned int
1094 +systracef_poll(struct file *file, struct poll_table_struct *wait)
1095 +{
1096 + struct fsystrace *fst = (struct fsystrace *)file->private_data;
1097 + unsigned int ret = 0;
1098 +
1099 + systrace_lock();
1100 + down(&fst->lock);
1101 + systrace_unlock();
1102 +
1103 + poll_wait(file, &fst->wqh, wait);
1104 +
1105 + if (TAILQ_FIRST(&fst->messages) != NULL)
1106 + ret = POLLIN | POLLRDNORM;
1107 +
1108 + up(&fst->lock);
1109 +
1110 + return (ret);
1111 +}
1112 +
1113 +ssize_t
1114 +systracef_read(struct file *filp, char *buf, size_t count, loff_t *off)
1115 +{
1116 + struct fsystrace *fst = (struct fsystrace *)filp->private_data;
1117 + struct str_process *strp;
1118 + int error = 0;
1119 +
1120 + if (count != sizeof(struct str_message))
1121 + return (-EINVAL);
1122 +
1123 + again:
1124 + systrace_lock();
1125 + down(&fst->lock);
1126 + systrace_unlock();
1127 +
1128 + if ((strp = TAILQ_FIRST(&fst->messages)) != NULL) {
1129 + error = copy_to_user(buf, &strp->msg, sizeof(struct str_message));
1130 + if (error != 0) {
1131 + error = -EFAULT;
1132 + } else {
1133 + error = sizeof(struct str_message);
1134 + TAILQ_REMOVE(&fst->messages, strp, msg_next);
1135 + CLR(strp->flags, STR_PROC_ONQUEUE);
1136 +
1137 + if (SYSTR_MSG_NOPROCESS(strp))
1138 + kfree(strp);
1139 + }
1140 + } else if (TAILQ_FIRST(&fst->processes) == NULL) {
1141 + /* EOF situation */
1142 + ;
1143 + } else {
1144 + if (filp->f_flags & O_NONBLOCK) {
1145 + error = -EAGAIN;
1146 + } else {
1147 + up(&fst->lock);
1148 + interruptible_sleep_on(&fst->wqh);
1149 +
1150 + if (signal_pending(current)) {
1151 + error = -ERESTARTSYS;
1152 + goto out;
1153 + }
1154 + goto again;
1155 + }
1156 + }
1157 +
1158 + up(&fst->lock);
1159 + out:
1160 + return (error);
1161 +}
1162 +
1163 +ssize_t
1164 +systracef_write(struct file *filp, const char *buf, size_t count, loff_t *off)
1165 +{
1166 + return (-ENOTSUPP);
1167 +}
1168 +
1169 +int
1170 +systracef_release(struct inode *inode, struct file *filp)
1171 +{
1172 + struct str_process *strp;
1173 + struct fsystrace *fst = filp->private_data;
1174 + struct str_policy *strpol;
1175 +
1176 + systrace_lock();
1177 + down(&fst->lock);
1178 + systrace_unlock();
1179 +
1180 + /* Kill all traced processes */
1181 + while ((strp = TAILQ_FIRST(&fst->processes)) != NULL) {
1182 + struct task_struct *p = strp->proc;
1183 +
1184 + systrace_detach(strp);
1185 + kill_proc(p->pid, SIGKILL, 1);
1186 + }
1187 +
1188 + /* Clean up fork and exit messages */
1189 + while ((strp = TAILQ_FIRST(&fst->messages)) != NULL) {
1190 + TAILQ_REMOVE(&fst->messages, strp, msg_next);
1191 + kfree(strp);
1192 + }
1193 +
1194 + /* Clean up policies */
1195 + while ((strpol = TAILQ_FIRST(&fst->policies)) != NULL)
1196 + systrace_closepolicy(fst, strpol);
1197 +
1198 + up(&fst->lock);
1199 +
1200 + kfree(filp->private_data);
1201 + filp->private_data = NULL;
1202 +
1203 + return (0);
1204 +}
1205 +
1206 +void
1207 +systrace_fork(struct task_struct *parent, struct task_struct *child)
1208 +{
1209 + struct str_process *parentstrp, *strp;
1210 + struct fsystrace *fst;
1211 +
1212 + systrace_lock();
1213 + if ((parentstrp = parent->systrace) == NULL) {
1214 + systrace_unlock();
1215 + return;
1216 + }
1217 +
1218 + fst = parentstrp->parent;
1219 + down(&fst->lock);
1220 + systrace_unlock();
1221 +
1222 + if (systrace_insert_process(fst, child) != 0) {
1223 + printk(KERN_ERR "systrace: failed inserting process!\n");
1224 + goto out;
1225 + }
1226 +
1227 + /* XXX make sure we have pid by this time in fork() */
1228 + if ((strp = systrace_findpid(fst, child->pid)) == NULL) {
1229 + printk(KERN_ERR "systrace: inconsistency in tracked process!\n");
1230 + BUG();
1231 + }
1232 +
1233 + if ((strp->policy = parentstrp->policy) != NULL)
1234 + strp->policy->refcount++;
1235 +
1236 + /* Fork message */
1237 + systrace_msg_child(fst, parentstrp, child->pid);
1238 + out:
1239 + up(&fst->lock);
1240 +}
1241 +
1242 +void
1243 +systrace_exit(struct task_struct *p)
1244 +{
1245 + struct str_process *strp;
1246 + struct fsystrace *fst;
1247 +
1248 + systrace_lock();
1249 + if ((strp = p->systrace) != NULL) {
1250 + fst = strp->parent;
1251 + down(&fst->lock);
1252 + systrace_unlock();
1253 +
1254 + /* Notify our monitor of our death */
1255 + systrace_msg_child(fst, strp, -1);
1256 +
1257 + systrace_detach(strp);
1258 + up(&fst->lock);
1259 + } else {
1260 + systrace_unlock();
1261 + }
1262 +}
1263 +
1264 +void fastcall
1265 +systrace_result(struct pt_regs *regs)
1266 +{
1267 + struct str_process *strp;
1268 + struct fsystrace *fst;
1269 + int error, argsize, narg, code;
1270 + extern struct sysent linux_sysent[];
1271 +
1272 + systrace_lock();
1273 +
1274 + if ((strp = current->systrace) == NULL)
1275 + goto out;
1276 +
1277 + code = strp->code;
1278 + narg = linux_sysent[code].sy_narg;
1279 + argsize = sizeof(register_t) * narg;
1280 +
1281 + fst = strp->parent;
1282 +
1283 + /* Restore elevated priveliges if appropriate */
1284 + if (strp->issuser) {
1285 + if (ISSET(strp->flags, STR_PROC_SETEUID)) {
1286 + if (current->euid == strp->seteuid) {
1287 + systrace_seteuid(current, strp->savedeuid);
1288 + CLR(strp->flags, STR_PROC_SETEUID);
1289 + }
1290 + if (current->egid == strp->setegid) {
1291 + systrace_setegid(current, strp->savedegid);
1292 + CLR(strp->flags, STR_PROC_SETEGID);
1293 + }
1294 + }
1295 + }
1296 +
1297 + /* Change in UID/GID */
1298 + if (strp->oldegid != current->egid || strp->oldeuid != current->euid) {
1299 + down(&fst->lock);
1300 + systrace_unlock();
1301 +
1302 + systrace_msg_ugid(fst, strp);
1303 + systrace_lock();
1304 + if ((strp = current->systrace) == NULL)
1305 + goto out;
1306 + }
1307 +
1308 + if (ISSET(strp->flags, STR_PROC_SYSCALLRES)) {
1309 + CLR(strp->flags, STR_PROC_SYSCALLRES);
1310 +
1311 + down(&fst->lock);
1312 + systrace_unlock();
1313 +
1314 + error = regs->eax;
1315 +
1316 + systrace_msg_result(fst, strp, error, code, argsize, strp->args);
1317 + systrace_lock();
1318 + if ((strp = current->systrace) == NULL)
1319 + goto out;
1320 + }
1321 +
1322 + if (strp->replace != NULL) {
1323 + kfree(strp->replace);
1324 + strp->replace = NULL;
1325 + }
1326 +
1327 + if (ISSET(strp->flags, STR_PROC_FSCHANGE))
1328 + set_fs(strp->oldfs);
1329 +
1330 + out:
1331 + systrace_unlock();
1332 +}
1333 +
1334 +/*
1335 + * XXX serialize system calls
1336 + */
1337 +int fastcall
1338 +systrace_intercept(struct pt_regs *regs)
1339 +{
1340 + register_t args[8];
1341 + int argsize, narg, code, error = 0, maycontrol = 0, issuser = 0;
1342 + short policy;
1343 + struct str_process *strp;
1344 + struct fsystrace *fst = NULL;
1345 + extern struct sysent linux_sysent[];
1346 + struct str_policy *strpolicy;
1347 +
1348 + systrace_lock();
1349 +
1350 + if ((strp = current->systrace) == NULL) {
1351 + systrace_unlock();
1352 + goto out;
1353 + }
1354 +
1355 + fst = strp->parent;
1356 +
1357 + down(&fst->lock);
1358 + systrace_unlock();
1359 +
1360 + CLR(strp->flags, STR_PROC_FSCHANGE);
1361 +
1362 + if (regs != NULL) {
1363 + code = regs->orig_eax;
1364 + } else {
1365 + error = -EPERM;
1366 + goto out;
1367 + }
1368 +
1369 + if (code > NR_syscalls) {
1370 + printk(KERN_ERR "systrace: in impossible state!\n");
1371 + BUG();
1372 + }
1373 +
1374 + narg = linux_sysent[code].sy_narg;
1375 + argsize = sizeof(register_t) * narg;
1376 +
1377 + /*
1378 + * Linux passes system call arguments in registers. We want
1379 + * to be able to pass back an args array; convert
1380 + * appropriately.
1381 + */
1382 +
1383 + FIXARGS(argsize, args, regs);
1384 +
1385 + if (strp->proc != current) {
1386 + printk(KERN_ERR "systrace: inconsistency in process states!\n");
1387 + BUG();
1388 + }
1389 +
1390 + if (fst->issuser) {
1391 + maycontrol = 1;
1392 + issuser = 1;
1393 + } else if (cap_isclear(current->cap_effective) &&
1394 + !(current->flags & PF_SUPERPRIV) &&
1395 + current->mm->dumpable) {
1396 + maycontrol = fst->euid == current->euid &&
1397 + fst->egid == current->egid;
1398 + }
1399 +
1400 + strp->code = code;
1401 + strp->maycontrol = maycontrol;
1402 + memcpy(strp->args, args, sizeof(strp->args));
1403 + strp->oldeuid = current->euid;
1404 + strp->oldegid = current->egid;
1405 + strp->issuser = fst->issuser;
1406 +
1407 + if (!maycontrol) {
1408 + policy = SYSTR_POLICY_PERMIT;
1409 + } else {
1410 + /* Find out current policy */
1411 + if ((strpolicy = strp->policy) == NULL) {
1412 + policy = SYSTR_POLICY_ASK;
1413 + } else {
1414 + if (code >= strpolicy->nsysent)
1415 + policy = SYSTR_POLICY_NEVER;
1416 + else
1417 + policy = strpolicy->sysent[code];
1418 + }
1419 + }
1420 +
1421 + switch (policy) {
1422 + case SYSTR_POLICY_PERMIT:
1423 + break;
1424 + case SYSTR_POLICY_ASK:
1425 + error = systrace_msg_ask(fst, strp, code, argsize, args);
1426 + /* systrace_msg_ask releases lock */
1427 + fst = NULL;
1428 + /* We might have detached by now for some reason */
1429 + if (error == 0 && (strp = current->systrace) != NULL) {
1430 + /* XXX - do I need to lock here? */
1431 + if (strp->answer == SYSTR_POLICY_NEVER) {
1432 + error = strp->error;
1433 + if (strp->replace != NULL) {
1434 + kfree(strp->replace);
1435 + strp->replace = NULL;
1436 + }
1437 + } else if (strp->replace != NULL) {
1438 + if ((error = systrace_replace(strp,
1439 + argsize, args) == 0)) {
1440 + SAVEARGS(argsize, args, regs);
1441 + strp->oldfs = get_fs();
1442 + set_fs(get_ds());
1443 + SET(strp->flags, STR_PROC_FSCHANGE);
1444 + }
1445 + }
1446 + }
1447 + break;
1448 + case SYSTR_POLICY_NEVER:
1449 + error = -EPERM;
1450 + break;
1451 + default:
1452 + if (policy < 0)
1453 + error = policy;
1454 + else
1455 + error = -EPERM;
1456 + break;
1457 + }
1458 +
1459 + /* XXX */
1460 +/*
1461 + if (error != 0)
1462 + goto out;
1463 +*/
1464 + systrace_lock();
1465 + if ((strp = current->systrace) != NULL) {
1466 + if (issuser) {
1467 + if (ISSET(strp->flags, STR_PROC_SETEUID)) {
1468 + strp->savedeuid = systrace_seteuid(current, strp->seteuid);
1469 + }
1470 + if (ISSET(strp->flags, STR_PROC_SETEGID)) {
1471 + strp->savedegid = systrace_setegid(current, strp->setegid);
1472 + }
1473 + } else {
1474 + CLR(strp->flags, STR_PROC_SETEUID | STR_PROC_SETEGID);
1475 + }
1476 + }
1477 + systrace_unlock();
1478 +
1479 + out:
1480 + if (fst != NULL)
1481 + up(&fst->lock);
1482 +
1483 + return (error);
1484 +}
1485 +
1486 +int
1487 +systrace_preprepl(struct str_process *strp, struct systrace_replace *repl)
1488 +{
1489 + size_t len;
1490 + int i, error = 0;
1491 +
1492 + if ((error = systrace_processready(strp)) != 0)
1493 + return (error);
1494 +
1495 + if (strp->replace != NULL) {
1496 + kfree(strp->replace);
1497 + strp->replace = NULL;
1498 + }
1499 +
1500 + if (repl->strr_nrepl < 0 || repl->strr_nrepl > SYSTR_MAXARGS)
1501 + return (-EINVAL);
1502 +
1503 + for (i = 0, len = 0; i < repl->strr_nrepl; i++) {
1504 + len += repl->strr_offlen[i];
1505 + if (repl->strr_offlen[i] == 0)
1506 + continue;
1507 + if (repl->strr_offlen[i] + repl->strr_off[i] > len)
1508 + return (-EINVAL);
1509 + }
1510 +
1511 + /* Make sure that the length adds up */
1512 + if (repl->strr_len != len)
1513 + return (-EINVAL);
1514 +
1515 + /* Check against a maximum length */
1516 + if (repl->strr_len > 2048)
1517 + return (-EINVAL);
1518 +
1519 + if ((strp->replace = kmalloc(sizeof(*strp->replace) + len, GFP_KERNEL))
1520 + == NULL)
1521 + return (-ENOSPC);
1522 +
1523 + memcpy(strp->replace, repl, sizeof(*strp->replace));
1524 +
1525 + if (copy_from_user(strp->replace + 1, repl->strr_base, len) != 0) {
1526 + kfree(strp->replace);
1527 + strp->replace = NULL;
1528 + return (-EFAULT);
1529 + }
1530 +
1531 + /* Adjust the offset */
1532 + repl = strp->replace;
1533 + repl->strr_base = (void *)(repl + 1);
1534 +
1535 + return (0);
1536 +}
1537 +
1538 +/*
1539 + * Replace the arguments with arguments from the monitoring process.
1540 + */
1541 +int
1542 +systrace_replace(struct str_process *strp, size_t argsize, register_t args[])
1543 +{
1544 + struct systrace_replace *repl = strp->replace;
1545 + void *kbase;
1546 + int i, maxarg, ind, ret = 0;
1547 +
1548 + maxarg = argsize / sizeof(register_t);
1549 +
1550 + kbase = repl->strr_base;
1551 + for (i = 0; i < maxarg && i < repl->strr_nrepl; i++) {
1552 + ind = repl->strr_argind[i];
1553 + if (ind < 0 || ind >= maxarg) {
1554 + kfree(repl);
1555 + strp->replace = NULL;
1556 + return (-EINVAL);
1557 + }
1558 + if (repl->strr_offlen[i] == 0) {
1559 + args[ind] = repl->strr_off[i];
1560 + continue;
1561 + }
1562 +
1563 + /* Replace the argument with the new address */
1564 + args[ind] = (register_t)(kbase + repl->strr_off[i]);
1565 + }
1566 +
1567 + return (ret);
1568 +}
1569 +
1570 +int
1571 +systrace_answer(struct str_process *strp, struct systrace_answer *ans)
1572 +{
1573 + int error = 0;
1574 +
1575 + if (!POLICY_VALID(ans->stra_policy)) {
1576 + error = -EINVAL;
1577 + goto out;
1578 + }
1579 +
1580 + /* Check if answer is in sync with us */
1581 + if (ans->stra_seqnr != strp->seqnr) {
1582 + error = -EINVAL;
1583 + goto out;
1584 + }
1585 +
1586 + if ((error = systrace_processready(strp)) != 0)
1587 + goto out;
1588 +
1589 + strp->answer = ans->stra_policy;
1590 + strp->error = ans->stra_error;
1591 + if (!strp->error)
1592 + strp->error = -EPERM;
1593 + if (ISSET(ans->stra_flags, SYSTR_FLAGS_RESULT))
1594 + SET(strp->flags, STR_PROC_SYSCALLRES);
1595 +
1596 + /* See if we should elevate privileges for this system call */
1597 + if (ISSET(ans->stra_flags, SYSTR_FLAGS_SETEUID)) {
1598 + SET(strp->flags, STR_PROC_SETEUID);
1599 + strp->seteuid = ans->stra_seteuid;
1600 + }
1601 + if (ISSET(ans->stra_flags, SYSTR_FLAGS_SETEGID)) {
1602 + SET(strp->flags, STR_PROC_SETEGID);
1603 + strp->setegid = ans->stra_setegid;
1604 + }
1605 +
1606 + /* Clearing the flag indicates to the process that it woke up */
1607 + CLR(strp->flags, STR_PROC_WAITANSWER);
1608 + wake_up(&strp->wqh);
1609 + out:
1610 +
1611 + return (error);
1612 +}
1613 +
1614 +int
1615 +systrace_io(struct str_process *strp, struct systrace_io *io)
1616 +{
1617 + int rw, ret = 0, copied, maycontrol = 0;
1618 + void *buf;
1619 + struct fsystrace *fst = strp->parent;
1620 + struct task_struct *tsk = strp->proc;
1621 +
1622 + if (fst->issuser) {
1623 + maycontrol = 1;
1624 + } else if (cap_isclear(tsk->cap_effective) &&
1625 + !(tsk->flags & PF_SUPERPRIV) &&
1626 + tsk->mm->dumpable) {
1627 + maycontrol = current->euid == tsk->euid &&
1628 + current->egid == tsk->egid;
1629 + }
1630 +
1631 + if (!maycontrol)
1632 + return (-EPERM);
1633 +
1634 + if ((buf = kmalloc(io->strio_len, GFP_KERNEL)) == NULL) {
1635 + printk(KERN_ERR "systrace: failed to allocate kernel memory!\n");
1636 + return (-ENOMEM);
1637 + }
1638 +
1639 + switch (io->strio_op) {
1640 + case SYSTR_READ:
1641 + rw = 0;
1642 + break;
1643 + case SYSTR_WRITE:
1644 + rw = 1;
1645 + if (copy_from_user(buf, io->strio_addr, io->strio_len)) {
1646 + ret = -EFAULT;
1647 + goto out;
1648 + }
1649 + break;
1650 + default:
1651 + return (-EINVAL);
1652 + }
1653 +
1654 + copied = access_process_vm(tsk, (unsigned long)io->strio_offs, buf,
1655 + io->strio_len, rw);
1656 +
1657 + if (copied != io->strio_len) {
1658 + ret = -EFAULT;
1659 + goto out;
1660 + }
1661 +
1662 + switch (io->strio_op) {
1663 + case SYSTR_READ:
1664 + if (copy_to_user(io->strio_addr, buf, io->strio_len)) {
1665 + ret = -EFAULT;
1666 + goto out;
1667 + }
1668 + break;
1669 + }
1670 +
1671 + out:
1672 + kfree(buf);
1673 +
1674 + return (ret);
1675 +}
1676 +
1677 +int
1678 +systrace_getcwd(struct fsystrace *fst, struct str_process *strp)
1679 +{
1680 + struct fs_struct *fsc, *fsp;
1681 + int error = 0;
1682 +
1683 + if ((error = systrace_processready(strp)) != 0)
1684 + return (error);
1685 +
1686 + task_lock(current);
1687 + task_lock(strp->proc);
1688 + fsc = current->fs;
1689 + fsp = strp->proc->fs;
1690 +
1691 + if (fsc == NULL || fsp == NULL) {
1692 + task_unlock(current);
1693 + task_unlock(strp->proc);
1694 + return (-EINVAL);
1695 + }
1696 +
1697 + fst->pwd_pid = strp->pid;
1698 +
1699 + /* XXX altroot? */
1700 + write_lock(&fsc->lock);
1701 +
1702 + fst->pwd_mnt = fsc->pwdmnt;
1703 + fst->pwd_dentry = fsc->pwd;
1704 + fst->root_mnt = fsc->rootmnt;
1705 + fst->root_dentry = fsc->root;
1706 +
1707 + read_lock(&fsp->lock);
1708 + fsc->pwdmnt = mntget(fsp->pwdmnt);
1709 + fsc->pwd = dget(fsp->pwd);
1710 + fsc->rootmnt = mntget(fsp->rootmnt);
1711 + fsc->root = dget(fsp->root);
1712 + read_unlock(&fsp->lock);
1713 +
1714 + write_unlock(&fsc->lock);
1715 +
1716 + task_unlock(current);
1717 + task_unlock(strp->proc);
1718 +
1719 + return (0);
1720 +}
1721 +
1722 +int
1723 +systrace_rescwd(struct fsystrace *fst)
1724 +{
1725 + struct fs_struct *fsc;
1726 +
1727 + if (fst->pwd_pid == 0)
1728 + return (-EINVAL);
1729 +
1730 + fsc = current->fs;
1731 +
1732 + write_lock(&fsc->lock);
1733 + dput(fsc->pwd);
1734 + mntput(fsc->pwdmnt);
1735 + dput(fsc->root);
1736 + mntput(fsc->rootmnt);
1737 +
1738 + fsc->pwd = fst->pwd_dentry;
1739 + fsc->pwdmnt = fst->pwd_mnt;
1740 + fsc->root = fst->root_dentry;
1741 + fsc->rootmnt = fst->root_mnt;
1742 + write_unlock(&fsc->lock);
1743 +
1744 + fst->pwd_pid = 0;
1745 +
1746 + return (0);
1747 +}
1748 +
1749 +int
1750 +systrace_processready(struct str_process *strp)
1751 +{
1752 + if (ISSET(strp->flags, STR_PROC_ONQUEUE))
1753 + return (-EBUSY);
1754 +
1755 + if (!ISSET(strp->flags, STR_PROC_WAITANSWER))
1756 + return (-EBUSY);
1757 +
1758 + if (ISSET(strp->proc->flags, PF_EXITING))
1759 + return (-EBUSY);
1760 +
1761 +#if 0
1762 + if (strp->proc->state != 0)
1763 + return (-EBUSY);
1764 +#endif /* 0 */
1765 +
1766 + return (0);
1767 +}
1768 +
1769 +int
1770 +systrace_insert_process(struct fsystrace *fst, struct task_struct *p)
1771 +{
1772 + struct str_process *strp;
1773 +
1774 + if ((strp = kmalloc(sizeof(*strp), GFP_KERNEL)) == NULL)
1775 + return (-ENOMEM);
1776 +
1777 + memset(strp, 0, sizeof(*strp));
1778 +
1779 + strp->pid = p->pid;
1780 + strp->proc = p;
1781 + strp->parent = fst;
1782 +
1783 + init_waitqueue_head(&strp->wqh);
1784 + init_MUTEX(&strp->lock);
1785 +
1786 + /* Insert into parent's process list */
1787 + TAILQ_INSERT_TAIL(&fst->processes, strp, next);
1788 + fst->nprocesses++;
1789 +
1790 + /* XXX need process flag*/
1791 + p->systrace = strp;
1792 +
1793 + return (0);
1794 +}
1795 +
1796 +struct str_process *
1797 +systrace_findpid(struct fsystrace *fst, pid_t pid)
1798 +{
1799 + struct str_process *strp;
1800 + struct task_struct *proc;
1801 +
1802 + TAILQ_FOREACH(strp, &fst->processes, next)
1803 + if (strp->pid == pid)
1804 + break;
1805 +
1806 + if (strp == NULL)
1807 + return (NULL);
1808 +
1809 + proc = systrace_find(strp);
1810 +
1811 + return (proc != NULL ? strp : NULL);
1812 +}
1813 +
1814 +int
1815 +systrace_attach(struct fsystrace *fst, pid_t pid)
1816 +{
1817 + struct task_struct *proc;
1818 +
1819 + proc = find_task_by_pid(pid);
1820 + if (proc == NULL)
1821 + return (-EINVAL);
1822 +
1823 + /* (1) Same process */
1824 +
1825 + if (proc->pid == current->pid)
1826 + return (-EINVAL);
1827 +
1828 + /* (2) System process */
1829 + /* XXX */
1830 +
1831 + /* (3) Already being systraced */
1832 +
1833 + if (proc->systrace != NULL)
1834 + return (-EBUSY);
1835 +
1836 + /*
1837 + * (4) We do not own it, it's not set{u,g}id AND we are not
1838 + * root
1839 + */
1840 + if ((!cap_isclear(proc->cap_permitted) || proc->flags & PF_SUPERPRIV ||
1841 + proc->euid != current->euid || proc->egid != current->egid) &&
1842 + !capable(CAP_SYS_ADMIN))
1843 + return (-EPERM);
1844 +
1845 + /* (5) It's init */
1846 + if (proc->pid == 1)
1847 + return (-EPERM);
1848 +
1849 + return (systrace_insert_process(fst, proc));
1850 +}
1851 +
1852 +int
1853 +systrace_detach(struct str_process *strp)
1854 +{
1855 + struct fsystrace *fst = strp->parent;
1856 + struct task_struct *proc;
1857 + int error = 0;
1858 +
1859 + if ((proc = systrace_find(strp)) != NULL)
1860 + proc->systrace = NULL;
1861 + else
1862 + error = -EINVAL;
1863 +
1864 + if (ISSET(strp->flags, STR_PROC_WAITANSWER)) {
1865 + CLR(strp->flags, STR_PROC_WAITANSWER);
1866 + wake_up(&strp->wqh);
1867 + }
1868 +
1869 + fst = strp->parent;
1870 + wake_up(&fst->wqh);
1871 +
1872 + if (ISSET(strp->flags, STR_PROC_ONQUEUE))
1873 + TAILQ_REMOVE(&fst->messages, strp, msg_next);
1874 +
1875 + TAILQ_REMOVE(&fst->processes, strp, next);
1876 + fst->nprocesses--;
1877 +
1878 + if (strp->policy != NULL)
1879 + systrace_closepolicy(fst, strp->policy);
1880 + if (strp->replace != NULL)
1881 + kfree(strp->replace);
1882 +
1883 + kfree(strp);
1884 +
1885 + return (error);
1886 +}
1887 +
1888 +int
1889 +systrace_msg_result(struct fsystrace *fst, struct str_process *strp,
1890 + int error, int code, size_t argsize, register_t args[])
1891 +{
1892 + struct str_msg_ask *msg_ask = &strp->msg.msg_data.msg_ask;
1893 + int i;
1894 +
1895 + msg_ask->code = code;
1896 + /* XXX argsize */
1897 + /* += fixup_socket_argsize ... () */
1898 + msg_ask->argsize = argsize;
1899 + msg_ask->result = error;
1900 + for (i = 0; i < argsize / sizeof(register_t) && i < SYSTR_MAXARGS; i++)
1901 + msg_ask->args[i] = args[i];
1902 +
1903 + msg_ask->rval[0] = 0x42;
1904 + msg_ask->rval[1] = 0x42;
1905 +
1906 + return (systrace_make_msg(strp, SYSTR_MSG_RES));
1907 +}
1908 +
1909 +int
1910 +systrace_msg_ask(struct fsystrace *fst, struct str_process *strp, int code,
1911 + size_t argsize, register_t args[])
1912 +{
1913 + struct str_msg_ask *msg_ask = &strp->msg.msg_data.msg_ask;
1914 + int i;
1915 +
1916 + msg_ask->code = code;
1917 + /* XXX argsize */
1918 + msg_ask->argsize = argsize;
1919 + for (i = 0; i < (argsize / sizeof(register_t)) && i < SYSTR_MAXARGS; i++)
1920 + msg_ask->args[i] = args[i];
1921 +
1922 + return (systrace_make_msg(strp, SYSTR_MSG_ASK));
1923 +}
1924 +
1925 +int
1926 +systrace_msg_ugid(struct fsystrace *fst, struct str_process *strp)
1927 +{
1928 + struct str_msg_ugid *msg_ugid = &strp->msg.msg_data.msg_ugid;
1929 + struct task_struct *tsk = strp->proc;
1930 +
1931 + msg_ugid->uid = tsk->euid;
1932 + msg_ugid->gid = tsk->egid;
1933 +
1934 + return (systrace_make_msg(strp, SYSTR_MSG_UGID));
1935 +}
1936 +
1937 +int
1938 +systrace_msg_execve(struct fsystrace *fst, struct str_process *strp, register_t patharg)
1939 +{
1940 + struct str_msg_execve *msg_execve = &strp->msg.msg_data.msg_execve;
1941 +
1942 + msg_execve->patharg = patharg;
1943 +
1944 + return (systrace_make_msg(strp, SYSTR_MSG_EXECVE));
1945 +}
1946 +
1947 +int
1948 +systrace_msg_child(struct fsystrace *fst, struct str_process *strp, pid_t npid)
1949 +{
1950 + struct str_process *nstrp;
1951 + struct str_message *msg;
1952 + struct str_msg_child *msg_child;
1953 +
1954 + /* XXX - use kmem cache!@; pool_*() like interface to it? */
1955 + if ((nstrp = kmalloc(sizeof(*nstrp), GFP_KERNEL)) == NULL)
1956 + return (-1);
1957 +
1958 + memset(nstrp, 0, sizeof(*nstrp));
1959 +
1960 + DPRINTF(("%s: %p: pid %d -> pid %d\n", __func__, nstrp, strp->pid, npid));
1961 +
1962 + msg = &nstrp->msg;
1963 + msg_child = &msg->msg_data.msg_child;
1964 +
1965 + msg->msg_type = SYSTR_MSG_CHILD;
1966 + msg->msg_pid = strp->pid;
1967 + if (strp->policy)
1968 + msg->msg_policy = strp->policy->nr;
1969 + else
1970 + msg->msg_policy = -1;
1971 + msg_child->new_pid = npid;
1972 +
1973 + TAILQ_INSERT_TAIL(&fst->messages, nstrp, msg_next);
1974 +
1975 + wake_up(&fst->wqh);
1976 +
1977 + return (0);
1978 +}
1979 +
1980 +int
1981 +systrace_make_msg(struct str_process *strp, int type)
1982 +{
1983 + struct str_message *msg = &strp->msg;
1984 + struct fsystrace *fst = strp->parent;
1985 + int error = 0;
1986 +
1987 + msg->msg_seqnr = ++strp->seqnr;
1988 + msg->msg_type = type;
1989 + msg->msg_pid = strp->pid;
1990 +
1991 + if (strp->policy)
1992 + msg->msg_policy = strp->policy->nr;
1993 + else
1994 + msg->msg_policy = -1;
1995 +
1996 + SET(strp->flags, STR_PROC_WAITANSWER);
1997 + if (ISSET(strp->flags, STR_PROC_ONQUEUE))
1998 + goto out;
1999 +
2000 + TAILQ_INSERT_TAIL(&fst->messages, strp, msg_next);
2001 + SET(strp->flags, STR_PROC_ONQUEUE);
2002 + /*
2003 + * XXX; need to do schedule trick here; what if we sleep on
2004 + * up(), then we might have awoken again, without knowing
2005 + */
2006 + out:
2007 + wake_up(&fst->wqh);
2008 + lock_kernel();
2009 + up(&fst->lock);
2010 +
2011 + /* Sleep until we have got a reply */
2012 + for (;;) {
2013 + interruptible_sleep_on(&strp->wqh);
2014 +
2015 + if (signal_pending(current)) {
2016 + error = -EINTR;
2017 + break;
2018 + }
2019 +
2020 + /* If we detach, then everything is permitted */
2021 + if ((strp = current->systrace) == NULL)
2022 + break;
2023 +
2024 + if (!ISSET(strp->flags, STR_PROC_WAITANSWER))
2025 + break;
2026 + }
2027 +
2028 + unlock_kernel();
2029 +
2030 + return (0);
2031 +}
2032 +
2033 +uid_t
2034 +systrace_seteuid(struct task_struct *tsk, uid_t euid)
2035 +{
2036 + uid_t oldeuid = tsk->euid;
2037 +
2038 + if (euid == oldeuid)
2039 + return (oldeuid);
2040 +
2041 + /* XXX */
2042 + tsk->mm->dumpable = 0;
2043 + wmb();
2044 +
2045 + tsk->euid = euid;
2046 + tsk->fsuid = euid;
2047 +
2048 + if (oldeuid != 0 && euid == 0)
2049 + current->cap_effective = CAP_FULL_SET;
2050 + else if (oldeuid == 0 && euid != 0)
2051 + cap_clear(current->cap_effective);
2052 +
2053 + return (oldeuid);
2054 +}
2055 +
2056 +gid_t
2057 +systrace_setegid(struct task_struct *tsk, gid_t egid)
2058 +{
2059 + uid_t oldegid = tsk->egid;
2060 +
2061 + if (egid == oldegid)
2062 + return (oldegid);
2063 +
2064 + /* XXX */
2065 + tsk->mm->dumpable = 0;
2066 + wmb();
2067 +
2068 + tsk->egid = egid;
2069 + tsk->fsgid = egid;
2070 +
2071 + return (oldegid);
2072 +}
2073 +
2074 +struct task_struct *
2075 +systrace_find(struct str_process *strp)
2076 +{
2077 + struct task_struct *proc;
2078 +
2079 + if ((proc = find_task_by_pid(strp->pid)) == NULL)
2080 + return (NULL);
2081 +
2082 + if (proc != strp->proc)
2083 + return (NULL);
2084 +
2085 + if (proc->systrace == NULL)
2086 + return (NULL);
2087 +
2088 + return (proc);
2089 +}
2090 Index: linux-2.6.17/include/linux/queue.h
2091 ===================================================================
2092 --- /dev/null
2093 +++ linux-2.6.17/include/linux/queue.h
2094 @@ -0,0 +1,145 @@
2095 +/* $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $ */
2096 +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
2097 +
2098 +/*
2099 + * Copyright (c) 1991, 1993
2100 + * The Regents of the University of California. All rights reserved.
2101 + *
2102 + * Redistribution and use in source and binary forms, with or without
2103 + * modification, are permitted provided that the following conditions
2104 + * are met:
2105 + * 1. Redistributions of source code must retain the above copyright
2106 + * notice, this list of conditions and the following disclaimer.
2107 + * 2. Redistributions in binary form must reproduce the above copyright
2108 + * notice, this list of conditions and the following disclaimer in the
2109 + * documentation and/or other materials provided with the distribution.
2110 + * 3. All advertising materials mentioning features or use of this software
2111 + * must display the following acknowledgement:
2112 + * This product includes software developed by the University of
2113 + * California, Berkeley and its contributors.
2114 + * 4. Neither the name of the University nor the names of its contributors
2115 + * may be used to endorse or promote products derived from this software
2116 + * without specific prior written permission.
2117 + *
2118 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2119 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2120 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2121 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2122 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2123 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2124 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2125 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2126 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2127 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2128 + * SUCH DAMAGE.
2129 + *
2130 + * @(#)queue.h 8.5 (Berkeley) 8/20/94
2131 + */
2132 +
2133 +#ifndef _SYS_QUEUE_H_
2134 +#define _SYS_QUEUE_H_
2135 +
2136 +/*
2137 + * Tail queue definitions.
2138 + */
2139 +#define TAILQ_HEAD(name, type) \
2140 +struct name { \
2141 + struct type *tqh_first; /* first element */ \
2142 + struct type **tqh_last; /* addr of last next element */ \
2143 +}
2144 +
2145 +#define TAILQ_HEAD_INITIALIZER(head) \
2146 + { NULL, &(head).tqh_first }
2147 +
2148 +#define TAILQ_ENTRY(type) \
2149 +struct { \
2150 + struct type *tqe_next; /* next element */ \
2151 + struct type **tqe_prev; /* address of previous next element */ \
2152 +}
2153 +
2154 +/*
2155 + * tail queue access methods
2156 + */
2157 +#define TAILQ_FIRST(head) ((head)->tqh_first)
2158 +#define TAILQ_END(head) NULL
2159 +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
2160 +#define TAILQ_LAST(head, headname) \
2161 + (*(((struct headname *)((head)->tqh_last))->tqh_last))
2162 +/* XXX */
2163 +#define TAILQ_PREV(elm, headname, field) \
2164 + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
2165 +#define TAILQ_EMPTY(head) \
2166 + (TAILQ_FIRST(head) == TAILQ_END(head))
2167 +
2168 +#define TAILQ_FOREACH(var, head, field) \
2169 + for((var) = TAILQ_FIRST(head); \
2170 + (var) != TAILQ_END(head); \
2171 + (var) = TAILQ_NEXT(var, field))
2172 +
2173 +#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \
2174 + for((var) = TAILQ_LAST(head, headname); \
2175 + (var) != TAILQ_END(head); \
2176 + (var) = TAILQ_PREV(var, headname, field))
2177 +
2178 +/*
2179 + * Tail queue functions.
2180 + */
2181 +#define TAILQ_INIT(head) do { \
2182 + (head)->tqh_first = NULL; \
2183 + (head)->tqh_last = &(head)->tqh_first; \
2184 +} while (0)
2185 +
2186 +#define TAILQ_INSERT_HEAD(head, elm, field) do { \
2187 + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
2188 + (head)->tqh_first->field.tqe_prev = \
2189 + &(elm)->field.tqe_next; \
2190 + else \
2191 + (head)->tqh_last = &(elm)->field.tqe_next; \
2192 + (head)->tqh_first = (elm); \
2193 + (elm)->field.tqe_prev = &(head)->tqh_first; \
2194 +} while (0)
2195 +
2196 +#define TAILQ_INSERT_TAIL(head, elm, field) do { \
2197 + (elm)->field.tqe_next = NULL; \
2198 + (elm)->field.tqe_prev = (head)->tqh_last; \
2199 + *(head)->tqh_last = (elm); \
2200 + (head)->tqh_last = &(elm)->field.tqe_next; \
2201 +} while (0)
2202 +
2203 +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
2204 + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
2205 + (elm)->field.tqe_next->field.tqe_prev = \
2206 + &(elm)->field.tqe_next; \
2207 + else \
2208 + (head)->tqh_last = &(elm)->field.tqe_next; \
2209 + (listelm)->field.tqe_next = (elm); \
2210 + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
2211 +} while (0)
2212 +
2213 +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
2214 + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
2215 + (elm)->field.tqe_next = (listelm); \
2216 + *(listelm)->field.tqe_prev = (elm); \
2217 + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
2218 +} while (0)
2219 +
2220 +#define TAILQ_REMOVE(head, elm, field) do { \
2221 + if (((elm)->field.tqe_next) != NULL) \
2222 + (elm)->field.tqe_next->field.tqe_prev = \
2223 + (elm)->field.tqe_prev; \
2224 + else \
2225 + (head)->tqh_last = (elm)->field.tqe_prev; \
2226 + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
2227 +} while (0)
2228 +
2229 +#define TAILQ_REPLACE(head, elm, elm2, field) do { \
2230 + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
2231 + (elm2)->field.tqe_next->field.tqe_prev = \
2232 + &(elm2)->field.tqe_next; \
2233 + else \
2234 + (head)->tqh_last = &(elm2)->field.tqe_next; \
2235 + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
2236 + *(elm2)->field.tqe_prev = (elm2); \
2237 +} while (0)
2238 +
2239 +#endif /* !_SYS_QUEUE_H_ */
2240 Index: linux-2.6.17/include/linux/sched.h
2241 ===================================================================
2242 --- linux-2.6.17.orig/include/linux/sched.h
2243 +++ linux-2.6.17/include/linux/sched.h
2244 @@ -888,6 +888,10 @@ struct task_struct {
2245
2246 unsigned long ptrace_message;
2247 siginfo_t *last_siginfo; /* For ptrace use. */
2248 +#ifdef CONFIG_SYSTRACE
2249 + void *systrace;
2250 +#endif
2251 +
2252 /*
2253 * current io wait handle: wait queue entry to use for io waits
2254 * If this thread is processing aio, this points at the waitqueue
2255 Index: linux-2.6.17/include/linux/systrace.h
2256 ===================================================================
2257 --- /dev/null
2258 +++ linux-2.6.17/include/linux/systrace.h
2259 @@ -0,0 +1,216 @@
2260 +/*
2261 + * systrace.h
2262 + *
2263 + * Copyright (c) 2002 Marius Aamodt Eriksen <marius@umich.edu>
2264 + *
2265 + * These definitions are muchly replicated from Niels Provos' OpenBSD
2266 + * implementation.
2267 + */
2268 +
2269 +#ifndef _INCLUDE_LINUX_SYSTRACE_H
2270 +#define _INCLUDE_LINUX_SYSTRACE_H
2271 +
2272 +/*
2273 + * XXX this is kind of nasty -- should add manually to everything that
2274 + * needs it
2275 + */
2276 +
2277 +#define SYSTR_EMULEN 8 /* sync with sys proc */
2278 +
2279 +#ifdef __KERNEL__
2280 +/* XXX ugly. argh... linux... */
2281 +typedef u32 register_t;
2282 +#endif /* __KERNEL__ */
2283 +
2284 +struct str_msg_emul {
2285 + char emul[SYSTR_EMULEN];
2286 +};
2287 +
2288 +#define SYSTR_MAX_POLICIES 64
2289 +#define SYSTR_MAXARGS 64
2290 +
2291 +/* XXX change register_t (args, rval) to something portable. */
2292 +struct str_msg_ask {
2293 + int code;
2294 + int argsize;
2295 + u32 args[SYSTR_MAXARGS];
2296 + u32 rval[2];
2297 + int result;
2298 +};
2299 +
2300 +/* Queued on fork or exit of a process */
2301 +
2302 +struct str_msg_child {
2303 + pid_t new_pid;
2304 +};
2305 +struct str_msg_ugid {
2306 + uid_t uid;
2307 + gid_t gid;
2308 +};
2309 +
2310 +struct str_msg_execve {
2311 + register_t patharg;
2312 +};
2313 +
2314 +#define SYSTR_MSG_ASK 1
2315 +#define SYSTR_MSG_RES 2
2316 +#define SYSTR_MSG_EMUL 3
2317 +#define SYSTR_MSG_CHILD 4
2318 +#define SYSTR_MSG_UGID 5
2319 +#define SYSTR_MSG_EXECVE 6
2320 +
2321 +#define SYSTR_MSG_NOPROCESS(x) \
2322 + ((x)->msg.msg_type == SYSTR_MSG_CHILD)
2323 +
2324 +#define MAXPATHLEN PATH_MAX
2325 +
2326 +struct str_message {
2327 + /* XXX - should be u_int16_t */
2328 + int msg_seqnr;
2329 + int msg_type;
2330 + pid_t msg_pid;
2331 + short msg_policy;
2332 + short reserved;
2333 + union {
2334 + struct str_msg_emul msg_emul;
2335 + struct str_msg_ask msg_ask;
2336 + struct str_msg_child msg_child;
2337 + struct str_msg_ugid msg_ugid;
2338 + struct str_msg_execve msg_execve;
2339 + } msg_data;
2340 +};
2341 +
2342 +struct systrace_answer {
2343 + /* XXX - should be u_int16_t */
2344 + int stra_seqnr;
2345 + pid_t stra_pid;
2346 + int stra_policy;
2347 + int stra_error;
2348 + int stra_flags;
2349 + uid_t stra_seteuid; /* elevated privileges for system call */
2350 + gid_t stra_setegid;
2351 +};
2352 +
2353 +#define SYSTR_READ 1
2354 +#define SYSTR_WRITE 2
2355 +
2356 +struct systrace_io {
2357 + pid_t strio_pid;
2358 + int strio_op;
2359 + void *strio_offs;
2360 + void *strio_addr;
2361 + size_t strio_len;
2362 +};
2363 +
2364 +#define SYSTR_POLICY_NEW 1
2365 +#define SYSTR_POLICY_ASSIGN 2
2366 +#define SYSTR_POLICY_MODIFY 3
2367 +
2368 +struct systrace_policy {
2369 + int strp_op;
2370 + int strp_num;
2371 + union {
2372 + struct {
2373 + short code;
2374 + short policy;
2375 + } assign;
2376 + pid_t pid;
2377 + int maxents;
2378 + } strp_data;
2379 +};
2380 +
2381 +
2382 +struct systrace_replace {
2383 + pid_t strr_pid;
2384 + int strr_nrepl;
2385 + void *strr_base;
2386 + size_t strr_len;
2387 + int strr_argind[SYSTR_MAXARGS];
2388 + size_t strr_off[SYSTR_MAXARGS];
2389 + size_t strr_offlen[SYSTR_MAXARGS];
2390 +};
2391 +
2392 +#define strp_pid strp_data.pid
2393 +#define strp_maxents strp_data.maxents
2394 +#define strp_code strp_data.assign.code
2395 +#define strp_policy strp_data.assign.policy
2396 +
2397 +/* ioctl definitions */
2398 +#define STR_MAGIC 's'
2399 +
2400 +#define STRIOCATTACH _IOW(STR_MAGIC, 101, pid_t)
2401 +#define STRIOCDETACH _IOW(STR_MAGIC, 102, pid_t)
2402 +#define STRIOCANSWER _IOW(STR_MAGIC, 103, struct systrace_answer)
2403 +#define STRIOCIO _IOWR(STR_MAGIC, 104, struct systrace_io)
2404 +#define STRIOCPOLICY _IOWR(STR_MAGIC, 105, struct systrace_policy)
2405 +#define STRIOCGETCWD _IOW(STR_MAGIC, 106, pid_t)
2406 +#define STRIOCRESCWD _IO(STR_MAGIC, 107)
2407 +#define STRIOWAKE _IO(STR_MAGIC, 108)
2408 +#define STRIOCLONE _IOW(STR_MAGIC, 109, int *);
2409 +#define STRIOCREPLACE _IOW(STR_MAGIC, 110, struct systrace_replace)
2410 +
2411 +#define SYSTR_POLICY_ASK 0
2412 +#define SYSTR_POLICY_PERMIT 1
2413 +#define SYSTR_POLICY_NEVER 2
2414 +
2415 +#define SYSTR_FLAGS_RESULT 0x001
2416 +#define SYSTR_FLAGS_SETEUID 0x002
2417 +#define SYSTR_FLAGS_SETEGID 0x004
2418 +
2419 +#ifdef __KERNEL__
2420 +
2421 +struct str_process;
2422 +struct fsystrace {
2423 + struct semaphore lock;
2424 + wait_queue_head_t wqh;
2425 + TAILQ_HEAD(strprocessq, str_process) processes;
2426 + TAILQ_HEAD(strpolicyq, str_policy) policies;
2427 + int nprocesses;
2428 + struct strprocessq messages;
2429 + int npolicynr;
2430 + int npolicies;
2431 +
2432 + int issuser;
2433 + uid_t euid;
2434 + gid_t egid;
2435 +
2436 + pid_t pid;
2437 + /* cwd magic */
2438 + pid_t pwd_pid;
2439 + struct vfsmount *pwd_mnt;
2440 + struct dentry *pwd_dentry;
2441 + struct vfsmount *root_mnt;
2442 + struct dentry *root_dentry;
2443 +};
2444 +
2445 +/* Internal prototypes */
2446 +
2447 +/*
2448 + int systrace_redirect(int, struct proc *, void *, register_t *);
2449 + void systrace_exit(struct proc *);
2450 + void systrace_fork(struct proc *, struct proc *);
2451 +*/
2452 +
2453 +int init_systrace(void);
2454 +void systrace_fork(struct task_struct *, struct task_struct *);
2455 +void systrace_exit(struct task_struct *);
2456 +
2457 +/* crud needed to make systrace happy */
2458 +struct sysent { /* system call table */
2459 + short sy_narg; /* number of args */
2460 + short sy_argsize; /* total size of arguments */
2461 +};
2462 +
2463 +/* Macros to set/clear/test flags. */
2464 +#define SET(t, f) ((t) |= (f))
2465 +#define CLR(t, f) ((t) &= ~(f))
2466 +#define ISSET(t, f) ((t) & (f))
2467 +
2468 +
2469 +#endif /* __KERNEL__ */
2470 +
2471 +#ifndef __KERNEL__
2472 +//typedef u_int32_t register_t;
2473 +#endif /* !__KERNEL__ */
2474 +
2475 +#endif /* _INCLUDE_LINUX_SYSTRACE_H */
2476 Index: linux-2.6.17/kernel/exit.c
2477 ===================================================================
2478 --- linux-2.6.17.orig/kernel/exit.c
2479 +++ linux-2.6.17/kernel/exit.c
2480 @@ -36,6 +36,11 @@
2481 #include <linux/compat.h>
2482 #include <linux/pipe_fs_i.h>
2483 #include <linux/audit.h> /* for audit_free() */
2484 +#ifdef CONFIG_SYSTRACE
2485 +#include <linux/queue.h>
2486 +#include <asm/semaphore.h>
2487 +#include <linux/systrace.h>
2488 +#endif
2489 #include <linux/grsecurity.h>
2490
2491 #ifdef CONFIG_GRKERNSEC
2492 @@ -937,6 +942,10 @@ fastcall NORET_TYPE void do_exit(long co
2493 gr_acl_handle_psacct(tsk, code);
2494 gr_acl_handle_exit();
2495
2496 +#ifdef CONFIG_SYSTRACE
2497 + systrace_exit(tsk);
2498 +#endif
2499 +
2500 exit_mm(tsk);
2501
2502 exit_sem(tsk);
2503 Index: linux-2.6.17/kernel/fork.c
2504 ===================================================================
2505 --- linux-2.6.17.orig/kernel/fork.c
2506 +++ linux-2.6.17/kernel/fork.c
2507 @@ -39,6 +39,11 @@
2508 #include <linux/rcupdate.h>
2509 #include <linux/ptrace.h>
2510 #include <linux/mount.h>
2511 +#ifdef CONFIG_SYSTRACE
2512 +#include <linux/queue.h>
2513 +#include <asm/semaphore.h>
2514 +#include <linux/systrace.h>
2515 +#endif /* CONFIG_SYSTRACE */
2516 #include <linux/audit.h>
2517 #include <linux/profile.h>
2518 #include <linux/rmap.h>
2519 @@ -1351,6 +1356,11 @@ long do_fork(unsigned long clone_flags,
2520 set_tsk_thread_flag(p, TIF_SIGPENDING);
2521 }
2522
2523 +#ifdef CONFIG_SYSTRACE
2524 + if (current->systrace != NULL)
2525 + systrace_fork(current, p);
2526 +#endif
2527 +
2528 if (!(clone_flags & CLONE_STOPPED))
2529 wake_up_new_task(p, clone_flags);
2530 else
2531 Index: linux-2.6.17/security/Kconfig
2532 ===================================================================
2533 --- linux-2.6.17.orig/security/Kconfig
2534 +++ linux-2.6.17/security/Kconfig
2535 @@ -547,6 +547,7 @@ config SECURITY_SECLVL
2536 If you are unsure how to answer this question, answer N.
2537
2538 source security/selinux/Kconfig
2539 +source drivers/systrace/Kconfig
2540
2541 endmenu
2542

  ViewVC Help
Powered by ViewVC 1.1.20