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