]>
Commit | Line | Data |
---|---|---|
f87181f3 AG |
1 | This is TOMOYO Linux patch for kernel 2.6.28.2. |
2 | ||
3 | Source code for this patch is http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.2.tar.bz2 | |
4 | --- | |
5 | fs/Kconfig | 2 | |
6 | fs/Makefile | 2 | |
7 | fs/attr.c | 10 +++ | |
8 | fs/compat.c | 5 + | |
9 | fs/compat_ioctl.c | 9 +++ | |
10 | fs/exec.c | 21 ++++++- | |
11 | fs/fcntl.c | 9 +++ | |
12 | fs/ioctl.c | 7 ++ | |
13 | fs/namei.c | 120 ++++++++++++++++++++++++++++++++++++++++ | |
14 | fs/namespace.c | 49 ++++++++++++++++ | |
15 | fs/open.c | 28 +++++++++ | |
16 | fs/proc/Makefile | 3 + | |
17 | fs/proc/version.c | 11 +++ | |
18 | include/linux/init_task.h | 4 + | |
19 | include/linux/sched.h | 9 +++ | |
20 | kernel/compat.c | 7 ++ | |
21 | kernel/kexec.c | 7 ++ | |
22 | kernel/kmod.c | 5 + | |
23 | kernel/module.c | 11 +++ | |
24 | kernel/ptrace.c | 15 +++++ | |
25 | kernel/sched.c | 7 ++ | |
26 | kernel/signal.c | 21 +++++++ | |
27 | kernel/sys.c | 21 +++++++ | |
28 | kernel/sysctl.c | 95 +++++++++++++++++++++++++++++++ | |
29 | kernel/time.c | 11 +++ | |
30 | kernel/time/ntp.c | 11 +++ | |
31 | net/core/datagram.c | 11 +++ | |
32 | net/ipv4/inet_connection_sock.c | 7 ++ | |
33 | net/ipv4/inet_hashtables.c | 7 ++ | |
34 | net/ipv4/udp.c | 9 ++- | |
35 | net/socket.c | 41 +++++++++++++ | |
36 | net/unix/af_unix.c | 15 +++++ | |
37 | 32 files changed, 587 insertions(+), 3 deletions(-) | |
38 | ||
39 | --- linux-2.6.28.2.orig/fs/Kconfig | |
40 | +++ linux-2.6.28.2/fs/Kconfig | |
41 | @@ -1557,4 +1557,6 @@ endif | |
42 | source "fs/nls/Kconfig" | |
43 | source "fs/dlm/Kconfig" | |
44 | ||
45 | +source "fs/Kconfig.ccs" | |
46 | + | |
47 | endmenu | |
48 | --- linux-2.6.28.2.orig/fs/Makefile | |
49 | +++ linux-2.6.28.2/fs/Makefile | |
50 | @@ -122,3 +122,5 @@ obj-$(CONFIG_HPPFS) += hppfs/ | |
51 | obj-$(CONFIG_DEBUG_FS) += debugfs/ | |
52 | obj-$(CONFIG_OCFS2_FS) += ocfs2/ | |
53 | obj-$(CONFIG_GFS2_FS) += gfs2/ | |
54 | + | |
55 | +include $(srctree)/fs/Makefile-2.6.ccs | |
56 | --- linux-2.6.28.2.orig/fs/attr.c | |
57 | +++ linux-2.6.28.2/fs/attr.c | |
58 | @@ -14,6 +14,9 @@ | |
59 | #include <linux/proc_fs.h> | |
60 | #include <linux/devpts_fs.h> | |
61 | #include <linux/vs_tag.h> | |
62 | +/***** TOMOYO Linux start. *****/ | |
63 | +#include <linux/tomoyo.h> | |
64 | +/***** TOMOYO Linux end. *****/ | |
65 | ||
66 | /* Taken over from the old code... */ | |
67 | ||
68 | @@ -162,6 +165,13 @@ int notify_change(struct dentry * dentry | |
69 | error = security_inode_setattr(dentry, attr); | |
70 | if (error) | |
71 | return error; | |
72 | + /***** TOMOYO Linux start. *****/ | |
73 | + if ((ia_valid & ATTR_MODE) && !ccs_capable(TOMOYO_SYS_CHMOD)) | |
74 | + return -EPERM; | |
75 | + if ((ia_valid & (ATTR_UID | ATTR_GID)) && | |
76 | + !ccs_capable(TOMOYO_SYS_CHOWN)) | |
77 | + return -EPERM; | |
78 | + /***** TOMOYO Linux end. *****/ | |
79 | ||
80 | if (ia_valid & ATTR_SIZE) | |
81 | down_write(&dentry->d_inode->i_alloc_sem); | |
82 | --- linux-2.6.28.2.orig/fs/compat.c | |
83 | +++ linux-2.6.28.2/fs/compat.c | |
84 | @@ -56,6 +56,9 @@ | |
85 | #include <asm/mmu_context.h> | |
86 | #include <asm/ioctls.h> | |
87 | #include "internal.h" | |
88 | +/***** TOMOYO Linux start. *****/ | |
89 | +#include <linux/tomoyo.h> | |
90 | +/***** TOMOYO Linux end. *****/ | |
91 | ||
92 | int compat_log = 1; | |
93 | ||
94 | @@ -1437,7 +1440,7 @@ int compat_do_execve(char * filename, | |
95 | if (retval < 0) | |
96 | goto out; | |
97 | ||
98 | - retval = search_binary_handler(bprm, regs); | |
99 | + retval = search_binary_handler_with_transition(bprm, regs); | |
100 | if (retval >= 0) { | |
101 | /* execve success */ | |
102 | security_bprm_free(bprm); | |
103 | --- linux-2.6.28.2.orig/fs/compat_ioctl.c | |
104 | +++ linux-2.6.28.2/fs/compat_ioctl.c | |
105 | @@ -113,6 +113,9 @@ | |
106 | #ifdef CONFIG_SPARC | |
107 | #include <asm/fbio.h> | |
108 | #endif | |
109 | +/***** TOMOYO Linux start. *****/ | |
110 | +#include <linux/tomoyo.h> | |
111 | +/***** TOMOYO Linux end. *****/ | |
112 | ||
113 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, | |
114 | unsigned long arg, struct file *f) | |
115 | @@ -2803,6 +2806,12 @@ asmlinkage long compat_sys_ioctl(unsigne | |
116 | /*FALL THROUGH*/ | |
117 | ||
118 | default: | |
119 | + /***** TOMOYO Linux start. *****/ | |
120 | + if (!ccs_capable(TOMOYO_SYS_IOCTL)) { | |
121 | + error = -EPERM; | |
122 | + goto out_fput; | |
123 | + } | |
124 | + /***** TOMOYO Linux end. *****/ | |
125 | if (filp->f_op && filp->f_op->compat_ioctl) { | |
126 | error = filp->f_op->compat_ioctl(filp, cmd, arg); | |
127 | if (error != -ENOIOCTLCMD) | |
128 | --- linux-2.6.28.2.orig/fs/exec.c | |
129 | +++ linux-2.6.28.2/fs/exec.c | |
130 | @@ -61,6 +61,10 @@ | |
131 | #include <linux/a.out.h> | |
132 | #endif | |
133 | ||
134 | +/***** TOMOYO Linux start. *****/ | |
135 | +#include <linux/tomoyo.h> | |
136 | +/***** TOMOYO Linux end. *****/ | |
137 | + | |
138 | int core_uses_pid; | |
139 | char core_pattern[CORENAME_MAX_SIZE] = "core"; | |
140 | int suid_dumpable = 0; | |
141 | @@ -129,6 +133,12 @@ SYSCALL_DEFINE1(uselib, const char __use | |
142 | error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); | |
143 | if (error) | |
144 | goto exit; | |
145 | + /***** TOMOYO Linux start. *****/ | |
146 | + /* 01 means "read". */ | |
147 | + error = ccs_check_open_permission(nd.path.dentry, nd.path.mnt, 01); | |
148 | + if (error) | |
149 | + goto exit; | |
150 | + /***** TOMOYO Linux end. *****/ | |
151 | ||
152 | file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); | |
153 | error = PTR_ERR(file); | |
154 | @@ -682,6 +692,15 @@ struct file *open_exec(const char *name) | |
155 | err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); | |
156 | if (err) | |
157 | goto out_path_put; | |
158 | + /***** TOMOYO Linux start. *****/ | |
159 | + if (current->tomoyo_flags & TOMOYO_CHECK_READ_FOR_OPEN_EXEC) { | |
160 | + /* 01 means "read". */ | |
161 | + err = ccs_check_open_permission(nd.path.dentry, nd.path.mnt, | |
162 | + 01); | |
163 | + if (err) | |
164 | + goto out_path_put; | |
165 | + } | |
166 | + /***** TOMOYO Linux end. *****/ | |
167 | ||
168 | file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); | |
169 | if (IS_ERR(file)) | |
170 | @@ -1340,7 +1359,7 @@ int do_execve(char * filename, | |
171 | goto out; | |
172 | ||
173 | current->flags &= ~PF_KTHREAD; | |
174 | - retval = search_binary_handler(bprm,regs); | |
175 | + retval = search_binary_handler_with_transition(bprm, regs); | |
176 | if (retval >= 0) { | |
177 | /* execve success */ | |
178 | security_bprm_free(bprm); | |
179 | --- linux-2.6.28.2.orig/fs/fcntl.c | |
180 | +++ linux-2.6.28.2/fs/fcntl.c | |
181 | @@ -24,6 +24,9 @@ | |
182 | #include <asm/poll.h> | |
183 | #include <asm/siginfo.h> | |
184 | #include <asm/uaccess.h> | |
185 | +/***** TOMOYO Linux start. *****/ | |
186 | +#include <linux/tomoyo.h> | |
187 | +/***** TOMOYO Linux end. *****/ | |
188 | ||
189 | void set_close_on_exec(unsigned int fd, int flag) | |
190 | { | |
191 | @@ -155,6 +158,12 @@ static int setfl(int fd, struct file * f | |
192 | if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode)) | |
193 | return -EPERM; | |
194 | ||
195 | + /***** TOMOYO Linux start. *****/ | |
196 | + if (((arg ^ filp->f_flags) & O_APPEND) && | |
197 | + ccs_check_rewrite_permission(filp)) | |
198 | + return -EPERM; | |
199 | + /***** TOMOYO Linux end. *****/ | |
200 | + | |
201 | /* O_NOATIME can only be set by the owner or superuser */ | |
202 | if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME)) | |
203 | if (!is_owner_or_cap(inode)) | |
204 | --- linux-2.6.28.2.orig/fs/ioctl.c | |
205 | +++ linux-2.6.28.2/fs/ioctl.c | |
206 | @@ -17,6 +17,9 @@ | |
207 | #include <linux/buffer_head.h> | |
208 | ||
209 | #include <asm/ioctls.h> | |
210 | +/***** TOMOYO Linux start. *****/ | |
211 | +#include <linux/tomoyo.h> | |
212 | +/***** TOMOYO Linux end. *****/ | |
213 | ||
214 | /* So that the fiemap access checks can't overflow on 32 bit machines. */ | |
215 | #define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent)) | |
216 | @@ -40,6 +43,10 @@ static long vfs_ioctl(struct file *filp, | |
217 | ||
218 | if (!filp->f_op) | |
219 | goto out; | |
220 | + /***** TOMOYO Linux start. *****/ | |
221 | + if (!ccs_capable(TOMOYO_SYS_IOCTL)) | |
222 | + return -EPERM; | |
223 | + /***** TOMOYO Linux end. *****/ | |
224 | ||
225 | if (filp->f_op->unlocked_ioctl) { | |
226 | error = filp->f_op->unlocked_ioctl(filp, cmd, arg); | |
227 | --- linux-2.6.28.2.orig/fs/namei.c | |
228 | +++ linux-2.6.28.2/fs/namei.c | |
229 | @@ -35,6 +35,10 @@ | |
230 | ||
231 | #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) | |
232 | ||
233 | +/***** TOMOYO Linux start. *****/ | |
234 | +#include <linux/tomoyo.h> | |
235 | +/***** TOMOYO Linux end. *****/ | |
236 | + | |
237 | /* [Feb-1997 T. Schoebel-Theuer] | |
238 | * Fundamental changes in the pathname lookup mechanisms (namei) | |
239 | * were necessary because of omirr. The reason is that omirr needs | |
240 | @@ -1484,6 +1488,14 @@ int vfs_create(struct inode *dir, struct | |
241 | error = security_inode_create(dir, dentry, mode); | |
242 | if (error) | |
243 | return error; | |
244 | + /***** TOMOYO Linux start. *****/ | |
245 | + if (nd) { | |
246 | + error = ccs_check_1path_perm(TYPE_CREATE_ACL, dentry, | |
247 | + nd->path.mnt); | |
248 | + if (error) | |
249 | + return error; | |
250 | + } | |
251 | + /***** TOMOYO Linux end. *****/ | |
252 | DQUOT_INIT(dir); | |
253 | error = dir->i_op->create(dir, dentry, mode, nd); | |
254 | if (!error) | |
255 | @@ -1538,6 +1550,13 @@ int may_open(struct nameidata *nd, int a | |
256 | if (!is_owner_or_cap(inode)) | |
257 | return -EPERM; | |
258 | ||
259 | + /***** TOMOYO Linux start. *****/ | |
260 | + /* includes O_APPEND and O_TRUNC checks */ | |
261 | + error = ccs_check_open_permission(dentry, nd->path.mnt, flag); | |
262 | + if (error) | |
263 | + return error; | |
264 | + /***** TOMOYO Linux end. *****/ | |
265 | + | |
266 | /* | |
267 | * Ensure there are no outstanding leases on the file. | |
268 | */ | |
269 | @@ -1594,6 +1613,9 @@ static int __open_namei_create(struct na | |
270 | return may_open(nd, 0, flag & ~O_TRUNC); | |
271 | } | |
272 | ||
273 | +/***** TOMOYO Linux start. *****/ | |
274 | +#include <linux/tomoyo_vfs.h> | |
275 | +/***** TOMOYO Linux end. *****/ | |
276 | /* | |
277 | * Note that while the flag value (low two bits) for sys_open means: | |
278 | * 00 - read-only | |
279 | @@ -1954,6 +1976,16 @@ int vfs_mknod(struct inode *dir, struct | |
280 | ||
281 | static int may_mknod(mode_t mode) | |
282 | { | |
283 | + /***** TOMOYO Linux start. *****/ | |
284 | + if (S_ISCHR(mode) && !ccs_capable(TOMOYO_CREATE_CHAR_DEV)) | |
285 | + return -EPERM; | |
286 | + if (S_ISBLK(mode) && !ccs_capable(TOMOYO_CREATE_BLOCK_DEV)) | |
287 | + return -EPERM; | |
288 | + if (S_ISFIFO(mode) && !ccs_capable(TOMOYO_CREATE_FIFO)) | |
289 | + return -EPERM; | |
290 | + if (S_ISSOCK(mode) && !ccs_capable(TOMOYO_CREATE_UNIX_SOCKET)) | |
291 | + return -EPERM; | |
292 | + /***** TOMOYO Linux end. *****/ | |
293 | switch (mode & S_IFMT) { | |
294 | case S_IFREG: | |
295 | case S_IFCHR: | |
296 | @@ -2002,10 +2034,34 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const | |
297 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); | |
298 | break; | |
299 | case S_IFCHR: case S_IFBLK: | |
300 | + /***** TOMOYO Linux start. *****/ | |
301 | + error = pre_vfs_mknod(nd.path.dentry->d_inode, dentry, | |
302 | + mode); | |
303 | + if (error) | |
304 | + break; | |
305 | + error = ccs_check_1path_perm(S_ISCHR(mode) ? | |
306 | + TYPE_MKCHAR_ACL : | |
307 | + TYPE_MKBLOCK_ACL, | |
308 | + dentry, nd.path.mnt); | |
309 | + if (error) | |
310 | + break; | |
311 | + /***** TOMOYO Linux end. *****/ | |
2380c486 JR |
312 | error = vfs_mknod(nd.path.dentry->d_inode, dentry, |
313 | nd.path.mnt, mode, new_decode_dev(dev)); | |
f87181f3 AG |
314 | break; |
315 | case S_IFIFO: case S_IFSOCK: | |
316 | + /***** TOMOYO Linux start. *****/ | |
317 | + error = pre_vfs_mknod(nd.path.dentry->d_inode, dentry, | |
318 | + mode); | |
319 | + if (error) | |
320 | + break; | |
321 | + error = ccs_check_1path_perm(S_ISFIFO(mode) ? | |
322 | + TYPE_MKFIFO_ACL : | |
323 | + TYPE_MKSOCK_ACL, | |
324 | + dentry, nd.path.mnt); | |
325 | + if (error) | |
326 | + break; | |
327 | + /***** TOMOYO Linux end. *****/ | |
2380c486 JR |
328 | error = vfs_mknod(nd.path.dentry->d_inode, dentry, |
329 | nd.path.mnt, mode, 0); | |
f87181f3 | 330 | break; |
f87181f3 AG |
331 | @@ -2068,6 +2124,13 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const |
332 | error = mnt_want_write(nd.path.mnt); | |
333 | if (error) | |
334 | goto out_dput; | |
335 | + /***** TOMOYO Linux start. *****/ | |
336 | + error = pre_vfs_mkdir(nd.path.dentry->d_inode, dentry); | |
337 | + if (!error) | |
338 | + error = ccs_check_1path_perm(TYPE_MKDIR_ACL, dentry, | |
339 | + nd.path.mnt); | |
340 | + if (!error) | |
341 | + /***** TOMOYO Linux end. *****/ | |
2380c486 | 342 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, nd.path.mnt, mode); |
f87181f3 AG |
343 | mnt_drop_write(nd.path.mnt); |
344 | out_dput: | |
345 | @@ -2178,6 +2241,13 @@ static long do_rmdir(int dfd, const char | |
346 | error = mnt_want_write(nd.path.mnt); | |
347 | if (error) | |
348 | goto exit3; | |
349 | + /***** TOMOYO Linux start. *****/ | |
350 | + error = pre_vfs_rmdir(nd.path.dentry->d_inode, dentry); | |
351 | + if (!error) | |
352 | + error = ccs_check_1path_perm(TYPE_RMDIR_ACL, dentry, | |
353 | + nd.path.mnt); | |
354 | + if (!error) | |
355 | + /***** TOMOYO Linux end. *****/ | |
2380c486 | 356 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry, nd.path.mnt); |
f87181f3 | 357 | mnt_drop_write(nd.path.mnt); |
2380c486 | 358 | if (!error && (saved_dev || saved_ino)) |
f87181f3 AG |
359 | @@ -2239,6 +2309,10 @@ static long do_unlinkat(int dfd, const c |
360 | struct inode *inode = NULL; | |
361 | ino_t saved_ino = 0; | |
362 | dev_t saved_dev = 0; | |
363 | + /***** TOMOYO Linux start. *****/ | |
364 | + if (!ccs_capable(TOMOYO_SYS_UNLINK)) | |
365 | + return -EPERM; | |
366 | + /***** TOMOYO Linux end. *****/ | |
367 | ||
368 | error = user_path_parent(dfd, pathname, &nd, &name); | |
369 | if (error) | |
370 | @@ -2263,6 +2337,13 @@ static long do_unlinkat(int dfd, const c | |
371 | error = mnt_want_write(nd.path.mnt); | |
372 | if (error) | |
373 | goto exit2; | |
374 | + /***** TOMOYO Linux start. *****/ | |
375 | + error = pre_vfs_unlink(nd.path.dentry->d_inode, dentry); | |
376 | + if (!error) | |
377 | + error = ccs_check_1path_perm(TYPE_UNLINK_ACL, dentry, | |
378 | + nd.path.mnt); | |
379 | + if (!error) | |
380 | + /***** TOMOYO Linux end. *****/ | |
2380c486 JR |
381 | error = vfs_unlink(nd.path.dentry->d_inode, dentry, nd.path.mnt); |
382 | if (!error && (saved_ino || saved_dev)) | |
383 | gr_handle_delete(saved_ino, saved_dev); | |
f87181f3 AG |
384 | @@ -2327,6 +2408,10 @@ SYSCALL_DEFINE3(symlinkat, const char __ |
385 | char *to; | |
386 | struct dentry *dentry; | |
387 | struct nameidata nd; | |
388 | + /***** TOMOYO Linux start. *****/ | |
389 | + if (!ccs_capable(TOMOYO_SYS_SYMLINK)) | |
390 | + return -EPERM; | |
391 | + /***** TOMOYO Linux end. *****/ | |
392 | ||
393 | from = getname(oldname); | |
394 | if (IS_ERR(from)) | |
395 | @@ -2344,6 +2429,13 @@ SYSCALL_DEFINE3(symlinkat, const char __ | |
396 | error = mnt_want_write(nd.path.mnt); | |
397 | if (error) | |
398 | goto out_dput; | |
399 | + /***** TOMOYO Linux start. *****/ | |
400 | + error = pre_vfs_symlink(nd.path.dentry->d_inode, dentry); | |
401 | + if (!error) | |
402 | + error = ccs_check_1path_perm(TYPE_SYMLINK_ACL, dentry, | |
403 | + nd.path.mnt); | |
404 | + if (!error) | |
405 | + /***** TOMOYO Linux end. *****/ | |
2380c486 JR |
406 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, nd.path.mnt, from); |
407 | if (!error) | |
408 | gr_handle_create(dentry, nd.path.mnt); | |
f87181f3 AG |
409 | @@ -2420,6 +2512,10 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con |
410 | ||
411 | if ((flags & ~AT_SYMLINK_FOLLOW) != 0) | |
412 | return -EINVAL; | |
413 | + /***** TOMOYO Linux start. *****/ | |
414 | + if (!ccs_capable(TOMOYO_SYS_LINK)) | |
415 | + return -EPERM; | |
416 | + /***** TOMOYO Linux end. *****/ | |
417 | ||
418 | error = user_path_at(olddfd, oldname, | |
419 | flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0, | |
420 | @@ -2440,6 +2536,15 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con | |
421 | error = mnt_want_write(nd.path.mnt); | |
422 | if (error) | |
423 | goto out_dput; | |
424 | + /***** TOMOYO Linux start. *****/ | |
425 | + error = pre_vfs_link(old_path.dentry, nd.path.dentry->d_inode, | |
426 | + new_dentry); | |
427 | + if (!error) | |
428 | + error = ccs_check_2path_perm(TYPE_LINK_ACL, old_path.dentry, | |
429 | + old_path.mnt, new_dentry, | |
430 | + nd.path.mnt); | |
431 | + if (!error) | |
432 | + /***** TOMOYO Linux end. *****/ | |
2380c486 JR |
433 | error = vfs_link(old_path.dentry, old_path.mnt, |
434 | nd.path.dentry->d_inode, | |
435 | new_dentry, nd.path.mnt); | |
f87181f3 AG |
436 | @@ -2616,6 +2721,10 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c |
437 | char *from; | |
438 | char *to; | |
439 | int error; | |
440 | + /***** TOMOYO Linux start. *****/ | |
441 | + if (!ccs_capable(TOMOYO_SYS_RENAME)) | |
442 | + return -EPERM; | |
443 | + /***** TOMOYO Linux end. *****/ | |
444 | ||
445 | error = user_path_parent(olddfd, oldname, &oldnd, &from); | |
446 | if (error) | |
447 | @@ -2672,6 +2781,17 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c | |
448 | error = -ENOTEMPTY; | |
449 | if (new_dentry == trap) | |
450 | goto exit5; | |
451 | + /***** TOMOYO Linux start. *****/ | |
452 | + error = pre_vfs_rename(old_dir->d_inode, old_dentry, | |
453 | + new_dir->d_inode, new_dentry); | |
454 | + if (error) | |
455 | + goto exit5; | |
456 | + error = ccs_check_2path_perm(TYPE_RENAME_ACL, old_dentry, | |
457 | + oldnd.path.mnt, new_dentry, | |
458 | + newnd.path.mnt); | |
459 | + if (error) | |
460 | + goto exit5; | |
461 | + /***** TOMOYO Linux end. *****/ | |
462 | ||
463 | error = mnt_want_write(oldnd.path.mnt); | |
464 | if (error) | |
465 | --- linux-2.6.28.2.orig/fs/namespace.c | |
466 | +++ linux-2.6.28.2/fs/namespace.c | |
467 | @@ -31,6 +31,12 @@ | |
468 | #include <asm/unistd.h> | |
469 | #include "pnode.h" | |
470 | #include "internal.h" | |
471 | +/***** SAKURA Linux start. *****/ | |
472 | +#include <linux/sakura.h> | |
473 | +/***** SAKURA Linux end. *****/ | |
474 | +/***** TOMOYO Linux start. *****/ | |
475 | +#include <linux/tomoyo.h> | |
476 | +/***** TOMOYO Linux end. *****/ | |
477 | ||
478 | #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head)) | |
479 | #define HASH_SIZE (1UL << HASH_SHIFT) | |
480 | @@ -1041,6 +1047,11 @@ static int do_umount(struct vfsmount *mn | |
481 | if (retval) | |
482 | return retval; | |
483 | ||
484 | + /***** SAKURA Linux start. *****/ | |
485 | + if (ccs_may_umount(mnt)) | |
486 | + return -EPERM; | |
487 | + /***** SAKURA Linux end. *****/ | |
488 | + | |
489 | /* | |
490 | * Allow userspace to request a mountpoint be expired rather than | |
491 | * unmounting unconditionally. Unmount only happens if: | |
492 | @@ -1132,6 +1143,10 @@ SYSCALL_DEFINE2(umount, char __user *, n | |
493 | { | |
494 | struct path path; | |
495 | int retval; | |
496 | + /***** TOMOYO Linux start. *****/ | |
497 | + if (!ccs_capable(TOMOYO_SYS_UMOUNT)) | |
498 | + return -EPERM; | |
499 | + /***** TOMOYO Linux end. *****/ | |
500 | ||
501 | retval = user_path(name, &path); | |
502 | if (retval) | |
503 | @@ -1480,6 +1495,11 @@ static int do_loopback(struct path *path | |
504 | ||
505 | if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt)) | |
506 | goto out; | |
507 | + /***** SAKURA Linux start. *****/ | |
508 | + err = -EPERM; | |
509 | + if (ccs_may_mount(path)) | |
510 | + goto out; | |
511 | + /***** SAKURA Linux end. *****/ | |
512 | ||
513 | err = -ENOMEM; | |
514 | if (recurse) | |
515 | @@ -1591,6 +1611,11 @@ static int do_move_mount(struct path *pa | |
516 | if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt)) | |
517 | goto out; | |
518 | ||
519 | + /***** SAKURA Linux start. *****/ | |
520 | + err = -EPERM; | |
521 | + if (ccs_may_umount(old_path.mnt) || ccs_may_mount(path)) | |
522 | + goto out; | |
523 | + /***** SAKURA Linux end. *****/ | |
524 | err = -ENOENT; | |
525 | mutex_lock(&path->dentry->d_inode->i_mutex); | |
526 | if (IS_DEADDIR(path->dentry->d_inode)) | |
527 | @@ -1694,6 +1719,11 @@ int do_add_mount(struct vfsmount *newmnt | |
528 | err = -EINVAL; | |
529 | if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode)) | |
530 | goto unlock; | |
531 | + /***** SAKURA Linux start. *****/ | |
532 | + err = -EPERM; | |
533 | + if (ccs_may_mount(path)) | |
534 | + goto unlock; | |
535 | + /***** SAKURA Linux end. *****/ | |
536 | ||
537 | newmnt->mnt_flags = mnt_flags; | |
538 | if ((err = graft_tree(newmnt, path))) | |
539 | @@ -1917,6 +1947,17 @@ long do_mount(char *dev_name, char *dir_ | |
540 | if (data_page) | |
541 | ((char *)data_page)[PAGE_SIZE - 1] = 0; | |
542 | ||
543 | + /***** TOMOYO Linux start. *****/ | |
544 | + if (!ccs_capable(TOMOYO_SYS_MOUNT)) | |
545 | + return -EPERM; | |
546 | + /***** TOMOYO Linux end. *****/ | |
547 | + /***** SAKURA Linux start. *****/ | |
548 | + retval = ccs_check_mount_permission(dev_name, dir_name, type_page, | |
549 | + &flags); | |
550 | + if (retval) | |
551 | + return retval; | |
552 | + /***** SAKURA Linux end. *****/ | |
553 | + | |
554 | /* Separate the per-mountpoint flags */ | |
555 | if (flags & MS_NOSUID) | |
556 | mnt_flags |= MNT_NOSUID; | |
557 | @@ -2180,6 +2221,10 @@ SYSCALL_DEFINE2(pivot_root, const char _ | |
558 | ||
559 | if (!capable(CAP_SYS_ADMIN)) | |
560 | return -EPERM; | |
561 | + /***** TOMOYO Linux start. *****/ | |
562 | + if (!ccs_capable(TOMOYO_SYS_PIVOT_ROOT)) | |
563 | + return -EPERM; | |
564 | + /***** TOMOYO Linux end. *****/ | |
565 | ||
566 | error = user_path_dir(new_root, &new); | |
567 | if (error) | |
568 | @@ -2193,6 +2238,10 @@ SYSCALL_DEFINE2(pivot_root, const char _ | |
569 | goto out1; | |
570 | ||
571 | error = security_sb_pivotroot(&old, &new); | |
572 | + /***** SAKURA Linux start. *****/ | |
573 | + if (!error) | |
574 | + error = ccs_check_pivot_root_permission(&old, &new); | |
575 | + /***** SAKURA Linux end. *****/ | |
576 | if (error) { | |
577 | path_put(&old); | |
578 | goto out1; | |
579 | --- linux-2.6.28.2.orig/fs/open.c | |
580 | +++ linux-2.6.28.2/fs/open.c | |
581 | @@ -29,6 +29,12 @@ | |
582 | #include <linux/vs_tag.h> | |
583 | #include <linux/vs_cowbl.h> | |
584 | #include <linux/grsecurity.h> | |
585 | +/***** SAKURA Linux start. *****/ | |
586 | +#include <linux/sakura.h> | |
587 | +/***** SAKURA Linux end. *****/ | |
588 | +/***** TOMOYO Linux start. *****/ | |
589 | +#include <linux/tomoyo.h> | |
590 | +/***** TOMOYO Linux end. *****/ | |
591 | ||
592 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |
593 | { | |
594 | @@ -269,6 +275,11 @@ static long do_sys_truncate(const char _ | |
595 | if (error) | |
596 | goto put_write_and_out; | |
597 | ||
598 | + /***** TOMOYO Linux start. *****/ | |
599 | + error = ccs_check_1path_perm(TYPE_TRUNCATE_ACL, path.dentry, path.mnt); | |
600 | + if (error) | |
601 | + goto put_write_and_out; | |
602 | + /***** TOMOYO Linux end. *****/ | |
603 | error = locks_verify_truncate(inode, NULL, length); | |
604 | if (!error) { | |
605 | DQUOT_INIT(inode); | |
606 | @@ -325,6 +336,11 @@ static long do_sys_ftruncate(unsigned in | |
607 | if (IS_APPEND(inode)) | |
608 | goto out_putf; | |
609 | ||
610 | + /***** TOMOYO Linux start. *****/ | |
611 | + error = ccs_check_1path_perm(TYPE_TRUNCATE_ACL, dentry, file->f_vfsmnt); | |
612 | + if (error) | |
613 | + goto out_putf; | |
614 | + /***** TOMOYO Linux end. *****/ | |
615 | error = locks_verify_truncate(inode, file, length); | |
616 | if (!error) | |
617 | error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); | |
618 | @@ -590,6 +606,14 @@ SYSCALL_DEFINE1(chroot, const char __use | |
619 | error = -EPERM; | |
620 | if (!capable(CAP_SYS_CHROOT)) | |
621 | goto dput_and_out; | |
622 | + /***** TOMOYO Linux start. *****/ | |
623 | + if (!ccs_capable(TOMOYO_SYS_CHROOT)) | |
624 | + goto dput_and_out; | |
625 | + /***** TOMOYO Linux end. *****/ | |
626 | + /***** SAKURA Linux start. *****/ | |
627 | + if (ccs_check_chroot_permission(&path)) | |
628 | + goto dput_and_out; | |
629 | + /***** SAKURA Linux end. *****/ | |
630 | ||
631 | set_fs_root(current->fs, &path); | |
632 | error = 0; | |
633 | @@ -1156,6 +1180,10 @@ EXPORT_SYMBOL(sys_close); | |
634 | */ | |
635 | SYSCALL_DEFINE0(vhangup) | |
636 | { | |
637 | + /***** TOMOYO Linux start. *****/ | |
638 | + if (!ccs_capable(TOMOYO_SYS_VHANGUP)) | |
639 | + return -EPERM; | |
640 | + /***** TOMOYO Linux end. *****/ | |
641 | if (capable(CAP_SYS_TTY_CONFIG)) { | |
642 | tty_vhangup_self(); | |
643 | return 0; | |
644 | --- linux-2.6.28.2.orig/fs/proc/Makefile | |
645 | +++ linux-2.6.28.2/fs/proc/Makefile | |
646 | @@ -25,3 +25,6 @@ proc-$(CONFIG_PROC_VMCORE) += vmcore.o | |
647 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | |
648 | proc-$(CONFIG_PRINTK) += kmsg.o | |
649 | proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o | |
650 | + | |
651 | +proc-$(CONFIG_SAKURA) += ccs_proc.o | |
652 | +proc-$(CONFIG_TOMOYO) += ccs_proc.o | |
653 | --- linux-2.6.28.2.orig/fs/proc/version.c | |
654 | +++ linux-2.6.28.2/fs/proc/version.c | |
655 | @@ -32,3 +32,14 @@ static int __init proc_version_init(void | |
656 | return 0; | |
657 | } | |
658 | module_init(proc_version_init); | |
659 | + | |
660 | +/***** CCS start. *****/ | |
661 | +#if defined(CONFIG_SAKURA) || defined(CONFIG_TOMOYO) | |
662 | +static int __init ccs_show_version(void) | |
663 | +{ | |
664 | + printk(KERN_INFO "Hook version: 2.6.28.2 2009/01/25\n"); | |
665 | + return 0; | |
666 | +} | |
667 | +module_init(ccs_show_version); | |
668 | +#endif | |
669 | +/***** CCS end. *****/ | |
670 | --- linux-2.6.28.2.orig/include/linux/init_task.h | |
671 | +++ linux-2.6.28.2/include/linux/init_task.h | |
672 | @@ -180,6 +180,10 @@ extern struct group_info init_groups; | |
673 | .vx_info = NULL, \ | |
674 | .nid = 0, \ | |
675 | .nx_info = NULL, \ | |
676 | + /***** TOMOYO Linux start. *****/ \ | |
677 | + .domain_info = &KERNEL_DOMAIN, \ | |
678 | + .tomoyo_flags = 0, \ | |
679 | + /***** TOMOYO Linux end. *****/ \ | |
680 | } | |
681 | ||
682 | ||
683 | --- linux-2.6.28.2.orig/include/linux/sched.h | |
684 | +++ linux-2.6.28.2/include/linux/sched.h | |
685 | @@ -29,6 +29,11 @@ | |
686 | #define CLONE_NEWNET 0x40000000 /* New network namespace */ | |
687 | #define CLONE_IO 0x80000000 /* Clone io context */ | |
688 | ||
689 | +/***** TOMOYO Linux start. *****/ | |
690 | +struct domain_info; | |
691 | +extern struct domain_info KERNEL_DOMAIN; | |
692 | +/***** TOMOYO Linux end. *****/ | |
693 | + | |
694 | /* | |
695 | * Scheduling policies | |
696 | */ | |
697 | @@ -1356,6 +1361,10 @@ struct task_struct { | |
698 | u8 brute; | |
699 | #endif | |
700 | ||
701 | + /***** TOMOYO Linux start. *****/ | |
702 | + struct domain_info *domain_info; | |
703 | + u32 tomoyo_flags; | |
704 | + /***** TOMOYO Linux end. *****/ | |
705 | }; | |
706 | ||
707 | /* | |
708 | --- linux-2.6.28.2.orig/kernel/compat.c | |
709 | +++ linux-2.6.28.2/kernel/compat.c | |
710 | @@ -26,6 +26,9 @@ | |
711 | #include <linux/times.h> | |
712 | ||
713 | #include <asm/uaccess.h> | |
714 | +/***** TOMOYO Linux start. *****/ | |
715 | +#include <linux/tomoyo.h> | |
716 | +/***** TOMOYO Linux end. *****/ | |
717 | ||
718 | /* | |
719 | * Note that the native side is already converted to a timespec, because | |
720 | @@ -901,6 +904,10 @@ asmlinkage long compat_sys_stime(compat_ | |
721 | err = security_settime(&tv, NULL); | |
722 | if (err) | |
723 | return err; | |
724 | + /***** TOMOYO Linux start. *****/ | |
725 | + if (!ccs_capable(TOMOYO_SYS_SETTIME)) | |
726 | + return -EPERM; | |
727 | + /***** TOMOYO Linux end. *****/ | |
728 | ||
729 | do_settimeofday(&tv); | |
730 | return 0; | |
731 | --- linux-2.6.28.2.orig/kernel/kexec.c | |
732 | +++ linux-2.6.28.2/kernel/kexec.c | |
733 | @@ -37,6 +37,9 @@ | |
734 | #include <asm/io.h> | |
735 | #include <asm/system.h> | |
736 | #include <asm/sections.h> | |
737 | +/***** TOMOYO Linux start. *****/ | |
738 | +#include <linux/tomoyo.h> | |
739 | +/***** TOMOYO Linux end. *****/ | |
740 | ||
741 | /* Per cpu memory for storing cpu states in case of system crash. */ | |
742 | note_buf_t* crash_notes; | |
743 | @@ -943,6 +946,10 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon | |
744 | /* We only trust the superuser with rebooting the system. */ | |
745 | if (!capable(CAP_SYS_BOOT)) | |
746 | return -EPERM; | |
747 | + /***** TOMOYO Linux start. *****/ | |
748 | + if (!ccs_capable(TOMOYO_SYS_KEXEC_LOAD)) | |
749 | + return -EPERM; | |
750 | + /***** TOMOYO Linux end. *****/ | |
751 | ||
752 | /* | |
753 | * Verify we have a legal set of flags | |
754 | --- linux-2.6.28.2.orig/kernel/kmod.c | |
755 | +++ linux-2.6.28.2/kernel/kmod.c | |
756 | @@ -174,6 +174,11 @@ static int ____call_usermodehelper(void | |
757 | */ | |
758 | set_user_nice(current, 0); | |
759 | ||
760 | + /***** TOMOYO Linux start. *****/ | |
761 | + current->domain_info = &KERNEL_DOMAIN; | |
762 | + current->tomoyo_flags = 0; | |
763 | + /***** TOMOYO Linux end. *****/ | |
764 | + | |
765 | retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); | |
766 | ||
767 | /* Exec failed? */ | |
768 | --- linux-2.6.28.2.orig/kernel/module.c | |
769 | +++ linux-2.6.28.2/kernel/module.c | |
770 | @@ -51,6 +51,9 @@ | |
771 | #include <asm/sections.h> | |
772 | #include <linux/tracepoint.h> | |
773 | #include <linux/ftrace.h> | |
774 | +/***** TOMOYO Linux start. *****/ | |
775 | +#include <linux/tomoyo.h> | |
776 | +/***** TOMOYO Linux end. *****/ | |
777 | ||
778 | #if 0 | |
779 | #define DEBUGP printk | |
780 | @@ -752,6 +755,10 @@ SYSCALL_DEFINE2(delete_module, const cha | |
781 | ||
782 | if (!capable(CAP_SYS_MODULE)) | |
783 | return -EPERM; | |
784 | + /***** TOMOYO Linux start. *****/ | |
785 | + if (!ccs_capable(TOMOYO_USE_KERNEL_MODULE)) | |
786 | + return -EPERM; | |
787 | + /***** TOMOYO Linux end. *****/ | |
788 | ||
789 | if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) | |
790 | return -EFAULT; | |
791 | @@ -2297,6 +2304,10 @@ SYSCALL_DEFINE3(init_module, void __user | |
792 | /* Must have permission */ | |
793 | if (!capable(CAP_SYS_MODULE)) | |
794 | return -EPERM; | |
795 | + /***** TOMOYO Linux start. *****/ | |
796 | + if (!ccs_capable(TOMOYO_USE_KERNEL_MODULE)) | |
797 | + return -EPERM; | |
798 | + /***** TOMOYO Linux end. *****/ | |
799 | ||
800 | /* Only one module load at a time, please */ | |
801 | if (mutex_lock_interruptible(&module_mutex) != 0) | |
802 | --- linux-2.6.28.2.orig/kernel/ptrace.c | |
803 | +++ linux-2.6.28.2/kernel/ptrace.c | |
804 | @@ -24,6 +24,9 @@ | |
805 | ||
806 | #include <asm/pgtable.h> | |
807 | #include <asm/uaccess.h> | |
808 | +/***** TOMOYO Linux start. *****/ | |
809 | +#include <linux/tomoyo.h> | |
810 | +/***** TOMOYO Linux end. *****/ | |
811 | ||
812 | /* | |
813 | * ptrace a task: make the debugger its new parent and | |
814 | @@ -549,6 +552,12 @@ SYSCALL_DEFINE4(ptrace, long, request, l | |
815 | { | |
816 | struct task_struct *child; | |
817 | long ret; | |
818 | + /***** TOMOYO Linux start. *****/ | |
819 | +#ifdef TOMOYO_SYS_PTRACE | |
820 | + if (!ccs_capable(TOMOYO_SYS_PTRACE)) | |
821 | + return -EPERM; | |
822 | +#endif | |
823 | + /***** TOMOYO Linux end. *****/ | |
824 | ||
825 | /* | |
826 | * This lock_kernel fixes a subtle race with suid exec | |
827 | @@ -672,6 +681,12 @@ asmlinkage long compat_sys_ptrace(compat | |
828 | { | |
829 | struct task_struct *child; | |
830 | long ret; | |
831 | + /***** TOMOYO Linux start. *****/ | |
832 | +#ifdef TOMOYO_SYS_PTRACE | |
833 | + if (!ccs_capable(TOMOYO_SYS_PTRACE)) | |
834 | + return -EPERM; | |
835 | +#endif | |
836 | + /***** TOMOYO Linux end. *****/ | |
837 | ||
838 | /* | |
839 | * This lock_kernel fixes a subtle race with suid exec | |
840 | --- linux-2.6.28.2.orig/kernel/sched.c | |
841 | +++ linux-2.6.28.2/kernel/sched.c | |
842 | @@ -76,6 +76,9 @@ | |
843 | ||
844 | #include <asm/tlb.h> | |
845 | #include <asm/irq_regs.h> | |
846 | +/***** TOMOYO Linux start. *****/ | |
847 | +#include <linux/tomoyo.h> | |
848 | +/***** TOMOYO Linux end. *****/ | |
849 | ||
850 | #include "sched_cpupri.h" | |
851 | ||
852 | @@ -5028,6 +5031,10 @@ int can_nice(const struct task_struct *p | |
853 | SYSCALL_DEFINE1(nice, int, increment) | |
854 | { | |
855 | long nice, retval; | |
856 | + /***** TOMOYO Linux start. *****/ | |
857 | + if (!ccs_capable(TOMOYO_SYS_NICE)) | |
858 | + return -EPERM; | |
859 | + /***** TOMOYO Linux end. *****/ | |
860 | ||
861 | /* | |
862 | * Setpriority might change our priority at the same moment. | |
863 | --- linux-2.6.28.2.orig/kernel/signal.c | |
864 | +++ linux-2.6.28.2/kernel/signal.c | |
865 | @@ -34,6 +34,9 @@ | |
866 | #include <asm/unistd.h> | |
867 | #include <asm/siginfo.h> | |
868 | #include "audit.h" /* audit_signal_info() */ | |
869 | +/***** TOMOYO Linux start. *****/ | |
870 | +#include <linux/tomoyo.h> | |
871 | +/***** TOMOYO Linux end. *****/ | |
872 | ||
873 | /* | |
874 | * SLAB caches for signal bits. | |
875 | @@ -2202,6 +2205,12 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const s | |
876 | SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) | |
877 | { | |
878 | struct siginfo info; | |
879 | + /***** TOMOYO Linux start. *****/ | |
880 | + if (sig && !ccs_capable(TOMOYO_SYS_KILL)) | |
881 | + return -EPERM; | |
882 | + if (sig && ccs_check_signal_acl(sig, pid)) | |
883 | + return -EPERM; | |
884 | + /***** TOMOYO Linux end. *****/ | |
885 | ||
886 | info.si_signo = sig; | |
887 | info.si_errno = 0; | |
888 | @@ -2263,6 +2272,12 @@ SYSCALL_DEFINE3(tgkill, pid_t, tgid, pid | |
889 | /* This is only valid for single tasks */ | |
890 | if (pid <= 0 || tgid <= 0) | |
891 | return -EINVAL; | |
892 | + /***** TOMOYO Linux start. *****/ | |
893 | + if (sig && !ccs_capable(TOMOYO_SYS_KILL)) | |
894 | + return -EPERM; | |
895 | + if (sig && ccs_check_signal_acl(sig, pid)) | |
896 | + return -EPERM; | |
897 | + /***** TOMOYO Linux end. *****/ | |
898 | ||
899 | return do_tkill(tgid, pid, sig); | |
900 | } | |
901 | @@ -2275,6 +2290,12 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, | |
902 | /* This is only valid for single tasks */ | |
903 | if (pid <= 0) | |
904 | return -EINVAL; | |
905 | + /***** TOMOYO Linux start. *****/ | |
906 | + if (sig && !ccs_capable(TOMOYO_SYS_KILL)) | |
907 | + return -EPERM; | |
908 | + if (sig && ccs_check_signal_acl(sig, pid)) | |
909 | + return -EPERM; | |
910 | + /***** TOMOYO Linux end. *****/ | |
911 | ||
912 | return do_tkill(0, pid, sig); | |
913 | } | |
914 | --- linux-2.6.28.2.orig/kernel/sys.c | |
915 | +++ linux-2.6.28.2/kernel/sys.c | |
916 | @@ -42,6 +42,9 @@ | |
917 | #include <asm/uaccess.h> | |
918 | #include <asm/io.h> | |
919 | #include <asm/unistd.h> | |
920 | +/***** TOMOYO Linux start. *****/ | |
921 | +#include <linux/tomoyo.h> | |
922 | +/***** TOMOYO Linux end. *****/ | |
923 | ||
924 | #ifndef SET_UNALIGN_CTL | |
925 | # define SET_UNALIGN_CTL(a,b) (-EINVAL) | |
926 | @@ -146,6 +149,12 @@ SYSCALL_DEFINE3(setpriority, int, which, | |
927 | ||
928 | if (which > PRIO_USER || which < PRIO_PROCESS) | |
929 | goto out; | |
930 | + /***** TOMOYO Linux start. *****/ | |
931 | + if (!ccs_capable(TOMOYO_SYS_NICE)) { | |
932 | + error = -EPERM; | |
933 | + goto out; | |
934 | + } | |
935 | + /***** TOMOYO Linux end. *****/ | |
936 | ||
937 | /* normalize: avoid signed division (rounding problems) */ | |
938 | error = -ESRCH; | |
939 | @@ -363,6 +372,10 @@ SYSCALL_DEFINE4(reboot, int, magic1, int | |
940 | magic2 != LINUX_REBOOT_MAGIC2B && | |
941 | magic2 != LINUX_REBOOT_MAGIC2C)) | |
942 | return -EINVAL; | |
943 | + /***** TOMOYO Linux start. *****/ | |
944 | + if (!ccs_capable(TOMOYO_SYS_REBOOT)) | |
945 | + return -EPERM; | |
946 | + /***** TOMOYO Linux end. *****/ | |
947 | ||
948 | /* Instead of trying to make the power_off code look like | |
949 | * halt when pm_power_off is not set do it the easy way. | |
950 | @@ -1337,6 +1350,10 @@ SYSCALL_DEFINE2(sethostname, char __user | |
951 | return -EPERM; | |
952 | if (len < 0 || len > __NEW_UTS_LEN) | |
953 | return -EINVAL; | |
954 | + /***** TOMOYO Linux start. *****/ | |
955 | + if (!ccs_capable(TOMOYO_SYS_SETHOSTNAME)) | |
956 | + return -EPERM; | |
957 | + /***** TOMOYO Linux end. *****/ | |
958 | down_write(&uts_sem); | |
959 | errno = -EFAULT; | |
960 | if (!copy_from_user(tmp, name, len)) { | |
961 | @@ -1386,6 +1403,10 @@ SYSCALL_DEFINE2(setdomainname, char __us | |
962 | return -EPERM; | |
963 | if (len < 0 || len > __NEW_UTS_LEN) | |
964 | return -EINVAL; | |
965 | + /***** TOMOYO Linux start. *****/ | |
966 | + if (!ccs_capable(TOMOYO_SYS_SETHOSTNAME)) | |
967 | + return -EPERM; | |
968 | + /***** TOMOYO Linux end. *****/ | |
969 | ||
970 | down_write(&uts_sem); | |
971 | errno = -EFAULT; | |
972 | --- linux-2.6.28.2.orig/kernel/sysctl.c | |
973 | +++ linux-2.6.28.2/kernel/sysctl.c | |
974 | @@ -51,6 +51,9 @@ | |
975 | ||
976 | #include <asm/uaccess.h> | |
977 | #include <asm/processor.h> | |
978 | +/***** TOMOYO Linux start. *****/ | |
979 | +#include <linux/tomoyo.h> | |
980 | +/***** TOMOYO Linux end. *****/ | |
981 | ||
982 | #ifdef CONFIG_X86 | |
983 | #include <asm/nmi.h> | |
984 | @@ -1596,6 +1599,93 @@ repeat: | |
985 | return -ENOTDIR; | |
986 | } | |
987 | ||
988 | + | |
989 | +/***** TOMOYO Linux start. *****/ | |
990 | +static int try_parse_table(int __user *name, int nlen, void __user *oldval, | |
991 | + void __user *newval, ctl_table *table) | |
992 | +{ | |
993 | + int n; | |
994 | + int error = -ENOMEM; | |
995 | + int op = 0; | |
996 | + char *buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
997 | + if (oldval) | |
998 | + op |= 004; | |
999 | + if (newval) | |
1000 | + op |= 002; | |
1001 | + if (!op) { /* Neither read nor write */ | |
1002 | + error = 0; | |
1003 | + goto out; | |
1004 | + } | |
1005 | + if (!buffer) | |
1006 | + goto out; | |
1007 | + memset(buffer, 0, PAGE_SIZE); | |
1008 | + snprintf(buffer, PAGE_SIZE - 1, "/proc/sys"); | |
1009 | + repeat: | |
1010 | + if (!nlen) { | |
1011 | + error = -ENOTDIR; | |
1012 | + goto out; | |
1013 | + } | |
1014 | + if (get_user(n, name)) { | |
1015 | + error = -EFAULT; | |
1016 | + goto out; | |
1017 | + } | |
1018 | + for ( ; table->ctl_name || table->procname; table++) { | |
1019 | + if (n == table->ctl_name && n) { | |
1020 | + int pos = strlen(buffer); | |
1021 | + const char *cp = table->procname; | |
1022 | + error = -ENOMEM; | |
1023 | + if (cp) { | |
1024 | + if (pos + 1 >= PAGE_SIZE - 1) | |
1025 | + goto out; | |
1026 | + buffer[pos++] = '/'; | |
1027 | + while (*cp) { | |
1028 | + const unsigned char c | |
1029 | + = *(const unsigned char *) cp; | |
1030 | + if (c == '\\') { | |
1031 | + if (pos + 2 >= PAGE_SIZE - 1) | |
1032 | + goto out; | |
1033 | + buffer[pos++] = '\\'; | |
1034 | + buffer[pos++] = '\\'; | |
1035 | + } else if (c > ' ' && c < 127) { | |
1036 | + if (pos + 1 >= PAGE_SIZE - 1) | |
1037 | + goto out; | |
1038 | + buffer[pos++] = c; | |
1039 | + } else { | |
1040 | + if (pos + 4 >= PAGE_SIZE - 1) | |
1041 | + goto out; | |
1042 | + buffer[pos++] = '\\'; | |
1043 | + buffer[pos++] = (c >> 6) + '0'; | |
1044 | + buffer[pos++] = ((c >> 3) & 7) | |
1045 | + + '0'; | |
1046 | + buffer[pos++] = (c & 7) + '0'; | |
1047 | + } | |
1048 | + cp++; | |
1049 | + } | |
1050 | + } else { | |
1051 | + /* Assume nobody assigns "=\$=" for procname. */ | |
1052 | + snprintf(buffer + pos, PAGE_SIZE - pos - 1, | |
1053 | + "/=%d=", n); | |
1054 | + if (!memchr(buffer, '\0', PAGE_SIZE - 2)) | |
1055 | + goto out; | |
1056 | + } | |
1057 | + if (table->child) { | |
1058 | + name++; | |
1059 | + nlen--; | |
1060 | + table = table->child; | |
1061 | + goto repeat; | |
1062 | + } | |
1063 | + /* printk("sysctl='%s'\n", buffer); */ | |
1064 | + error = ccs_check_file_perm(buffer, op, "sysctl"); | |
1065 | + goto out; | |
1066 | + } | |
1067 | + } | |
1068 | + error = -ENOTDIR; | |
1069 | + out: | |
1070 | + kfree(buffer); | |
1071 | + return error; | |
1072 | +} | |
1073 | +/***** TOMOYO Linux end. *****/ | |
1074 | + | |
1075 | int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, | |
1076 | void __user *newval, size_t newlen) | |
1077 | { | |
1078 | @@ -1612,6 +1702,11 @@ int do_sysctl(int __user *name, int nlen | |
1079 | ||
1080 | for (head = sysctl_head_next(NULL); head; | |
1081 | head = sysctl_head_next(head)) { | |
1082 | + /***** TOMOYO Linux start. *****/ | |
1083 | + error = try_parse_table(name, nlen, oldval, newval, | |
1084 | + head->ctl_table); | |
1085 | + if (!error) | |
1086 | + /***** TOMOYO Linux end. *****/ | |
1087 | error = parse_table(name, nlen, oldval, oldlenp, | |
1088 | newval, newlen, | |
1089 | head->root, head->ctl_table); | |
1090 | --- linux-2.6.28.2.orig/kernel/time.c | |
1091 | +++ linux-2.6.28.2/kernel/time.c | |
1092 | @@ -40,6 +40,9 @@ | |
1093 | ||
1094 | #include <asm/uaccess.h> | |
1095 | #include <asm/unistd.h> | |
1096 | +/***** TOMOYO Linux start. *****/ | |
1097 | +#include <linux/tomoyo.h> | |
1098 | +/***** TOMOYO Linux end. *****/ | |
1099 | ||
1100 | #include "timeconst.h" | |
1101 | ||
1102 | @@ -90,6 +93,10 @@ SYSCALL_DEFINE1(stime, time_t __user *, | |
1103 | err = security_settime(&tv, NULL); | |
1104 | if (err) | |
1105 | return err; | |
1106 | + /***** TOMOYO Linux start. *****/ | |
1107 | + if (!ccs_capable(TOMOYO_SYS_SETTIME)) | |
1108 | + return -EPERM; | |
1109 | + /***** TOMOYO Linux end. *****/ | |
1110 | ||
1111 | do_settimeofday(&tv); | |
1112 | return 0; | |
1113 | @@ -161,6 +168,10 @@ int do_sys_settimeofday(struct timespec | |
1114 | error = security_settime(tv, tz); | |
1115 | if (error) | |
1116 | return error; | |
1117 | + /***** TOMOYO Linux start. *****/ | |
1118 | + if (!ccs_capable(TOMOYO_SYS_SETTIME)) | |
1119 | + return -EPERM; | |
1120 | + /***** TOMOYO Linux end. *****/ | |
1121 | ||
1122 | if (tz) { | |
1123 | /* SMP safe, global irq locking makes it work. */ | |
1124 | --- linux-2.6.28.2.orig/kernel/time/ntp.c | |
1125 | +++ linux-2.6.28.2/kernel/time/ntp.c | |
1126 | @@ -18,6 +18,9 @@ | |
1127 | #include <linux/clocksource.h> | |
1128 | #include <linux/workqueue.h> | |
1129 | #include <asm/timex.h> | |
1130 | +/***** TOMOYO Linux start. *****/ | |
1131 | +#include <linux/tomoyo.h> | |
1132 | +/***** TOMOYO Linux end. *****/ | |
1133 | ||
1134 | /* | |
1135 | * Timekeeping variables | |
1136 | @@ -286,10 +289,18 @@ int do_adjtimex(struct timex *txc) | |
1137 | if (!(txc->modes & ADJ_OFFSET_READONLY) && | |
1138 | !capable(CAP_SYS_TIME)) | |
1139 | return -EPERM; | |
1140 | + /***** TOMOYO Linux start. *****/ | |
1141 | + if (txc->modes && !ccs_capable(TOMOYO_SYS_SETTIME)) | |
1142 | + return -EPERM; | |
1143 | + /***** TOMOYO Linux end. *****/ | |
1144 | } else { | |
1145 | /* In order to modify anything, you gotta be super-user! */ | |
1146 | if (txc->modes && !capable(CAP_SYS_TIME)) | |
1147 | return -EPERM; | |
1148 | + /***** TOMOYO Linux start. *****/ | |
1149 | + if (txc->modes && !ccs_capable(TOMOYO_SYS_SETTIME)) | |
1150 | + return -EPERM; | |
1151 | + /***** TOMOYO Linux end. *****/ | |
1152 | ||
1153 | /* if the quartz is off by more than 10% something is VERY wrong! */ | |
1154 | if (txc->modes & ADJ_TICK && | |
1155 | --- linux-2.6.28.2.orig/net/core/datagram.c | |
1156 | +++ linux-2.6.28.2/net/core/datagram.c | |
1157 | @@ -56,6 +56,11 @@ | |
1158 | #include <net/sock.h> | |
1159 | #include <net/tcp_states.h> | |
1160 | ||
1161 | +/***** TOMOYO Linux start. *****/ | |
1162 | +#include <linux/tomoyo.h> | |
1163 | +#include <linux/tomoyo_socket.h> | |
1164 | +/***** TOMOYO Linux end. *****/ | |
1165 | + | |
1166 | /* | |
1167 | * Is a socket 'connection oriented' ? | |
1168 | */ | |
1169 | @@ -179,6 +184,12 @@ struct sk_buff *__skb_recv_datagram(stru | |
1170 | } | |
1171 | spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags); | |
1172 | ||
1173 | + /***** TOMOYO Linux start. *****/ | |
1174 | + error = ccs_socket_recv_datagram_permission(sk, skb, flags); | |
1175 | + if (error) | |
1176 | + goto no_packet; | |
1177 | + /***** TOMOYO Linux end. *****/ | |
1178 | + | |
1179 | if (skb) | |
1180 | return skb; | |
1181 | ||
1182 | --- linux-2.6.28.2.orig/net/ipv4/inet_connection_sock.c | |
1183 | +++ linux-2.6.28.2/net/ipv4/inet_connection_sock.c | |
1184 | @@ -23,6 +23,9 @@ | |
1185 | #include <net/route.h> | |
1186 | #include <net/tcp_states.h> | |
1187 | #include <net/xfrm.h> | |
1188 | +/***** SAKURA Linux start. *****/ | |
1189 | +#include <linux/sakura.h> | |
1190 | +/***** SAKURA Linux end. *****/ | |
1191 | ||
1192 | #ifdef INET_CSK_DEBUG | |
1193 | const char inet_csk_timer_bug_msg[] = "inet_csk BUG: unknown timer value\n"; | |
1194 | @@ -108,6 +111,10 @@ int inet_csk_get_port(struct sock *sk, u | |
1195 | head = &hashinfo->bhash[inet_bhashfn(net, rover, | |
1196 | hashinfo->bhash_size)]; | |
1197 | spin_lock(&head->lock); | |
1198 | + /***** SAKURA Linux start. *****/ | |
1199 | + if (ccs_may_autobind(rover)) | |
1200 | + goto next; | |
1201 | + /***** SAKURA Linux end. *****/ | |
1202 | inet_bind_bucket_for_each(tb, node, &head->chain) | |
1203 | if (tb->ib_net == net && tb->port == rover) | |
1204 | goto next; | |
1205 | --- linux-2.6.28.2.orig/net/ipv4/inet_hashtables.c | |
1206 | +++ linux-2.6.28.2/net/ipv4/inet_hashtables.c | |
1207 | @@ -22,6 +22,9 @@ | |
1208 | #include <net/inet_connection_sock.h> | |
1209 | #include <net/inet_hashtables.h> | |
1210 | #include <net/ip.h> | |
1211 | +/***** SAKURA Linux start. *****/ | |
1212 | +#include <linux/sakura.h> | |
1213 | +/***** SAKURA Linux end. *****/ | |
1214 | ||
1215 | /* | |
1216 | * Allocate and initialize a new local port bind bucket. | |
1217 | @@ -440,6 +443,10 @@ int __inet_hash_connect(struct inet_time | |
1218 | local_bh_disable(); | |
1219 | for (i = 1; i <= remaining; i++) { | |
1220 | port = low + (i + offset) % remaining; | |
1221 | + /***** SAKURA Linux start. *****/ | |
1222 | + if (ccs_may_autobind(port)) | |
1223 | + continue; | |
1224 | + /***** SAKURA Linux end. *****/ | |
1225 | head = &hinfo->bhash[inet_bhashfn(net, port, | |
1226 | hinfo->bhash_size)]; | |
1227 | spin_lock(&head->lock); | |
1228 | --- linux-2.6.28.2.orig/net/ipv4/udp.c | |
1229 | +++ linux-2.6.28.2/net/ipv4/udp.c | |
1230 | @@ -103,6 +103,9 @@ | |
1231 | #include <net/checksum.h> | |
1232 | #include <net/xfrm.h> | |
1233 | #include "udp_impl.h" | |
1234 | +/***** SAKURA Linux start. *****/ | |
1235 | +#include <linux/sakura.h> | |
1236 | +/***** SAKURA Linux end. *****/ | |
1237 | ||
1238 | /* | |
1239 | * Snmp MIB for the UDP layer | |
1240 | @@ -172,7 +175,11 @@ int udp_lib_get_port(struct sock *sk, un | |
1241 | snum = first = rand % remaining + low; | |
1242 | rand |= 1; | |
1243 | while (udp_lib_lport_inuse(net, snum, udptable, sk, | |
1244 | - saddr_comp)) { | |
1245 | + saddr_comp) | |
1246 | + /***** SAKURA Linux start. *****/ | |
1247 | + || ccs_may_autobind(snum) | |
1248 | + /***** SAKURA Linux end. *****/ | |
1249 | + ) { | |
1250 | do { | |
1251 | snum = snum + rand; | |
1252 | } while (snum < low || snum > high); | |
1253 | --- linux-2.6.28.2.orig/net/socket.c | |
1254 | +++ linux-2.6.28.2/net/socket.c | |
1255 | @@ -97,6 +97,11 @@ | |
1256 | #include <net/sock.h> | |
1257 | #include <linux/netfilter.h> | |
1258 | ||
1259 | +/***** TOMOYO Linux start. *****/ | |
1260 | +#include <linux/tomoyo.h> | |
1261 | +#include <linux/tomoyo_socket.h> | |
1262 | +/***** TOMOYO Linux end. *****/ | |
1263 | + | |
1264 | static int sock_no_open(struct inode *irrelevant, struct file *dontcare); | |
1265 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, | |
1266 | unsigned long nr_segs, loff_t pos); | |
1267 | @@ -560,6 +565,12 @@ static inline int __sock_sendmsg(struct | |
1268 | err = security_socket_sendmsg(sock, msg, size); | |
1269 | if (err) | |
1270 | return err; | |
1271 | + /***** TOMOYO Linux start. *****/ | |
1272 | + if (ccs_socket_sendmsg_permission(sock, | |
1273 | + (struct sockaddr *) msg->msg_name, | |
1274 | + msg->msg_namelen)) | |
1275 | + return -EPERM; | |
1276 | + /***** TOMOYO Linux end. *****/ | |
1277 | ||
1278 | return sock->ops->sendmsg(iocb, sock, msg, size); | |
1279 | } | |
1280 | @@ -1122,6 +1133,12 @@ static int __sock_create(struct net *net | |
1281 | family = PF_PACKET; | |
1282 | } | |
1283 | ||
1284 | + /***** TOMOYO Linux start. *****/ | |
1285 | + err = ccs_socket_create_permission(family, type, protocol); | |
1286 | + if (err) | |
1287 | + return err; | |
1288 | + /***** TOMOYO Linux end. *****/ | |
1289 | + | |
1290 | err = security_socket_create(family, type, protocol, kern); | |
1291 | if (err) | |
1292 | return err; | |
1293 | @@ -1377,6 +1394,13 @@ SYSCALL_DEFINE3(bind, int, fd, struct so | |
1294 | err = security_socket_bind(sock, | |
1295 | (struct sockaddr *)&address, | |
1296 | addrlen); | |
1297 | + /***** TOMOYO Linux start. *****/ | |
1298 | + if (!err) | |
1299 | + err = ccs_socket_bind_permission(sock, | |
1300 | + (struct sockaddr *) | |
1301 | + &address, | |
1302 | + addrlen); | |
1303 | + /***** TOMOYO Linux end. *****/ | |
1304 | if (!err) | |
1305 | err = sock->ops->bind(sock, | |
1306 | (struct sockaddr *) | |
1307 | @@ -1406,6 +1430,10 @@ SYSCALL_DEFINE2(listen, int, fd, int, ba | |
1308 | backlog = somaxconn; | |
1309 | ||
1310 | err = security_socket_listen(sock, backlog); | |
1311 | + /***** TOMOYO Linux start. *****/ | |
1312 | + if (!err) | |
1313 | + err = ccs_socket_listen_permission(sock); | |
1314 | + /***** TOMOYO Linux end. *****/ | |
1315 | if (!err) | |
1316 | err = sock->ops->listen(sock, backlog); | |
1317 | ||
1318 | @@ -1476,6 +1504,13 @@ SYSCALL_DEFINE4(accept4, int, fd, struct | |
1319 | if (err < 0) | |
1320 | goto out_fd; | |
1321 | ||
1322 | + /***** TOMOYO Linux start. *****/ | |
1323 | + if (ccs_socket_accept_permission(newsock, | |
1324 | + (struct sockaddr *) &address)) { | |
1325 | + err = -ECONNABORTED; /* Hope less harmful than -EPERM. */ | |
1326 | + goto out_fd; | |
1327 | + } | |
1328 | + /***** TOMOYO Linux end. *****/ | |
1329 | if (upeer_sockaddr) { | |
1330 | if (newsock->ops->getname(newsock, (struct sockaddr *)&address, | |
1331 | &len, 2) < 0) { | |
1332 | @@ -1541,6 +1576,12 @@ SYSCALL_DEFINE3(connect, int, fd, struct | |
1333 | err = move_addr_to_kernel(uservaddr, addrlen, (struct sockaddr *)&address); | |
1334 | if (err < 0) | |
1335 | goto out_put; | |
1336 | + /***** TOMOYO Linux start. *****/ | |
1337 | + err = ccs_socket_connect_permission(sock, (struct sockaddr *) &address, | |
1338 | + addrlen); | |
1339 | + if (err) | |
1340 | + goto out_put; | |
1341 | + /***** TOMOYO Linux end. *****/ | |
1342 | ||
1343 | err = | |
1344 | security_socket_connect(sock, (struct sockaddr *)&address, addrlen); | |
1345 | --- linux-2.6.28.2.orig/net/unix/af_unix.c | |
1346 | +++ linux-2.6.28.2/net/unix/af_unix.c | |
1347 | @@ -114,6 +114,9 @@ | |
1348 | #include <linux/vs_context.h> | |
1349 | #include <linux/vs_limit.h> | |
1350 | #include <linux/grsecurity.h> | |
1351 | +/***** TOMOYO Linux start. *****/ | |
1352 | +#include <linux/tomoyo.h> | |
1353 | +/***** TOMOYO Linux end. *****/ | |
1354 | ||
1355 | static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; | |
1356 | static DEFINE_SPINLOCK(unix_table_lock); | |
1357 | @@ -783,6 +786,11 @@ static int unix_bind(struct socket *sock | |
1358 | err = unix_autobind(sock); | |
1359 | goto out; | |
1360 | } | |
1361 | + /***** TOMOYO Linux start. *****/ | |
1362 | + err = -EPERM; | |
1363 | + if (sunaddr->sun_path[0] && !ccs_capable(TOMOYO_CREATE_UNIX_SOCKET)) | |
1364 | + goto out; | |
1365 | + /***** TOMOYO Linux end. *****/ | |
1366 | ||
1367 | err = unix_mkname(sunaddr, addr_len, &hash); | |
1368 | if (err < 0) | |
1369 | @@ -829,6 +837,13 @@ static int unix_bind(struct socket *sock | |
1370 | goto out_mknod_dput; | |
1371 | } | |
1372 | ||
1373 | + /***** TOMOYO Linux start. *****/ | |
1374 | + err = pre_vfs_mknod(nd.path.dentry->d_inode, dentry, mode); | |
1375 | + if (!err) | |
1376 | + err = ccs_check_1path_perm(TYPE_MKSOCK_ACL, dentry, | |
1377 | + nd.path.mnt); | |
1378 | + if (!err) | |
1379 | + /***** TOMOYO Linux end. *****/ | |
2380c486 JR |
1380 | err = vfs_mknod(nd.path.dentry->d_inode, dentry, nd.path.mnt, |
1381 | mode, 0); | |
f87181f3 | 1382 | mnt_drop_write(nd.path.mnt); |