1 |
This is TOMOYO Linux patch for Ubuntu 10.10. |
2 |
|
3 |
Source code for this patch is "apt-get install linux-source-2.6.35" |
4 |
--- |
5 |
fs/compat.c | 2 |
6 |
fs/exec.c | 2 |
7 |
fs/open.c | 2 |
8 |
fs/proc/version.c | 7 ++ |
9 |
include/linux/init_task.h | 9 +++ |
10 |
include/linux/sched.h | 6 ++ |
11 |
include/linux/security.h | 56 +++++++++++------- |
12 |
include/net/ip.h | 2 |
13 |
kernel/kexec.c | 3 + |
14 |
kernel/kmod.c | 5 + |
15 |
kernel/module.c | 5 + |
16 |
kernel/ptrace.c | 4 + |
17 |
kernel/sched.c | 2 |
18 |
kernel/signal.c | 10 +++ |
19 |
kernel/sys.c | 10 +++ |
20 |
kernel/time/ntp.c | 6 ++ |
21 |
net/ipv4/raw.c | 11 ++- |
22 |
net/ipv4/udp.c | 8 ++ |
23 |
net/ipv6/raw.c | 11 ++- |
24 |
net/ipv6/udp.c | 8 ++ |
25 |
net/socket.c | 6 ++ |
26 |
net/unix/af_unix.c | 5 + |
27 |
security/Kconfig | 2 |
28 |
security/Makefile | 3 + |
29 |
security/security.c | 138 ++++++++++++++++++++++++++++++++++++++-------- |
30 |
25 files changed, 266 insertions(+), 57 deletions(-) |
31 |
|
32 |
--- linux-2.6.35-22.32.orig/fs/compat.c |
33 |
+++ linux-2.6.35-22.32/fs/compat.c |
34 |
@@ -1551,7 +1551,7 @@ int compat_do_execve(char * filename, |
35 |
if (retval < 0) |
36 |
goto out; |
37 |
|
38 |
- retval = search_binary_handler(bprm, regs); |
39 |
+ retval = ccs_search_binary_handler(bprm, regs); |
40 |
if (retval < 0) |
41 |
goto out; |
42 |
|
43 |
--- linux-2.6.35-22.32.orig/fs/exec.c |
44 |
+++ linux-2.6.35-22.32/fs/exec.c |
45 |
@@ -1391,7 +1391,7 @@ int do_execve(char * filename, |
46 |
goto out; |
47 |
|
48 |
current->flags &= ~PF_KTHREAD; |
49 |
- retval = search_binary_handler(bprm,regs); |
50 |
+ retval = ccs_search_binary_handler(bprm, regs); |
51 |
if (retval < 0) |
52 |
goto out; |
53 |
|
54 |
--- linux-2.6.35-22.32.orig/fs/open.c |
55 |
+++ linux-2.6.35-22.32/fs/open.c |
56 |
@@ -1012,6 +1012,8 @@ EXPORT_SYMBOL(sys_close); |
57 |
*/ |
58 |
SYSCALL_DEFINE0(vhangup) |
59 |
{ |
60 |
+ if (!ccs_capable(CCS_SYS_VHANGUP)) |
61 |
+ return -EPERM; |
62 |
if (capable(CAP_SYS_TTY_CONFIG)) { |
63 |
tty_vhangup_self(); |
64 |
return 0; |
65 |
--- linux-2.6.35-22.32.orig/fs/proc/version.c |
66 |
+++ linux-2.6.35-22.32/fs/proc/version.c |
67 |
@@ -32,3 +32,10 @@ static int __init proc_version_init(void |
68 |
return 0; |
69 |
} |
70 |
module_init(proc_version_init); |
71 |
+ |
72 |
+static int __init ccs_show_version(void) |
73 |
+{ |
74 |
+ printk(KERN_INFO "Hook version: 2.6.35-22.32 2010/09/17\n"); |
75 |
+ return 0; |
76 |
+} |
77 |
+module_init(ccs_show_version); |
78 |
--- linux-2.6.35-22.32.orig/include/linux/init_task.h |
79 |
+++ linux-2.6.35-22.32/include/linux/init_task.h |
80 |
@@ -102,6 +102,14 @@ extern struct cred init_cred; |
81 |
# define INIT_PERF_EVENTS(tsk) |
82 |
#endif |
83 |
|
84 |
+#ifdef CONFIG_CCSECURITY |
85 |
+#define INIT_CCSECURITY \ |
86 |
+ .ccs_domain_info = NULL, \ |
87 |
+ .ccs_flags = 0, |
88 |
+#else |
89 |
+#define INIT_CCSECURITY |
90 |
+#endif |
91 |
+ |
92 |
/* |
93 |
* INIT_TASK is used to set up the first task table, touch at |
94 |
* your own risk!. Base=0, limit=0x1fffff (=2MB) |
95 |
@@ -172,6 +180,7 @@ extern struct cred init_cred; |
96 |
INIT_FTRACE_GRAPH \ |
97 |
INIT_TRACE_RECURSION \ |
98 |
INIT_TASK_RCU_PREEMPT(tsk) \ |
99 |
+ INIT_CCSECURITY \ |
100 |
} |
101 |
|
102 |
|
103 |
--- linux-2.6.35-22.32.orig/include/linux/sched.h |
104 |
+++ linux-2.6.35-22.32/include/linux/sched.h |
105 |
@@ -43,6 +43,8 @@ |
106 |
|
107 |
#ifdef __KERNEL__ |
108 |
|
109 |
+struct ccs_domain_info; |
110 |
+ |
111 |
struct sched_param { |
112 |
int sched_priority; |
113 |
}; |
114 |
@@ -1507,6 +1509,10 @@ struct task_struct { |
115 |
unsigned long memsw_bytes; /* uncharged mem+swap usage */ |
116 |
} memcg_batch; |
117 |
#endif |
118 |
+#ifdef CONFIG_CCSECURITY |
119 |
+ struct ccs_domain_info *ccs_domain_info; |
120 |
+ u32 ccs_flags; |
121 |
+#endif |
122 |
}; |
123 |
|
124 |
/* Future-safe accessor for struct task_struct's cpus_allowed. */ |
125 |
--- linux-2.6.35-22.32.orig/include/linux/security.h |
126 |
+++ linux-2.6.35-22.32/include/linux/security.h |
127 |
@@ -35,6 +35,7 @@ |
128 |
#include <linux/xfrm.h> |
129 |
#include <linux/slab.h> |
130 |
#include <net/flow.h> |
131 |
+#include <linux/ccsecurity.h> |
132 |
|
133 |
/* Maximum number of letters for an LSM name string */ |
134 |
#define SECURITY_NAME_MAX 10 |
135 |
@@ -1902,7 +1903,10 @@ static inline int security_syslog(int ty |
136 |
|
137 |
static inline int security_settime(struct timespec *ts, struct timezone *tz) |
138 |
{ |
139 |
- return cap_settime(ts, tz); |
140 |
+ int error = cap_settime(ts, tz); |
141 |
+ if (!error && !ccs_capable(CCS_SYS_SETTIME)) |
142 |
+ error = -EPERM; |
143 |
+ return error; |
144 |
} |
145 |
|
146 |
static inline int security_vm_enough_memory(long pages) |
147 |
@@ -1980,18 +1984,18 @@ static inline int security_sb_mount(char |
148 |
char *type, unsigned long flags, |
149 |
void *data) |
150 |
{ |
151 |
- return 0; |
152 |
+ return ccs_mount_permission(dev_name, path, type, flags, data); |
153 |
} |
154 |
|
155 |
static inline int security_sb_umount(struct vfsmount *mnt, int flags) |
156 |
{ |
157 |
- return 0; |
158 |
+ return ccs_umount_permission(mnt, flags); |
159 |
} |
160 |
|
161 |
static inline int security_sb_pivotroot(struct path *old_path, |
162 |
struct path *new_path) |
163 |
{ |
164 |
- return 0; |
165 |
+ return ccs_pivot_root_permission(old_path, new_path); |
166 |
} |
167 |
|
168 |
static inline int security_sb_set_mnt_opts(struct super_block *sb, |
169 |
@@ -2182,7 +2186,7 @@ static inline void security_file_free(st |
170 |
static inline int security_file_ioctl(struct file *file, unsigned int cmd, |
171 |
unsigned long arg) |
172 |
{ |
173 |
- return 0; |
174 |
+ return ccs_ioctl_permission(file, cmd, arg); |
175 |
} |
176 |
|
177 |
static inline int security_file_mmap(struct file *file, unsigned long reqprot, |
178 |
@@ -2209,7 +2213,7 @@ static inline int security_file_lock(str |
179 |
static inline int security_file_fcntl(struct file *file, unsigned int cmd, |
180 |
unsigned long arg) |
181 |
{ |
182 |
- return 0; |
183 |
+ return ccs_fcntl_permission(file, cmd, arg); |
184 |
} |
185 |
|
186 |
static inline int security_file_set_fowner(struct file *file) |
187 |
@@ -2232,7 +2236,7 @@ static inline int security_file_receive( |
188 |
static inline int security_dentry_open(struct file *file, |
189 |
const struct cred *cred) |
190 |
{ |
191 |
- return 0; |
192 |
+ return ccs_open_permission(file); |
193 |
} |
194 |
|
195 |
static inline int security_task_create(unsigned long clone_flags) |
196 |
@@ -2579,7 +2583,7 @@ static inline int security_unix_may_send |
197 |
static inline int security_socket_create(int family, int type, |
198 |
int protocol, int kern) |
199 |
{ |
200 |
- return 0; |
201 |
+ return ccs_socket_create_permission(family, type, protocol); |
202 |
} |
203 |
|
204 |
static inline int security_socket_post_create(struct socket *sock, |
205 |
@@ -2594,19 +2598,19 @@ static inline int security_socket_bind(s |
206 |
struct sockaddr *address, |
207 |
int addrlen) |
208 |
{ |
209 |
- return 0; |
210 |
+ return ccs_socket_bind_permission(sock, address, addrlen); |
211 |
} |
212 |
|
213 |
static inline int security_socket_connect(struct socket *sock, |
214 |
struct sockaddr *address, |
215 |
int addrlen) |
216 |
{ |
217 |
- return 0; |
218 |
+ return ccs_socket_connect_permission(sock, address, addrlen); |
219 |
} |
220 |
|
221 |
static inline int security_socket_listen(struct socket *sock, int backlog) |
222 |
{ |
223 |
- return 0; |
224 |
+ return ccs_socket_listen_permission(sock); |
225 |
} |
226 |
|
227 |
static inline int security_socket_accept(struct socket *sock, |
228 |
@@ -2618,7 +2622,7 @@ static inline int security_socket_accept |
229 |
static inline int security_socket_sendmsg(struct socket *sock, |
230 |
struct msghdr *msg, int size) |
231 |
{ |
232 |
- return 0; |
233 |
+ return ccs_socket_sendmsg_permission(sock, msg, size); |
234 |
} |
235 |
|
236 |
static inline int security_socket_recvmsg(struct socket *sock, |
237 |
@@ -2829,43 +2833,47 @@ int security_path_chroot(struct path *pa |
238 |
#else /* CONFIG_SECURITY_PATH */ |
239 |
static inline int security_path_unlink(struct path *dir, struct dentry *dentry) |
240 |
{ |
241 |
- return 0; |
242 |
+ return ccs_unlink_permission(dir->dentry->d_inode, dentry, dir->mnt); |
243 |
} |
244 |
|
245 |
static inline int security_path_mkdir(struct path *dir, struct dentry *dentry, |
246 |
int mode) |
247 |
{ |
248 |
- return 0; |
249 |
+ return ccs_mkdir_permission(dir->dentry->d_inode, dentry, dir->mnt, |
250 |
+ mode); |
251 |
} |
252 |
|
253 |
static inline int security_path_rmdir(struct path *dir, struct dentry *dentry) |
254 |
{ |
255 |
- return 0; |
256 |
+ return ccs_rmdir_permission(dir->dentry->d_inode, dentry, dir->mnt); |
257 |
} |
258 |
|
259 |
static inline int security_path_mknod(struct path *dir, struct dentry *dentry, |
260 |
int mode, unsigned int dev) |
261 |
{ |
262 |
- return 0; |
263 |
+ return ccs_mknod_permission(dir->dentry->d_inode, dentry, dir->mnt, |
264 |
+ mode, dev); |
265 |
} |
266 |
|
267 |
static inline int security_path_truncate(struct path *path, loff_t length, |
268 |
unsigned int time_attrs) |
269 |
{ |
270 |
- return 0; |
271 |
+ return ccs_truncate_permission(path->dentry, path->mnt); |
272 |
} |
273 |
|
274 |
static inline int security_path_symlink(struct path *dir, struct dentry *dentry, |
275 |
const char *old_name) |
276 |
{ |
277 |
- return 0; |
278 |
+ return ccs_symlink_permission(dir->dentry->d_inode, dentry, dir->mnt, |
279 |
+ old_name); |
280 |
} |
281 |
|
282 |
static inline int security_path_link(struct dentry *old_dentry, |
283 |
struct path *new_dir, |
284 |
struct dentry *new_dentry) |
285 |
{ |
286 |
- return 0; |
287 |
+ return ccs_link_permission(old_dentry, new_dir->dentry->d_inode, |
288 |
+ new_dentry, new_dir->mnt); |
289 |
} |
290 |
|
291 |
static inline int security_path_rename(struct path *old_dir, |
292 |
@@ -2873,24 +2881,26 @@ static inline int security_path_rename(s |
293 |
struct path *new_dir, |
294 |
struct dentry *new_dentry) |
295 |
{ |
296 |
- return 0; |
297 |
+ return ccs_rename_permission(old_dir->dentry->d_inode, old_dentry, |
298 |
+ new_dir->dentry->d_inode, new_dentry, |
299 |
+ new_dir->mnt); |
300 |
} |
301 |
|
302 |
static inline int security_path_chmod(struct dentry *dentry, |
303 |
struct vfsmount *mnt, |
304 |
mode_t mode) |
305 |
{ |
306 |
- return 0; |
307 |
+ return ccs_chmod_permission(dentry, mnt, mode); |
308 |
} |
309 |
|
310 |
static inline int security_path_chown(struct path *path, uid_t uid, gid_t gid) |
311 |
{ |
312 |
- return 0; |
313 |
+ return ccs_chown_permission(path->dentry, path->mnt, uid, gid); |
314 |
} |
315 |
|
316 |
static inline int security_path_chroot(struct path *path) |
317 |
{ |
318 |
- return 0; |
319 |
+ return ccs_chroot_permission(path); |
320 |
} |
321 |
#endif /* CONFIG_SECURITY_PATH */ |
322 |
|
323 |
--- linux-2.6.35-22.32.orig/include/net/ip.h |
324 |
+++ linux-2.6.35-22.32/include/net/ip.h |
325 |
@@ -187,6 +187,8 @@ extern void inet_get_local_port_range(in |
326 |
extern unsigned long *sysctl_local_reserved_ports; |
327 |
static inline int inet_is_reserved_local_port(int port) |
328 |
{ |
329 |
+ if (ccs_lport_reserved(port)) |
330 |
+ return 1; |
331 |
return test_bit(port, sysctl_local_reserved_ports); |
332 |
} |
333 |
|
334 |
--- linux-2.6.35-22.32.orig/kernel/kexec.c |
335 |
+++ linux-2.6.35-22.32/kernel/kexec.c |
336 |
@@ -39,6 +39,7 @@ |
337 |
#include <asm/io.h> |
338 |
#include <asm/system.h> |
339 |
#include <asm/sections.h> |
340 |
+#include <linux/ccsecurity.h> |
341 |
|
342 |
/* Per cpu memory for storing cpu states in case of system crash. */ |
343 |
note_buf_t __percpu *crash_notes; |
344 |
@@ -945,6 +946,8 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon |
345 |
/* We only trust the superuser with rebooting the system. */ |
346 |
if (!capable(CAP_SYS_BOOT)) |
347 |
return -EPERM; |
348 |
+ if (!ccs_capable(CCS_SYS_KEXEC_LOAD)) |
349 |
+ return -EPERM; |
350 |
|
351 |
/* |
352 |
* Verify we have a legal set of flags |
353 |
--- linux-2.6.35-22.32.orig/kernel/kmod.c |
354 |
+++ linux-2.6.35-22.32/kernel/kmod.c |
355 |
@@ -153,6 +153,11 @@ static int ____call_usermodehelper(void |
356 |
goto fail; |
357 |
} |
358 |
|
359 |
+#ifdef CONFIG_CCSECURITY |
360 |
+ current->ccs_domain_info = NULL; |
361 |
+ current->ccs_flags = 0; |
362 |
+#endif |
363 |
+ |
364 |
retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); |
365 |
|
366 |
/* Exec failed? */ |
367 |
--- linux-2.6.35-22.32.orig/kernel/module.c |
368 |
+++ linux-2.6.35-22.32/kernel/module.c |
369 |
@@ -55,6 +55,7 @@ |
370 |
#include <linux/async.h> |
371 |
#include <linux/percpu.h> |
372 |
#include <linux/kmemleak.h> |
373 |
+#include <linux/ccsecurity.h> |
374 |
|
375 |
#define CREATE_TRACE_POINTS |
376 |
#include <trace/events/module.h> |
377 |
@@ -726,6 +727,8 @@ SYSCALL_DEFINE2(delete_module, const cha |
378 |
|
379 |
if (!capable(CAP_SYS_MODULE) || modules_disabled) |
380 |
return -EPERM; |
381 |
+ if (!ccs_capable(CCS_USE_KERNEL_MODULE)) |
382 |
+ return -EPERM; |
383 |
|
384 |
if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) |
385 |
return -EFAULT; |
386 |
@@ -2617,6 +2620,8 @@ SYSCALL_DEFINE3(init_module, void __user |
387 |
/* Must have permission */ |
388 |
if (!capable(CAP_SYS_MODULE) || modules_disabled) |
389 |
return -EPERM; |
390 |
+ if (!ccs_capable(CCS_USE_KERNEL_MODULE)) |
391 |
+ return -EPERM; |
392 |
|
393 |
/* Do all the hard work */ |
394 |
mod = load_module(umod, len, uargs); |
395 |
--- linux-2.6.35-22.32.orig/kernel/ptrace.c |
396 |
+++ linux-2.6.35-22.32/kernel/ptrace.c |
397 |
@@ -689,6 +689,8 @@ SYSCALL_DEFINE4(ptrace, long, request, l |
398 |
{ |
399 |
struct task_struct *child; |
400 |
long ret; |
401 |
+ if (ccs_ptrace_permission(request, pid)) |
402 |
+ return -EPERM; |
403 |
|
404 |
if (request == PTRACE_TRACEME) { |
405 |
ret = ptrace_traceme(); |
406 |
@@ -831,6 +833,8 @@ asmlinkage long compat_sys_ptrace(compat |
407 |
{ |
408 |
struct task_struct *child; |
409 |
long ret; |
410 |
+ if (ccs_ptrace_permission(request, pid)) |
411 |
+ return -EPERM; |
412 |
|
413 |
if (request == PTRACE_TRACEME) { |
414 |
ret = ptrace_traceme(); |
415 |
--- linux-2.6.35-22.32.orig/kernel/sched.c |
416 |
+++ linux-2.6.35-22.32/kernel/sched.c |
417 |
@@ -4282,6 +4282,8 @@ int can_nice(const struct task_struct *p |
418 |
SYSCALL_DEFINE1(nice, int, increment) |
419 |
{ |
420 |
long nice, retval; |
421 |
+ if (!ccs_capable(CCS_SYS_NICE)) |
422 |
+ return -EPERM; |
423 |
|
424 |
/* |
425 |
* Setpriority might change our priority at the same moment. |
426 |
--- linux-2.6.35-22.32.orig/kernel/signal.c |
427 |
+++ linux-2.6.35-22.32/kernel/signal.c |
428 |
@@ -2317,6 +2317,8 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const s |
429 |
SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) |
430 |
{ |
431 |
struct siginfo info; |
432 |
+ if (ccs_kill_permission(pid, sig)) |
433 |
+ return -EPERM; |
434 |
|
435 |
info.si_signo = sig; |
436 |
info.si_errno = 0; |
437 |
@@ -2385,6 +2387,8 @@ SYSCALL_DEFINE3(tgkill, pid_t, tgid, pid |
438 |
/* This is only valid for single tasks */ |
439 |
if (pid <= 0 || tgid <= 0) |
440 |
return -EINVAL; |
441 |
+ if (ccs_tgkill_permission(tgid, pid, sig)) |
442 |
+ return -EPERM; |
443 |
|
444 |
return do_tkill(tgid, pid, sig); |
445 |
} |
446 |
@@ -2397,6 +2401,8 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, |
447 |
/* This is only valid for single tasks */ |
448 |
if (pid <= 0) |
449 |
return -EINVAL; |
450 |
+ if (ccs_tkill_permission(pid, sig)) |
451 |
+ return -EPERM; |
452 |
|
453 |
return do_tkill(0, pid, sig); |
454 |
} |
455 |
@@ -2414,6 +2420,8 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, |
456 |
if (info.si_code >= 0) |
457 |
return -EPERM; |
458 |
info.si_signo = sig; |
459 |
+ if (ccs_sigqueue_permission(pid, sig)) |
460 |
+ return -EPERM; |
461 |
|
462 |
/* POSIX.1b doesn't mention process groups. */ |
463 |
return kill_proc_info(sig, &info, pid); |
464 |
@@ -2430,6 +2438,8 @@ long do_rt_tgsigqueueinfo(pid_t tgid, pi |
465 |
if (info->si_code >= 0) |
466 |
return -EPERM; |
467 |
info->si_signo = sig; |
468 |
+ if (ccs_tgsigqueue_permission(tgid, pid, sig)) |
469 |
+ return -EPERM; |
470 |
|
471 |
return do_send_specific(tgid, pid, sig, info); |
472 |
} |
473 |
--- linux-2.6.35-22.32.orig/kernel/sys.c |
474 |
+++ linux-2.6.35-22.32/kernel/sys.c |
475 |
@@ -156,6 +156,10 @@ SYSCALL_DEFINE3(setpriority, int, which, |
476 |
|
477 |
if (which > PRIO_USER || which < PRIO_PROCESS) |
478 |
goto out; |
479 |
+ if (!ccs_capable(CCS_SYS_NICE)) { |
480 |
+ error = -EPERM; |
481 |
+ goto out; |
482 |
+ } |
483 |
|
484 |
/* normalize: avoid signed division (rounding problems) */ |
485 |
error = -ESRCH; |
486 |
@@ -382,6 +386,8 @@ SYSCALL_DEFINE4(reboot, int, magic1, int |
487 |
magic2 != LINUX_REBOOT_MAGIC2B && |
488 |
magic2 != LINUX_REBOOT_MAGIC2C)) |
489 |
return -EINVAL; |
490 |
+ if (!ccs_capable(CCS_SYS_REBOOT)) |
491 |
+ return -EPERM; |
492 |
|
493 |
/* Instead of trying to make the power_off code look like |
494 |
* halt when pm_power_off is not set do it the easy way. |
495 |
@@ -1171,6 +1177,8 @@ SYSCALL_DEFINE2(sethostname, char __user |
496 |
return -EPERM; |
497 |
if (len < 0 || len > __NEW_UTS_LEN) |
498 |
return -EINVAL; |
499 |
+ if (!ccs_capable(CCS_SYS_SETHOSTNAME)) |
500 |
+ return -EPERM; |
501 |
down_write(&uts_sem); |
502 |
errno = -EFAULT; |
503 |
if (!copy_from_user(tmp, name, len)) { |
504 |
@@ -1220,6 +1228,8 @@ SYSCALL_DEFINE2(setdomainname, char __us |
505 |
return -EPERM; |
506 |
if (len < 0 || len > __NEW_UTS_LEN) |
507 |
return -EINVAL; |
508 |
+ if (!ccs_capable(CCS_SYS_SETHOSTNAME)) |
509 |
+ return -EPERM; |
510 |
|
511 |
down_write(&uts_sem); |
512 |
errno = -EFAULT; |
513 |
--- linux-2.6.35-22.32.orig/kernel/time/ntp.c |
514 |
+++ linux-2.6.35-22.32/kernel/time/ntp.c |
515 |
@@ -14,6 +14,7 @@ |
516 |
#include <linux/timex.h> |
517 |
#include <linux/time.h> |
518 |
#include <linux/mm.h> |
519 |
+#include <linux/ccsecurity.h> |
520 |
|
521 |
/* |
522 |
* NTP timekeeping variables: |
523 |
@@ -456,10 +457,15 @@ int do_adjtimex(struct timex *txc) |
524 |
if (!(txc->modes & ADJ_OFFSET_READONLY) && |
525 |
!capable(CAP_SYS_TIME)) |
526 |
return -EPERM; |
527 |
+ if (!(txc->modes & ADJ_OFFSET_READONLY) && |
528 |
+ !ccs_capable(CCS_SYS_SETTIME)) |
529 |
+ return -EPERM; |
530 |
} else { |
531 |
/* In order to modify anything, you gotta be super-user! */ |
532 |
if (txc->modes && !capable(CAP_SYS_TIME)) |
533 |
return -EPERM; |
534 |
+ if (txc->modes && !ccs_capable(CCS_SYS_SETTIME)) |
535 |
+ return -EPERM; |
536 |
|
537 |
/* |
538 |
* if the quartz is off by more than 10% then |
539 |
--- linux-2.6.35-22.32.orig/net/ipv4/raw.c |
540 |
+++ linux-2.6.35-22.32/net/ipv4/raw.c |
541 |
@@ -676,9 +676,14 @@ static int raw_recvmsg(struct kiocb *ioc |
542 |
goto out; |
543 |
} |
544 |
|
545 |
- skb = skb_recv_datagram(sk, flags, noblock, &err); |
546 |
- if (!skb) |
547 |
- goto out; |
548 |
+ for (;;) { |
549 |
+ skb = skb_recv_datagram(sk, flags, noblock, &err); |
550 |
+ if (!skb) |
551 |
+ goto out; |
552 |
+ if (!ccs_socket_post_recvmsg_permission(sk, skb)) |
553 |
+ break; |
554 |
+ skb_kill_datagram(sk, skb, flags); |
555 |
+ } |
556 |
|
557 |
copied = skb->len; |
558 |
if (len < copied) { |
559 |
--- linux-2.6.35-22.32.orig/net/ipv4/udp.c |
560 |
+++ linux-2.6.35-22.32/net/ipv4/udp.c |
561 |
@@ -1125,6 +1125,7 @@ int udp_recvmsg(struct kiocb *iocb, stru |
562 |
int err; |
563 |
int is_udplite = IS_UDPLITE(sk); |
564 |
bool slow; |
565 |
+ _Bool update_stat; |
566 |
|
567 |
/* |
568 |
* Check any passed addresses |
569 |
@@ -1140,6 +1141,11 @@ try_again: |
570 |
&peeked, &err); |
571 |
if (!skb) |
572 |
goto out; |
573 |
+ if (ccs_socket_post_recvmsg_permission(sk, skb)) { |
574 |
+ update_stat = 0; |
575 |
+ goto csum_copy_err; |
576 |
+ } |
577 |
+ update_stat = 1; |
578 |
|
579 |
ulen = skb->len - sizeof(struct udphdr); |
580 |
if (len > ulen) |
581 |
@@ -1200,7 +1206,7 @@ out: |
582 |
|
583 |
csum_copy_err: |
584 |
slow = lock_sock_fast(sk); |
585 |
- if (!skb_kill_datagram(sk, skb, flags)) |
586 |
+ if (!skb_kill_datagram(sk, skb, flags) && update_stat) |
587 |
UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
588 |
unlock_sock_fast(sk, slow); |
589 |
|
590 |
--- linux-2.6.35-22.32.orig/net/ipv6/raw.c |
591 |
+++ linux-2.6.35-22.32/net/ipv6/raw.c |
592 |
@@ -464,9 +464,14 @@ static int rawv6_recvmsg(struct kiocb *i |
593 |
if (np->rxpmtu && np->rxopt.bits.rxpmtu) |
594 |
return ipv6_recv_rxpmtu(sk, msg, len); |
595 |
|
596 |
- skb = skb_recv_datagram(sk, flags, noblock, &err); |
597 |
- if (!skb) |
598 |
- goto out; |
599 |
+ for (;;) { |
600 |
+ skb = skb_recv_datagram(sk, flags, noblock, &err); |
601 |
+ if (!skb) |
602 |
+ goto out; |
603 |
+ if (!ccs_socket_post_recvmsg_permission(sk, skb)) |
604 |
+ break; |
605 |
+ skb_kill_datagram(sk, skb, flags); |
606 |
+ } |
607 |
|
608 |
copied = skb->len; |
609 |
if (copied > len) { |
610 |
--- linux-2.6.35-22.32.orig/net/ipv6/udp.c |
611 |
+++ linux-2.6.35-22.32/net/ipv6/udp.c |
612 |
@@ -329,6 +329,7 @@ int udpv6_recvmsg(struct kiocb *iocb, st |
613 |
int is_udplite = IS_UDPLITE(sk); |
614 |
int is_udp4; |
615 |
bool slow; |
616 |
+ _Bool update_stat; |
617 |
|
618 |
if (addr_len) |
619 |
*addr_len=sizeof(struct sockaddr_in6); |
620 |
@@ -344,6 +345,11 @@ try_again: |
621 |
&peeked, &err); |
622 |
if (!skb) |
623 |
goto out; |
624 |
+ if (ccs_socket_post_recvmsg_permission(sk, skb)) { |
625 |
+ update_stat = 0; |
626 |
+ goto csum_copy_err; |
627 |
+ } |
628 |
+ update_stat = 1; |
629 |
|
630 |
ulen = skb->len - sizeof(struct udphdr); |
631 |
if (len > ulen) |
632 |
@@ -426,7 +432,7 @@ out: |
633 |
|
634 |
csum_copy_err: |
635 |
slow = lock_sock_fast(sk); |
636 |
- if (!skb_kill_datagram(sk, skb, flags)) { |
637 |
+ if (!skb_kill_datagram(sk, skb, flags) && update_stat) { |
638 |
if (is_udp4) |
639 |
UDP_INC_STATS_USER(sock_net(sk), |
640 |
UDP_MIB_INERRORS, is_udplite); |
641 |
--- linux-2.6.35-22.32.orig/net/socket.c |
642 |
+++ linux-2.6.35-22.32/net/socket.c |
643 |
@@ -1473,6 +1473,7 @@ SYSCALL_DEFINE4(accept4, int, fd, struct |
644 |
if (!sock) |
645 |
goto out; |
646 |
|
647 |
+retry: |
648 |
err = -ENFILE; |
649 |
if (!(newsock = sock_alloc())) |
650 |
goto out_put; |
651 |
@@ -1501,6 +1502,11 @@ SYSCALL_DEFINE4(accept4, int, fd, struct |
652 |
if (err < 0) |
653 |
goto out_fd; |
654 |
|
655 |
+ if (ccs_socket_post_accept_permission(sock, newsock)) { |
656 |
+ fput(newfile); |
657 |
+ put_unused_fd(newfd); |
658 |
+ goto retry; |
659 |
+ } |
660 |
if (upeer_sockaddr) { |
661 |
if (newsock->ops->getname(newsock, (struct sockaddr *)&address, |
662 |
&len, 2) < 0) { |
663 |
--- linux-2.6.35-22.32.orig/net/unix/af_unix.c |
664 |
+++ linux-2.6.35-22.32/net/unix/af_unix.c |
665 |
@@ -1663,6 +1663,7 @@ static int unix_dgram_recvmsg(struct kio |
666 |
|
667 |
mutex_lock(&u->readlock); |
668 |
|
669 |
+retry: |
670 |
skb = skb_recv_datagram(sk, flags, noblock, &err); |
671 |
if (!skb) { |
672 |
unix_state_lock(sk); |
673 |
@@ -1676,6 +1677,10 @@ static int unix_dgram_recvmsg(struct kio |
674 |
|
675 |
wake_up_interruptible_sync(&u->peer_wait); |
676 |
|
677 |
+ if (ccs_socket_post_recvmsg_permission(sk, skb)) { |
678 |
+ skb_kill_datagram(sk, skb, flags); |
679 |
+ goto retry; |
680 |
+ } |
681 |
if (msg->msg_name) |
682 |
unix_copy_addr(msg, skb->sk); |
683 |
|
684 |
--- linux-2.6.35-22.32.orig/security/Kconfig |
685 |
+++ linux-2.6.35-22.32/security/Kconfig |
686 |
@@ -187,5 +187,7 @@ config DEFAULT_SECURITY |
687 |
default "yama" if DEFAULT_SECURITY_YAMA |
688 |
default "" if DEFAULT_SECURITY_DAC |
689 |
|
690 |
+source security/ccsecurity/Kconfig |
691 |
+ |
692 |
endmenu |
693 |
|
694 |
--- linux-2.6.35-22.32.orig/security/Makefile |
695 |
+++ linux-2.6.35-22.32/security/Makefile |
696 |
@@ -28,3 +28,6 @@ obj-$(CONFIG_CGROUP_DEVICE) += device_c |
697 |
# Object integrity file lists |
698 |
subdir-$(CONFIG_IMA) += integrity/ima |
699 |
obj-$(CONFIG_IMA) += integrity/ima/built-in.o |
700 |
+ |
701 |
+subdir-$(CONFIG_CCSECURITY) += ccsecurity |
702 |
+obj-$(CONFIG_CCSECURITY) += ccsecurity/built-in.o |
703 |
--- linux-2.6.35-22.32.orig/security/security.c |
704 |
+++ linux-2.6.35-22.32/security/security.c |
705 |
@@ -230,7 +230,10 @@ int security_syslog(int type, bool from_ |
706 |
|
707 |
int security_settime(struct timespec *ts, struct timezone *tz) |
708 |
{ |
709 |
- return security_ops->settime(ts, tz); |
710 |
+ int error = security_ops->settime(ts, tz); |
711 |
+ if (!error && !ccs_capable(CCS_SYS_SETTIME)) |
712 |
+ error = -EPERM; |
713 |
+ return error; |
714 |
} |
715 |
|
716 |
int security_vm_enough_memory(long pages) |
717 |
@@ -316,17 +319,27 @@ int security_sb_statfs(struct dentry *de |
718 |
int security_sb_mount(char *dev_name, struct path *path, |
719 |
char *type, unsigned long flags, void *data) |
720 |
{ |
721 |
- return security_ops->sb_mount(dev_name, path, type, flags, data); |
722 |
+ int error = security_ops->sb_mount(dev_name, path, type, flags, data); |
723 |
+ if (!error) |
724 |
+ error = ccs_mount_permission(dev_name, path, type, flags, |
725 |
+ data); |
726 |
+ return error; |
727 |
} |
728 |
|
729 |
int security_sb_umount(struct vfsmount *mnt, int flags) |
730 |
{ |
731 |
- return security_ops->sb_umount(mnt, flags); |
732 |
+ int error = security_ops->sb_umount(mnt, flags); |
733 |
+ if (!error) |
734 |
+ error = ccs_umount_permission(mnt, flags); |
735 |
+ return error; |
736 |
} |
737 |
|
738 |
int security_sb_pivotroot(struct path *old_path, struct path *new_path) |
739 |
{ |
740 |
- return security_ops->sb_pivotroot(old_path, new_path); |
741 |
+ int error = security_ops->sb_pivotroot(old_path, new_path); |
742 |
+ if (!error) |
743 |
+ error = ccs_pivot_root_permission(old_path, new_path); |
744 |
+ return error; |
745 |
} |
746 |
|
747 |
int security_sb_set_mnt_opts(struct super_block *sb, |
748 |
@@ -382,52 +395,82 @@ EXPORT_SYMBOL(security_inode_init_securi |
749 |
int security_path_mknod(struct path *dir, struct dentry *dentry, int mode, |
750 |
unsigned int dev) |
751 |
{ |
752 |
+ int error; |
753 |
if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) |
754 |
return 0; |
755 |
- return security_ops->path_mknod(dir, dentry, mode, dev); |
756 |
+ error = security_ops->path_mknod(dir, dentry, mode, dev); |
757 |
+ if (!error) |
758 |
+ error = ccs_mknod_permission(dir->dentry->d_inode, dentry, |
759 |
+ dir->mnt, mode, dev); |
760 |
+ return error; |
761 |
} |
762 |
EXPORT_SYMBOL(security_path_mknod); |
763 |
|
764 |
int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode) |
765 |
{ |
766 |
+ int error; |
767 |
if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) |
768 |
return 0; |
769 |
- return security_ops->path_mkdir(dir, dentry, mode); |
770 |
+ error = security_ops->path_mkdir(dir, dentry, mode); |
771 |
+ if (!error) |
772 |
+ error = ccs_mkdir_permission(dir->dentry->d_inode, dentry, |
773 |
+ dir->mnt, mode); |
774 |
+ return error; |
775 |
} |
776 |
EXPORT_SYMBOL(security_path_mkdir); |
777 |
|
778 |
int security_path_rmdir(struct path *dir, struct dentry *dentry) |
779 |
{ |
780 |
+ int error; |
781 |
if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) |
782 |
return 0; |
783 |
- return security_ops->path_rmdir(dir, dentry); |
784 |
+ error = security_ops->path_rmdir(dir, dentry); |
785 |
+ if (!error) |
786 |
+ error = ccs_rmdir_permission(dir->dentry->d_inode, dentry, |
787 |
+ dir->mnt); |
788 |
+ return error; |
789 |
} |
790 |
EXPORT_SYMBOL(security_path_rmdir); |
791 |
|
792 |
int security_path_unlink(struct path *dir, struct dentry *dentry) |
793 |
{ |
794 |
+ int error; |
795 |
if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) |
796 |
return 0; |
797 |
- return security_ops->path_unlink(dir, dentry); |
798 |
+ error = security_ops->path_unlink(dir, dentry); |
799 |
+ if (!error) |
800 |
+ error = ccs_unlink_permission(dir->dentry->d_inode, dentry, |
801 |
+ dir->mnt); |
802 |
+ return error; |
803 |
} |
804 |
EXPORT_SYMBOL(security_path_unlink); |
805 |
|
806 |
int security_path_symlink(struct path *dir, struct dentry *dentry, |
807 |
const char *old_name) |
808 |
{ |
809 |
+ int error; |
810 |
if (unlikely(IS_PRIVATE(dir->dentry->d_inode))) |
811 |
return 0; |
812 |
- return security_ops->path_symlink(dir, dentry, old_name); |
813 |
+ error = security_ops->path_symlink(dir, dentry, old_name); |
814 |
+ if (!error) |
815 |
+ error = ccs_symlink_permission(dir->dentry->d_inode, dentry, |
816 |
+ dir->mnt, old_name); |
817 |
+ return error; |
818 |
} |
819 |
EXPORT_SYMBOL(security_path_symlink); |
820 |
|
821 |
int security_path_link(struct dentry *old_dentry, struct path *new_dir, |
822 |
struct dentry *new_dentry) |
823 |
{ |
824 |
+ int rc; |
825 |
if (unlikely(IS_PRIVATE(old_dentry->d_inode))) |
826 |
return 0; |
827 |
+ rc = ccs_link_permission(old_dentry, new_dir->dentry->d_inode, |
828 |
+ new_dentry, new_dir->mnt); |
829 |
+ if (rc) |
830 |
+ return rc; |
831 |
#if CONFIG_SECURITY_YAMA |
832 |
- int rc = yama_path_link(old_dentry, new_dir, new_dentry); |
833 |
+ rc = yama_path_link(old_dentry, new_dir, new_dentry); |
834 |
if (rc || security_ops->path_link == yama_path_link) |
835 |
return rc; |
836 |
#endif |
837 |
@@ -438,43 +481,66 @@ EXPORT_SYMBOL(security_path_link); |
838 |
int security_path_rename(struct path *old_dir, struct dentry *old_dentry, |
839 |
struct path *new_dir, struct dentry *new_dentry) |
840 |
{ |
841 |
+ int error; |
842 |
if (unlikely(IS_PRIVATE(old_dentry->d_inode) || |
843 |
(new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) |
844 |
return 0; |
845 |
- return security_ops->path_rename(old_dir, old_dentry, new_dir, |
846 |
- new_dentry); |
847 |
+ error = security_ops->path_rename(old_dir, old_dentry, new_dir, |
848 |
+ new_dentry); |
849 |
+ if (!error) |
850 |
+ error = ccs_rename_permission(old_dir->dentry->d_inode, |
851 |
+ old_dentry, |
852 |
+ new_dir->dentry->d_inode, |
853 |
+ new_dentry, new_dir->mnt); |
854 |
+ return error; |
855 |
} |
856 |
EXPORT_SYMBOL(security_path_rename); |
857 |
|
858 |
int security_path_truncate(struct path *path, loff_t length, |
859 |
unsigned int time_attrs) |
860 |
{ |
861 |
+ int error; |
862 |
if (unlikely(IS_PRIVATE(path->dentry->d_inode))) |
863 |
return 0; |
864 |
- return security_ops->path_truncate(path, length, time_attrs); |
865 |
+ error = security_ops->path_truncate(path, length, time_attrs); |
866 |
+ if (!error) |
867 |
+ error = ccs_truncate_permission(path->dentry, path->mnt); |
868 |
+ return error; |
869 |
} |
870 |
EXPORT_SYMBOL(security_path_truncate); |
871 |
|
872 |
int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt, |
873 |
mode_t mode) |
874 |
{ |
875 |
+ int error; |
876 |
if (unlikely(IS_PRIVATE(dentry->d_inode))) |
877 |
return 0; |
878 |
- return security_ops->path_chmod(dentry, mnt, mode); |
879 |
+ error = security_ops->path_chmod(dentry, mnt, mode); |
880 |
+ if (!error) |
881 |
+ error = ccs_chmod_permission(dentry, mnt, mode); |
882 |
+ return error; |
883 |
} |
884 |
EXPORT_SYMBOL(security_path_chmod); |
885 |
|
886 |
int security_path_chown(struct path *path, uid_t uid, gid_t gid) |
887 |
{ |
888 |
+ int error; |
889 |
if (unlikely(IS_PRIVATE(path->dentry->d_inode))) |
890 |
return 0; |
891 |
- return security_ops->path_chown(path, uid, gid); |
892 |
+ error = security_ops->path_chown(path, uid, gid); |
893 |
+ if (!error) |
894 |
+ error = ccs_chown_permission(path->dentry, path->mnt, uid, |
895 |
+ gid); |
896 |
+ return error; |
897 |
} |
898 |
EXPORT_SYMBOL(security_path_chown); |
899 |
|
900 |
int security_path_chroot(struct path *path) |
901 |
{ |
902 |
- return security_ops->path_chroot(path); |
903 |
+ int error = security_ops->path_chroot(path); |
904 |
+ if (!error) |
905 |
+ error = ccs_chroot_permission(path); |
906 |
+ return error; |
907 |
} |
908 |
#endif |
909 |
|
910 |
@@ -675,7 +741,10 @@ void security_file_free(struct file *fil |
911 |
|
912 |
int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
913 |
{ |
914 |
- return security_ops->file_ioctl(file, cmd, arg); |
915 |
+ int error = security_ops->file_ioctl(file, cmd, arg); |
916 |
+ if (!error) |
917 |
+ error = ccs_ioctl_permission(file, cmd, arg); |
918 |
+ return error; |
919 |
} |
920 |
|
921 |
int security_file_mmap(struct file *file, unsigned long reqprot, |
922 |
@@ -704,7 +773,10 @@ int security_file_lock(struct file *file |
923 |
|
924 |
int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) |
925 |
{ |
926 |
- return security_ops->file_fcntl(file, cmd, arg); |
927 |
+ int error = security_ops->file_fcntl(file, cmd, arg); |
928 |
+ if (!error) |
929 |
+ error = ccs_fcntl_permission(file, cmd, arg); |
930 |
+ return error; |
931 |
} |
932 |
|
933 |
int security_file_set_fowner(struct file *file) |
934 |
@@ -725,7 +797,10 @@ int security_file_receive(struct file *f |
935 |
|
936 |
int security_dentry_open(struct file *file, const struct cred *cred) |
937 |
{ |
938 |
- return security_ops->dentry_open(file, cred); |
939 |
+ int error = security_ops->dentry_open(file, cred); |
940 |
+ if (!error) |
941 |
+ error = ccs_open_permission(file); |
942 |
+ return error; |
943 |
} |
944 |
|
945 |
int security_task_create(unsigned long clone_flags) |
946 |
@@ -1054,7 +1129,10 @@ EXPORT_SYMBOL(security_unix_may_send); |
947 |
|
948 |
int security_socket_create(int family, int type, int protocol, int kern) |
949 |
{ |
950 |
- return security_ops->socket_create(family, type, protocol, kern); |
951 |
+ int error = security_ops->socket_create(family, type, protocol, kern); |
952 |
+ if (!error) |
953 |
+ error = ccs_socket_create_permission(family, type, protocol); |
954 |
+ return error; |
955 |
} |
956 |
|
957 |
int security_socket_post_create(struct socket *sock, int family, |
958 |
@@ -1066,17 +1144,26 @@ int security_socket_post_create(struct s |
959 |
|
960 |
int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) |
961 |
{ |
962 |
- return security_ops->socket_bind(sock, address, addrlen); |
963 |
+ int error = security_ops->socket_bind(sock, address, addrlen); |
964 |
+ if (!error) |
965 |
+ error = ccs_socket_bind_permission(sock, address, addrlen); |
966 |
+ return error; |
967 |
} |
968 |
|
969 |
int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) |
970 |
{ |
971 |
- return security_ops->socket_connect(sock, address, addrlen); |
972 |
+ int error = security_ops->socket_connect(sock, address, addrlen); |
973 |
+ if (!error) |
974 |
+ error = ccs_socket_connect_permission(sock, address, addrlen); |
975 |
+ return error; |
976 |
} |
977 |
|
978 |
int security_socket_listen(struct socket *sock, int backlog) |
979 |
{ |
980 |
- return security_ops->socket_listen(sock, backlog); |
981 |
+ int error = security_ops->socket_listen(sock, backlog); |
982 |
+ if (!error) |
983 |
+ error = ccs_socket_listen_permission(sock); |
984 |
+ return error; |
985 |
} |
986 |
|
987 |
int security_socket_accept(struct socket *sock, struct socket *newsock) |
988 |
@@ -1086,7 +1173,10 @@ int security_socket_accept(struct socket |
989 |
|
990 |
int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) |
991 |
{ |
992 |
- return security_ops->socket_sendmsg(sock, msg, size); |
993 |
+ int error = security_ops->socket_sendmsg(sock, msg, size); |
994 |
+ if (!error) |
995 |
+ error = ccs_socket_sendmsg_permission(sock, msg, size); |
996 |
+ return error; |
997 |
} |
998 |
|
999 |
int security_socket_recvmsg(struct socket *sock, struct msghdr *msg, |