12 |
arch/sparc/kernel/ptrace.c | 5 +++++ |
arch/sparc/kernel/ptrace.c | 5 +++++ |
13 |
arch/sparc64/kernel/ptrace.c | 5 +++++ |
arch/sparc64/kernel/ptrace.c | 5 +++++ |
14 |
arch/x86_64/ia32/ptrace32.c | 3 +++ |
arch/x86_64/ia32/ptrace32.c | 3 +++ |
|
fs/attr.c | 5 +++++ |
|
15 |
fs/compat.c | 9 ++++++++- |
fs/compat.c | 9 ++++++++- |
16 |
fs/exec.c | 11 ++++++++++- |
fs/exec.c | 11 ++++++++++- |
17 |
fs/fcntl.c | 4 ++++ |
fs/fcntl.c | 5 +++++ |
18 |
fs/ioctl.c | 5 +++++ |
fs/ioctl.c | 3 +++ |
19 |
fs/namei.c | 31 ++++++++++++++++++++++++++++++- |
fs/namei.c | 30 +++++++++++++++++++++++++++++- |
20 |
fs/namespace.c | 22 ++++++++++++++++++++++ |
fs/namespace.c | 9 +++++++++ |
21 |
fs/open.c | 28 ++++++++++++++++++++++++++++ |
fs/open.c | 26 ++++++++++++++++++++++++++ |
22 |
fs/proc/proc_misc.c | 1 + |
fs/proc/proc_misc.c | 1 + |
23 |
include/linux/init_task.h | 9 +++++++++ |
include/linux/init_task.h | 9 +++++++++ |
24 |
include/linux/sched.h | 6 ++++++ |
include/linux/sched.h | 6 ++++++ |
35 |
kernel/time/ntp.c | 3 +++ |
kernel/time/ntp.c | 3 +++ |
36 |
net/ipv4/inet_connection_sock.c | 3 +++ |
net/ipv4/inet_connection_sock.c | 3 +++ |
37 |
net/ipv4/inet_hashtables.c | 3 +++ |
net/ipv4/inet_hashtables.c | 3 +++ |
38 |
net/ipv4/raw.c | 4 ++++ |
net/ipv4/raw.c | 12 +++++++++--- |
39 |
net/ipv4/udp.c | 8 ++++++++ |
net/ipv4/udp.c | 14 +++++++++++++- |
40 |
net/ipv6/inet6_hashtables.c | 3 +++ |
net/ipv6/inet6_hashtables.c | 3 +++ |
41 |
net/ipv6/raw.c | 4 ++++ |
net/ipv6/raw.c | 12 +++++++++--- |
42 |
net/ipv6/udp.c | 4 ++++ |
net/ipv6/udp.c | 10 +++++++++- |
43 |
net/socket.c | 23 +++++++++++++++++++++++ |
net/socket.c | 22 ++++++++++++++++++++++ |
44 |
net/unix/af_unix.c | 4 ++++ |
net/unix/af_unix.c | 9 +++++++++ |
45 |
security/Kconfig | 2 ++ |
security/Kconfig | 2 ++ |
46 |
security/Makefile | 3 +++ |
security/Makefile | 3 +++ |
47 |
43 files changed, 278 insertions(+), 3 deletions(-) |
42 files changed, 280 insertions(+), 11 deletions(-) |
48 |
|
|
49 |
--- linux-2.6.21.7.orig/arch/alpha/kernel/ptrace.c |
--- linux-2.6.21.7.orig/arch/alpha/kernel/ptrace.c |
50 |
+++ linux-2.6.21.7/arch/alpha/kernel/ptrace.c |
+++ linux-2.6.21.7/arch/alpha/kernel/ptrace.c |
60 |
unsigned long tmp; |
unsigned long tmp; |
61 |
size_t copied; |
size_t copied; |
62 |
long ret; |
long ret; |
63 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
64 |
+ return -EPERM; |
+ return -EPERM; |
65 |
|
|
66 |
lock_kernel(); |
lock_kernel(); |
79 |
struct task_struct *child; |
struct task_struct *child; |
80 |
unsigned int value, tmp; |
unsigned int value, tmp; |
81 |
long i, ret; |
long i, ret; |
82 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
83 |
+ return -EPERM; |
+ return -EPERM; |
84 |
|
|
85 |
lock_kernel(); |
lock_kernel(); |
98 |
struct task_struct *child; |
struct task_struct *child; |
99 |
struct switch_stack *sw; |
struct switch_stack *sw; |
100 |
long ret; |
long ret; |
101 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
102 |
+ return -EPERM; |
+ return -EPERM; |
103 |
|
|
104 |
lock_kernel(); |
lock_kernel(); |
117 |
{ |
{ |
118 |
struct task_struct *child; |
struct task_struct *child; |
119 |
int ret; |
int ret; |
120 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
121 |
+ return -EPERM; |
+ return -EPERM; |
122 |
|
|
123 |
lock_kernel(); |
lock_kernel(); |
136 |
{ |
{ |
137 |
struct task_struct *child; |
struct task_struct *child; |
138 |
int ret; |
int ret; |
139 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
140 |
+ return -EPERM; |
+ return -EPERM; |
141 |
|
|
142 |
#if 0 |
#if 0 |
155 |
{ |
{ |
156 |
struct task_struct *child; |
struct task_struct *child; |
157 |
int ret; |
int ret; |
158 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
159 |
+ return -EPERM; |
+ return -EPERM; |
160 |
|
|
161 |
lock_kernel(); |
lock_kernel(); |
174 |
struct task_struct *child; |
struct task_struct *child; |
175 |
int ret; |
int ret; |
176 |
|
|
177 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
178 |
+ return -EPERM; |
+ return -EPERM; |
179 |
lock_kernel(); |
lock_kernel(); |
180 |
if (request == PTRACE_TRACEME) { |
if (request == PTRACE_TRACEME) { |
193 |
unsigned long addr2 = regs->u_regs[UREG_I4]; |
unsigned long addr2 = regs->u_regs[UREG_I4]; |
194 |
struct task_struct *child; |
struct task_struct *child; |
195 |
int ret; |
int ret; |
196 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) { |
+ if (ccs_ptrace_permission(request, pid)) { |
197 |
+ pt_error_return(regs, EPERM); |
+ pt_error_return(regs, EPERM); |
198 |
+ return; |
+ return; |
199 |
+ } |
+ } |
214 |
unsigned long addr2 = regs->u_regs[UREG_I4]; |
unsigned long addr2 = regs->u_regs[UREG_I4]; |
215 |
struct task_struct *child; |
struct task_struct *child; |
216 |
int ret; |
int ret; |
217 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) { |
+ if (ccs_ptrace_permission(request, pid)) { |
218 |
+ pt_error_return(regs, EPERM); |
+ pt_error_return(regs, EPERM); |
219 |
+ return; |
+ return; |
220 |
+ } |
+ } |
235 |
void __user *datap = compat_ptr(data); |
void __user *datap = compat_ptr(data); |
236 |
int ret; |
int ret; |
237 |
__u32 val; |
__u32 val; |
238 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
239 |
+ return -EPERM; |
+ return -EPERM; |
240 |
|
|
241 |
switch (request) { |
switch (request) { |
242 |
case PTRACE_TRACEME: |
case PTRACE_TRACEME: |
|
--- linux-2.6.21.7.orig/fs/attr.c |
|
|
+++ linux-2.6.21.7/fs/attr.c |
|
|
@@ -15,6 +15,7 @@ |
|
|
#include <linux/fcntl.h> |
|
|
#include <linux/quotaops.h> |
|
|
#include <linux/security.h> |
|
|
+#include <linux/ccsecurity.h> |
|
|
|
|
|
/* Taken over from the old code... */ |
|
|
|
|
|
@@ -146,11 +147,15 @@ int notify_change(struct dentry * dentry |
|
|
if (inode->i_op && inode->i_op->setattr) { |
|
|
error = security_inode_setattr(dentry, attr); |
|
|
if (!error) |
|
|
+ error = ccs_setattr_permission(dentry, attr); |
|
|
+ if (!error) |
|
|
error = inode->i_op->setattr(dentry, attr); |
|
|
} else { |
|
|
error = inode_change_ok(inode, attr); |
|
|
if (!error) |
|
|
error = security_inode_setattr(dentry, attr); |
|
|
+ if (!error) |
|
|
+ error = ccs_setattr_permission(dentry, attr); |
|
|
if (!error) { |
|
|
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || |
|
|
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) |
|
243 |
--- linux-2.6.21.7.orig/fs/compat.c |
--- linux-2.6.21.7.orig/fs/compat.c |
244 |
+++ linux-2.6.21.7/fs/compat.c |
+++ linux-2.6.21.7/fs/compat.c |
245 |
@@ -56,6 +56,7 @@ |
@@ -56,6 +56,7 @@ |
255 |
/* RED-PEN how should LSM module know it's handling 32bit? */ |
/* RED-PEN how should LSM module know it's handling 32bit? */ |
256 |
error = security_file_ioctl(filp, cmd, arg); |
error = security_file_ioctl(filp, cmd, arg); |
257 |
+ if (!error) |
+ if (!error) |
258 |
+ error = ccs_check_ioctl_permission(filp, cmd, arg); |
+ error = ccs_ioctl_permission(filp, cmd, arg); |
259 |
if (error) |
if (error) |
260 |
goto out_fput; |
goto out_fput; |
261 |
|
|
330 |
|
|
331 |
void fastcall set_close_on_exec(unsigned int fd, int flag) |
void fastcall set_close_on_exec(unsigned int fd, int flag) |
332 |
{ |
{ |
333 |
@@ -213,6 +214,9 @@ static int setfl(int fd, struct file * f |
@@ -392,6 +393,8 @@ asmlinkage long sys_fcntl(unsigned int f |
334 |
if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode)) |
goto out; |
|
return -EPERM; |
|
335 |
|
|
336 |
+ if (((arg ^ filp->f_flags) & O_APPEND) && ccs_rewrite_permission(filp)) |
err = security_file_fcntl(filp, cmd, arg); |
337 |
+ return -EPERM; |
+ if (!err) |
338 |
+ |
+ err = ccs_fcntl_permission(filp, cmd, arg); |
339 |
/* O_NOATIME can only be set by the owner or superuser */ |
if (err) { |
340 |
if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME)) |
fput(filp); |
341 |
if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) |
return err; |
342 |
|
@@ -416,6 +419,8 @@ asmlinkage long sys_fcntl64(unsigned int |
343 |
|
goto out; |
344 |
|
|
345 |
|
err = security_file_fcntl(filp, cmd, arg); |
346 |
|
+ if (!err) |
347 |
|
+ err = ccs_fcntl_permission(filp, cmd, arg); |
348 |
|
if (err) { |
349 |
|
fput(filp); |
350 |
|
return err; |
351 |
--- linux-2.6.21.7.orig/fs/ioctl.c |
--- linux-2.6.21.7.orig/fs/ioctl.c |
352 |
+++ linux-2.6.21.7/fs/ioctl.c |
+++ linux-2.6.21.7/fs/ioctl.c |
353 |
@@ -15,6 +15,7 @@ |
@@ -15,6 +15,7 @@ |
358 |
|
|
359 |
static long do_ioctl(struct file *filp, unsigned int cmd, |
static long do_ioctl(struct file *filp, unsigned int cmd, |
360 |
unsigned long arg) |
unsigned long arg) |
361 |
@@ -23,6 +24,8 @@ static long do_ioctl(struct file *filp, |
@@ -167,6 +168,8 @@ asmlinkage long sys_ioctl(unsigned int f |
|
|
|
|
if (!filp->f_op) |
|
|
goto out; |
|
|
+ if (!ccs_capable(CCS_SYS_IOCTL)) |
|
|
+ return -EPERM; |
|
|
|
|
|
if (filp->f_op->unlocked_ioctl) { |
|
|
error = filp->f_op->unlocked_ioctl(filp, cmd, arg); |
|
|
@@ -167,6 +170,8 @@ asmlinkage long sys_ioctl(unsigned int f |
|
362 |
goto out; |
goto out; |
363 |
|
|
364 |
error = security_file_ioctl(filp, cmd, arg); |
error = security_file_ioctl(filp, cmd, arg); |
400 |
error = vfs_create(dir->d_inode, path->dentry, mode, nd); |
error = vfs_create(dir->d_inode, path->dentry, mode, nd); |
401 |
mutex_unlock(&dir->d_inode->i_mutex); |
mutex_unlock(&dir->d_inode->i_mutex); |
402 |
dput(nd->dentry); |
dput(nd->dentry); |
403 |
@@ -1610,6 +1620,7 @@ static int open_namei_create(struct name |
@@ -1883,6 +1893,9 @@ asmlinkage long sys_mknodat(int dfd, con |
|
return may_open(nd, 0, flag & ~O_TRUNC); |
|
|
} |
|
|
|
|
|
+#include <linux/ccsecurity_vfs.h> |
|
|
/* |
|
|
* open_namei() |
|
|
* |
|
|
@@ -1883,6 +1894,9 @@ asmlinkage long sys_mknodat(int dfd, con |
|
404 |
if (!IS_POSIXACL(nd.dentry->d_inode)) |
if (!IS_POSIXACL(nd.dentry->d_inode)) |
405 |
mode &= ~current->fs->umask; |
mode &= ~current->fs->umask; |
406 |
if (!IS_ERR(dentry)) { |
if (!IS_ERR(dentry)) { |
410 |
switch (mode & S_IFMT) { |
switch (mode & S_IFMT) { |
411 |
case 0: case S_IFREG: |
case 0: case S_IFREG: |
412 |
error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); |
error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); |
413 |
@@ -1959,6 +1973,8 @@ asmlinkage long sys_mkdirat(int dfd, con |
@@ -1959,6 +1972,8 @@ asmlinkage long sys_mkdirat(int dfd, con |
414 |
|
|
415 |
if (!IS_POSIXACL(nd.dentry->d_inode)) |
if (!IS_POSIXACL(nd.dentry->d_inode)) |
416 |
mode &= ~current->fs->umask; |
mode &= ~current->fs->umask; |
419 |
error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); |
error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); |
420 |
dput(dentry); |
dput(dentry); |
421 |
out_unlock: |
out_unlock: |
422 |
@@ -2066,6 +2082,8 @@ static long do_rmdir(int dfd, const char |
@@ -2066,6 +2081,8 @@ static long do_rmdir(int dfd, const char |
423 |
error = PTR_ERR(dentry); |
error = PTR_ERR(dentry); |
424 |
if (IS_ERR(dentry)) |
if (IS_ERR(dentry)) |
425 |
goto exit2; |
goto exit2; |
428 |
error = vfs_rmdir(nd.dentry->d_inode, dentry); |
error = vfs_rmdir(nd.dentry->d_inode, dentry); |
429 |
dput(dentry); |
dput(dentry); |
430 |
exit2: |
exit2: |
431 |
@@ -2146,6 +2164,9 @@ static long do_unlinkat(int dfd, const c |
@@ -2146,6 +2163,9 @@ static long do_unlinkat(int dfd, const c |
432 |
inode = dentry->d_inode; |
inode = dentry->d_inode; |
433 |
if (inode) |
if (inode) |
434 |
atomic_inc(&inode->i_count); |
atomic_inc(&inode->i_count); |
438 |
error = vfs_unlink(nd.dentry->d_inode, dentry); |
error = vfs_unlink(nd.dentry->d_inode, dentry); |
439 |
exit2: |
exit2: |
440 |
dput(dentry); |
dput(dentry); |
441 |
@@ -2227,6 +2248,9 @@ asmlinkage long sys_symlinkat(const char |
@@ -2227,6 +2247,9 @@ asmlinkage long sys_symlinkat(const char |
442 |
if (IS_ERR(dentry)) |
if (IS_ERR(dentry)) |
443 |
goto out_unlock; |
goto out_unlock; |
444 |
|
|
448 |
error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); |
error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); |
449 |
dput(dentry); |
dput(dentry); |
450 |
out_unlock: |
out_unlock: |
451 |
@@ -2322,6 +2346,9 @@ asmlinkage long sys_linkat(int olddfd, c |
@@ -2322,6 +2345,9 @@ asmlinkage long sys_linkat(int olddfd, c |
452 |
error = PTR_ERR(new_dentry); |
error = PTR_ERR(new_dentry); |
453 |
if (IS_ERR(new_dentry)) |
if (IS_ERR(new_dentry)) |
454 |
goto out_unlock; |
goto out_unlock; |
458 |
error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); |
error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); |
459 |
dput(new_dentry); |
dput(new_dentry); |
460 |
out_unlock: |
out_unlock: |
461 |
@@ -2547,7 +2574,9 @@ static int do_rename(int olddfd, const c |
@@ -2547,7 +2573,9 @@ static int do_rename(int olddfd, const c |
462 |
error = -ENOTEMPTY; |
error = -ENOTEMPTY; |
463 |
if (new_dentry == trap) |
if (new_dentry == trap) |
464 |
goto exit5; |
goto exit5; |
488 |
if (retval) |
if (retval) |
489 |
return retval; |
return retval; |
490 |
|
|
491 |
@@ -633,6 +636,8 @@ asmlinkage long sys_umount(char __user * |
@@ -1376,6 +1379,7 @@ int copy_mount_options(const void __user |
|
{ |
|
|
struct nameidata nd; |
|
|
int retval; |
|
|
+ if (!ccs_capable(CCS_SYS_UMOUNT)) |
|
|
+ return -EPERM; |
|
|
|
|
|
retval = __user_walk(name, LOOKUP_FOLLOW, &nd); |
|
|
if (retval) |
|
|
@@ -917,6 +922,9 @@ static int do_loopback(struct nameidata |
|
|
|
|
|
if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) |
|
|
goto out; |
|
|
+ err = -EPERM; |
|
|
+ if (ccs_may_mount(nd)) |
|
|
+ goto out; |
|
|
|
|
|
err = -ENOMEM; |
|
|
if (recurse) |
|
|
@@ -1002,6 +1010,9 @@ static int do_move_mount(struct nameidat |
|
|
if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) |
|
|
goto out; |
|
|
|
|
|
+ err = -EPERM; |
|
|
+ if (ccs_may_mount(nd)) |
|
|
+ goto out; |
|
|
err = -ENOENT; |
|
|
mutex_lock(&nd->dentry->d_inode->i_mutex); |
|
|
if (IS_DEADDIR(nd->dentry->d_inode)) |
|
|
@@ -1103,6 +1114,9 @@ int do_add_mount(struct vfsmount *newmnt |
|
|
err = -EINVAL; |
|
|
if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode)) |
|
|
goto unlock; |
|
|
+ err = -EPERM; |
|
|
+ if (ccs_may_mount(nd)) |
|
|
+ goto unlock; |
|
|
|
|
|
newmnt->mnt_flags = mnt_flags; |
|
|
if ((err = graft_tree(newmnt, nd))) |
|
|
@@ -1376,6 +1390,7 @@ int copy_mount_options(const void __user |
|
492 |
long do_mount(char *dev_name, char *dir_name, char *type_page, |
long do_mount(char *dev_name, char *dir_name, char *type_page, |
493 |
unsigned long flags, void *data_page) |
unsigned long flags, void *data_page) |
494 |
{ |
{ |
496 |
struct nameidata nd; |
struct nameidata nd; |
497 |
int retval = 0; |
int retval = 0; |
498 |
int mnt_flags = 0; |
int mnt_flags = 0; |
499 |
@@ -1417,6 +1432,9 @@ long do_mount(char *dev_name, char *dir_ |
@@ -1417,6 +1421,9 @@ long do_mount(char *dev_name, char *dir_ |
500 |
return retval; |
return retval; |
501 |
|
|
502 |
retval = security_sb_mount(dev_name, &nd, type_page, flags, data_page); |
retval = security_sb_mount(dev_name, &nd, type_page, flags, data_page); |
506 |
if (retval) |
if (retval) |
507 |
goto dput_out; |
goto dput_out; |
508 |
|
|
509 |
@@ -1686,6 +1704,8 @@ asmlinkage long sys_pivot_root(const cha |
@@ -1702,6 +1709,8 @@ asmlinkage long sys_pivot_root(const cha |
|
|
|
|
if (!capable(CAP_SYS_ADMIN)) |
|
|
return -EPERM; |
|
|
+ if (!ccs_capable(CCS_SYS_PIVOT_ROOT)) |
|
|
+ return -EPERM; |
|
|
|
|
|
lock_kernel(); |
|
|
|
|
|
@@ -1702,6 +1722,8 @@ asmlinkage long sys_pivot_root(const cha |
|
510 |
goto out1; |
goto out1; |
511 |
|
|
512 |
error = security_sb_pivotroot(&old_nd, &new_nd); |
error = security_sb_pivotroot(&old_nd, &new_nd); |
529 |
if (error) |
if (error) |
530 |
goto dput_and_out; |
goto dput_and_out; |
531 |
|
|
532 |
+ error = ccs_truncate_permission(nd.dentry, nd.mnt, length, 0); |
+ error = ccs_truncate_permission(nd.dentry, nd.mnt); |
533 |
+ if (!error) |
+ if (!error) |
534 |
error = locks_verify_truncate(inode, NULL, length); |
error = locks_verify_truncate(inode, NULL, length); |
535 |
if (!error) { |
if (!error) { |
538 |
if (IS_APPEND(inode)) |
if (IS_APPEND(inode)) |
539 |
goto out_putf; |
goto out_putf; |
540 |
|
|
541 |
+ error = ccs_truncate_permission(dentry, file->f_vfsmnt, length, 0); |
+ error = ccs_truncate_permission(dentry, file->f_vfsmnt); |
542 |
+ if (error) |
+ if (error) |
543 |
+ goto out_putf; |
+ goto out_putf; |
544 |
error = locks_verify_truncate(inode, file, length); |
error = locks_verify_truncate(inode, file, length); |
545 |
if (!error) |
if (!error) |
546 |
error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); |
error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); |
547 |
@@ -481,6 +487,10 @@ asmlinkage long sys_chroot(const char __ |
@@ -481,6 +487,8 @@ asmlinkage long sys_chroot(const char __ |
548 |
error = -EPERM; |
error = -EPERM; |
549 |
if (!capable(CAP_SYS_CHROOT)) |
if (!capable(CAP_SYS_CHROOT)) |
550 |
goto dput_and_out; |
goto dput_and_out; |
|
+ if (!ccs_capable(CCS_SYS_CHROOT)) |
|
|
+ goto dput_and_out; |
|
551 |
+ if (ccs_chroot_permission(&nd)) |
+ if (ccs_chroot_permission(&nd)) |
552 |
+ goto dput_and_out; |
+ goto dput_and_out; |
553 |
|
|
554 |
set_fs_root(current->fs, nd.mnt, nd.dentry); |
set_fs_root(current->fs, nd.mnt, nd.dentry); |
555 |
set_fs_altroot(); |
set_fs_altroot(); |
556 |
@@ -514,6 +524,9 @@ asmlinkage long sys_fchmod(unsigned int |
@@ -514,6 +522,9 @@ asmlinkage long sys_fchmod(unsigned int |
557 |
err = -EPERM; |
err = -EPERM; |
558 |
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
559 |
goto out_putf; |
goto out_putf; |
563 |
mutex_lock(&inode->i_mutex); |
mutex_lock(&inode->i_mutex); |
564 |
if (mode == (mode_t) -1) |
if (mode == (mode_t) -1) |
565 |
mode = inode->i_mode; |
mode = inode->i_mode; |
566 |
@@ -548,6 +561,9 @@ asmlinkage long sys_fchmodat(int dfd, co |
@@ -548,6 +559,9 @@ asmlinkage long sys_fchmodat(int dfd, co |
567 |
error = -EPERM; |
error = -EPERM; |
568 |
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
569 |
goto dput_and_out; |
goto dput_and_out; |
573 |
|
|
574 |
mutex_lock(&inode->i_mutex); |
mutex_lock(&inode->i_mutex); |
575 |
if (mode == (mode_t) -1) |
if (mode == (mode_t) -1) |
576 |
@@ -611,6 +627,8 @@ asmlinkage long sys_chown(const char __u |
@@ -611,6 +625,8 @@ asmlinkage long sys_chown(const char __u |
577 |
error = user_path_walk(filename, &nd); |
error = user_path_walk(filename, &nd); |
578 |
if (error) |
if (error) |
579 |
goto out; |
goto out; |
582 |
error = chown_common(nd.dentry, user, group); |
error = chown_common(nd.dentry, user, group); |
583 |
path_release(&nd); |
path_release(&nd); |
584 |
out: |
out: |
585 |
@@ -631,6 +649,8 @@ asmlinkage long sys_fchownat(int dfd, co |
@@ -631,6 +647,8 @@ asmlinkage long sys_fchownat(int dfd, co |
586 |
error = __user_walk_fd(dfd, filename, follow, &nd); |
error = __user_walk_fd(dfd, filename, follow, &nd); |
587 |
if (error) |
if (error) |
588 |
goto out; |
goto out; |
591 |
error = chown_common(nd.dentry, user, group); |
error = chown_common(nd.dentry, user, group); |
592 |
path_release(&nd); |
path_release(&nd); |
593 |
out: |
out: |
594 |
@@ -645,6 +665,8 @@ asmlinkage long sys_lchown(const char __ |
@@ -645,6 +663,8 @@ asmlinkage long sys_lchown(const char __ |
595 |
error = user_path_walk_link(filename, &nd); |
error = user_path_walk_link(filename, &nd); |
596 |
if (error) |
if (error) |
597 |
goto out; |
goto out; |
600 |
error = chown_common(nd.dentry, user, group); |
error = chown_common(nd.dentry, user, group); |
601 |
path_release(&nd); |
path_release(&nd); |
602 |
out: |
out: |
603 |
@@ -664,6 +686,8 @@ asmlinkage long sys_fchown(unsigned int |
@@ -664,6 +684,8 @@ asmlinkage long sys_fchown(unsigned int |
604 |
|
|
605 |
dentry = file->f_path.dentry; |
dentry = file->f_path.dentry; |
606 |
audit_inode(NULL, dentry->d_inode); |
audit_inode(NULL, dentry->d_inode); |
609 |
error = chown_common(dentry, user, group); |
error = chown_common(dentry, user, group); |
610 |
fput(file); |
fput(file); |
611 |
out: |
out: |
612 |
@@ -756,7 +780,9 @@ static struct file *do_filp_open(int dfd |
@@ -756,7 +778,9 @@ static struct file *do_filp_open(int dfd |
613 |
if ((namei_flags+1) & O_ACCMODE) |
if ((namei_flags+1) & O_ACCMODE) |
614 |
namei_flags++; |
namei_flags++; |
615 |
|
|
619 |
if (!error) |
if (!error) |
620 |
return nameidata_to_filp(&nd, flags); |
return nameidata_to_filp(&nd, flags); |
621 |
|
|
622 |
@@ -1085,6 +1111,8 @@ EXPORT_SYMBOL(sys_close); |
@@ -1085,6 +1109,8 @@ EXPORT_SYMBOL(sys_close); |
623 |
*/ |
*/ |
624 |
asmlinkage long sys_vhangup(void) |
asmlinkage long sys_vhangup(void) |
625 |
{ |
{ |
634 |
entry->proc_fops = &proc_sysrq_trigger_operations; |
entry->proc_fops = &proc_sysrq_trigger_operations; |
635 |
} |
} |
636 |
#endif |
#endif |
637 |
+ printk(KERN_INFO "Hook version: 2.6.21.7 2009/09/10\n"); |
+ printk(KERN_INFO "Hook version: 2.6.21.7 2010/08/23\n"); |
638 |
} |
} |
639 |
--- linux-2.6.21.7.orig/include/linux/init_task.h |
--- linux-2.6.21.7.orig/include/linux/init_task.h |
640 |
+++ linux-2.6.21.7/include/linux/init_task.h |
+++ linux-2.6.21.7/include/linux/init_task.h |
663 |
|
|
664 |
--- linux-2.6.21.7.orig/include/linux/sched.h |
--- linux-2.6.21.7.orig/include/linux/sched.h |
665 |
+++ linux-2.6.21.7/include/linux/sched.h |
+++ linux-2.6.21.7/include/linux/sched.h |
666 |
@@ -27,6 +27,8 @@ |
@@ -37,6 +37,8 @@ |
667 |
#define CLONE_NEWUTS 0x04000000 /* New utsname group? */ |
|
668 |
#define CLONE_NEWIPC 0x08000000 /* New ipcs */ |
#ifdef __KERNEL__ |
669 |
|
|
670 |
+struct ccs_domain_info; |
+struct ccs_domain_info; |
671 |
+ |
+ |
672 |
/* |
struct sched_param { |
673 |
* Scheduling policies |
int sched_priority; |
674 |
*/ |
}; |
675 |
@@ -1052,6 +1054,10 @@ struct task_struct { |
@@ -1052,6 +1054,10 @@ struct task_struct { |
676 |
#ifdef CONFIG_FAULT_INJECTION |
#ifdef CONFIG_FAULT_INJECTION |
677 |
int make_it_fail; |
int make_it_fail; |
777 |
/* |
/* |
778 |
* This lock_kernel fixes a subtle race with suid exec |
* This lock_kernel fixes a subtle race with suid exec |
779 |
*/ |
*/ |
780 |
+ if (!ccs_capable(CCS_SYS_PTRACE)) |
+ if (ccs_ptrace_permission(request, pid)) |
781 |
+ return -EPERM; |
+ return -EPERM; |
782 |
lock_kernel(); |
lock_kernel(); |
783 |
if (request == PTRACE_TRACEME) { |
if (request == PTRACE_TRACEME) { |
1018 |
|
|
1019 |
struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE]; |
struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE]; |
1020 |
DEFINE_RWLOCK(raw_v4_lock); |
DEFINE_RWLOCK(raw_v4_lock); |
1021 |
@@ -597,6 +598,9 @@ static int raw_recvmsg(struct kiocb *ioc |
@@ -594,9 +595,14 @@ static int raw_recvmsg(struct kiocb *ioc |
|
skb = skb_recv_datagram(sk, flags, noblock, &err); |
|
|
if (!skb) |
|
1022 |
goto out; |
goto out; |
1023 |
+ err = ccs_socket_recvmsg_permission(sk, skb, flags); |
} |
1024 |
+ if (err) |
|
1025 |
+ goto out; |
- skb = skb_recv_datagram(sk, flags, noblock, &err); |
1026 |
|
- if (!skb) |
1027 |
|
- goto out; |
1028 |
|
+ for (;;) { |
1029 |
|
+ skb = skb_recv_datagram(sk, flags, noblock, &err); |
1030 |
|
+ if (!skb) |
1031 |
|
+ goto out; |
1032 |
|
+ if (!ccs_socket_post_recvmsg_permission(sk, skb)) |
1033 |
|
+ break; |
1034 |
|
+ skb_kill_datagram(sk, skb, flags); |
1035 |
|
+ } |
1036 |
|
|
1037 |
copied = skb->len; |
copied = skb->len; |
1038 |
if (len < copied) { |
if (len < copied) { |
1064 |
if (! __udp_lib_lport_inuse(result, udptable)) |
if (! __udp_lib_lport_inuse(result, udptable)) |
1065 |
break; |
break; |
1066 |
} |
} |
1067 |
@@ -825,6 +830,9 @@ try_again: |
@@ -811,6 +816,7 @@ int udp_recvmsg(struct kiocb *iocb, stru |
1068 |
|
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; |
1069 |
|
struct sk_buff *skb; |
1070 |
|
int copied, err, copy_only, is_udplite = IS_UDPLITE(sk); |
1071 |
|
+ _Bool update_stat; |
1072 |
|
|
1073 |
|
/* |
1074 |
|
* Check any passed addresses |
1075 |
|
@@ -825,6 +831,11 @@ try_again: |
1076 |
skb = skb_recv_datagram(sk, flags, noblock, &err); |
skb = skb_recv_datagram(sk, flags, noblock, &err); |
1077 |
if (!skb) |
if (!skb) |
1078 |
goto out; |
goto out; |
1079 |
+ err = ccs_socket_recvmsg_permission(sk, skb, flags); |
+ if (ccs_socket_post_recvmsg_permission(sk, skb)) { |
1080 |
+ if (err) |
+ update_stat = 0; |
1081 |
+ goto out; |
+ goto csum_copy_err; |
1082 |
|
+ } |
1083 |
|
+ update_stat = 1; |
1084 |
|
|
1085 |
copied = skb->len - sizeof(struct udphdr); |
copied = skb->len - sizeof(struct udphdr); |
1086 |
if (copied > len) { |
if (copied > len) { |
1087 |
|
@@ -883,7 +894,8 @@ out: |
1088 |
|
return err; |
1089 |
|
|
1090 |
|
csum_copy_err: |
1091 |
|
- UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite); |
1092 |
|
+ if (update_stat) |
1093 |
|
+ UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite); |
1094 |
|
|
1095 |
|
skb_kill_datagram(sk, skb, flags); |
1096 |
|
|
1097 |
--- linux-2.6.21.7.orig/net/ipv6/inet6_hashtables.c |
--- linux-2.6.21.7.orig/net/ipv6/inet6_hashtables.c |
1098 |
+++ linux-2.6.21.7/net/ipv6/inet6_hashtables.c |
+++ linux-2.6.21.7/net/ipv6/inet6_hashtables.c |
1099 |
@@ -21,6 +21,7 @@ |
@@ -21,6 +21,7 @@ |
1123 |
|
|
1124 |
struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE]; |
struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE]; |
1125 |
DEFINE_RWLOCK(raw_v6_lock); |
DEFINE_RWLOCK(raw_v6_lock); |
1126 |
@@ -413,6 +414,9 @@ static int rawv6_recvmsg(struct kiocb *i |
@@ -410,9 +411,14 @@ static int rawv6_recvmsg(struct kiocb *i |
1127 |
skb = skb_recv_datagram(sk, flags, noblock, &err); |
if (flags & MSG_ERRQUEUE) |
1128 |
if (!skb) |
return ipv6_recv_error(sk, msg, len); |
1129 |
goto out; |
|
1130 |
+ err = ccs_socket_recvmsg_permission(sk, skb, flags); |
- skb = skb_recv_datagram(sk, flags, noblock, &err); |
1131 |
+ if (err) |
- if (!skb) |
1132 |
+ goto out; |
- goto out; |
1133 |
|
+ for (;;) { |
1134 |
|
+ skb = skb_recv_datagram(sk, flags, noblock, &err); |
1135 |
|
+ if (!skb) |
1136 |
|
+ goto out; |
1137 |
|
+ if (!ccs_socket_post_recvmsg_permission(sk, skb)) |
1138 |
|
+ break; |
1139 |
|
+ skb_kill_datagram(sk, skb, flags); |
1140 |
|
+ } |
1141 |
|
|
1142 |
copied = skb->len; |
copied = skb->len; |
1143 |
if (copied > len) { |
if (copied > len) { |
1151 |
|
|
1152 |
DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; |
DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; |
1153 |
|
|
1154 |
@@ -133,6 +134,9 @@ try_again: |
@@ -122,6 +123,7 @@ int udpv6_recvmsg(struct kiocb *iocb, st |
1155 |
|
struct sk_buff *skb; |
1156 |
|
size_t copied; |
1157 |
|
int err, copy_only, is_udplite = IS_UDPLITE(sk); |
1158 |
|
+ _Bool update_stat; |
1159 |
|
|
1160 |
|
if (addr_len) |
1161 |
|
*addr_len=sizeof(struct sockaddr_in6); |
1162 |
|
@@ -133,6 +135,11 @@ try_again: |
1163 |
skb = skb_recv_datagram(sk, flags, noblock, &err); |
skb = skb_recv_datagram(sk, flags, noblock, &err); |
1164 |
if (!skb) |
if (!skb) |
1165 |
goto out; |
goto out; |
1166 |
+ err = ccs_socket_recvmsg_permission(sk, skb, flags); |
+ if (ccs_socket_post_recvmsg_permission(sk, skb)) { |
1167 |
+ if (err) |
+ update_stat = 0; |
1168 |
+ goto out; |
+ goto csum_copy_err; |
1169 |
|
+ } |
1170 |
|
+ update_stat = 1; |
1171 |
|
|
1172 |
copied = skb->len - sizeof(struct udphdr); |
copied = skb->len - sizeof(struct udphdr); |
1173 |
if (copied > len) { |
if (copied > len) { |
1174 |
|
@@ -205,7 +212,8 @@ csum_copy_err: |
1175 |
|
skb_kill_datagram(sk, skb, flags); |
1176 |
|
|
1177 |
|
if (flags & MSG_DONTWAIT) { |
1178 |
|
- UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); |
1179 |
|
+ if (update_stat) |
1180 |
|
+ UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); |
1181 |
|
return -EAGAIN; |
1182 |
|
} |
1183 |
|
goto try_again; |
1184 |
--- linux-2.6.21.7.orig/net/socket.c |
--- linux-2.6.21.7.orig/net/socket.c |
1185 |
+++ linux-2.6.21.7/net/socket.c |
+++ linux-2.6.21.7/net/socket.c |
1186 |
@@ -93,6 +93,8 @@ |
@@ -93,6 +93,8 @@ |
1192 |
static int sock_no_open(struct inode *irrelevant, struct file *dontcare); |
static int sock_no_open(struct inode *irrelevant, struct file *dontcare); |
1193 |
static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
1194 |
unsigned long nr_segs, loff_t pos); |
unsigned long nr_segs, loff_t pos); |
1195 |
@@ -547,6 +549,10 @@ static inline int __sock_sendmsg(struct |
@@ -547,6 +549,8 @@ static inline int __sock_sendmsg(struct |
1196 |
si->size = size; |
si->size = size; |
1197 |
|
|
1198 |
err = security_socket_sendmsg(sock, msg, size); |
err = security_socket_sendmsg(sock, msg, size); |
1199 |
+ if (!err) |
+ if (!err) |
1200 |
+ err = ccs_socket_sendmsg_permission(sock, (struct sockaddr *) |
+ err = ccs_socket_sendmsg_permission(sock, msg, size); |
|
+ msg->msg_name, |
|
|
+ msg->msg_namelen); |
|
1201 |
if (err) |
if (err) |
1202 |
return err; |
return err; |
1203 |
|
|
1204 |
@@ -1071,6 +1077,8 @@ static int __sock_create(int family, int |
@@ -1071,6 +1075,8 @@ static int __sock_create(int family, int |
1205 |
} |
} |
1206 |
|
|
1207 |
err = security_socket_create(family, type, protocol, kern); |
err = security_socket_create(family, type, protocol, kern); |
1210 |
if (err) |
if (err) |
1211 |
return err; |
return err; |
1212 |
|
|
1213 |
@@ -1299,6 +1307,11 @@ asmlinkage long sys_bind(int fd, struct |
@@ -1299,6 +1305,11 @@ asmlinkage long sys_bind(int fd, struct |
1214 |
(struct sockaddr *)address, |
(struct sockaddr *)address, |
1215 |
addrlen); |
addrlen); |
1216 |
if (!err) |
if (!err) |
1222 |
err = sock->ops->bind(sock, |
err = sock->ops->bind(sock, |
1223 |
(struct sockaddr *) |
(struct sockaddr *) |
1224 |
address, addrlen); |
address, addrlen); |
1225 |
@@ -1328,6 +1341,8 @@ asmlinkage long sys_listen(int fd, int b |
@@ -1328,6 +1339,8 @@ asmlinkage long sys_listen(int fd, int b |
1226 |
|
|
1227 |
err = security_socket_listen(sock, backlog); |
err = security_socket_listen(sock, backlog); |
1228 |
if (!err) |
if (!err) |
1231 |
err = sock->ops->listen(sock, backlog); |
err = sock->ops->listen(sock, backlog); |
1232 |
|
|
1233 |
fput_light(sock->file, fput_needed); |
fput_light(sock->file, fput_needed); |
1234 |
@@ -1391,6 +1406,11 @@ asmlinkage long sys_accept(int fd, struc |
@@ -1359,6 +1372,7 @@ asmlinkage long sys_accept(int fd, struc |
1235 |
|
if (!sock) |
1236 |
|
goto out; |
1237 |
|
|
1238 |
|
+retry: |
1239 |
|
err = -ENFILE; |
1240 |
|
if (!(newsock = sock_alloc())) |
1241 |
|
goto out_put; |
1242 |
|
@@ -1391,6 +1405,11 @@ asmlinkage long sys_accept(int fd, struc |
1243 |
if (err < 0) |
if (err < 0) |
1244 |
goto out_fd; |
goto out_fd; |
1245 |
|
|
1246 |
+ if (ccs_socket_accept_permission(newsock, |
+ if (ccs_socket_post_accept_permission(sock, newsock)) { |
1247 |
+ (struct sockaddr *) address)) { |
+ fput(newfile); |
1248 |
+ err = -ECONNABORTED; /* Hope less harmful than -EPERM. */ |
+ put_unused_fd(newfd); |
1249 |
+ goto out_fd; |
+ goto retry; |
1250 |
+ } |
+ } |
1251 |
if (upeer_sockaddr) { |
if (upeer_sockaddr) { |
1252 |
if (newsock->ops->getname(newsock, (struct sockaddr *)address, |
if (newsock->ops->getname(newsock, (struct sockaddr *)address, |
1253 |
&len, 2) < 0) { |
&len, 2) < 0) { |
1254 |
@@ -1453,6 +1473,9 @@ asmlinkage long sys_connect(int fd, stru |
@@ -1453,6 +1472,9 @@ asmlinkage long sys_connect(int fd, stru |
1255 |
|
|
1256 |
err = |
err = |
1257 |
security_socket_connect(sock, (struct sockaddr *)address, addrlen); |
security_socket_connect(sock, (struct sockaddr *)address, addrlen); |
1281 |
err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); |
err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); |
1282 |
if (err) |
if (err) |
1283 |
goto out_mknod_dput; |
goto out_mknod_dput; |
1284 |
|
@@ -1608,12 +1612,17 @@ static int unix_dgram_recvmsg(struct kio |
1285 |
|
|
1286 |
|
mutex_lock(&u->readlock); |
1287 |
|
|
1288 |
|
+retry: |
1289 |
|
skb = skb_recv_datagram(sk, flags, noblock, &err); |
1290 |
|
if (!skb) |
1291 |
|
goto out_unlock; |
1292 |
|
|
1293 |
|
wake_up_interruptible(&u->peer_wait); |
1294 |
|
|
1295 |
|
+ if (ccs_socket_post_recvmsg_permission(sk, skb)) { |
1296 |
|
+ skb_kill_datagram(sk, skb, flags); |
1297 |
|
+ goto retry; |
1298 |
|
+ } |
1299 |
|
if (msg->msg_name) |
1300 |
|
unix_copy_addr(msg, skb->sk); |
1301 |
|
|
1302 |
--- linux-2.6.21.7.orig/security/Kconfig |
--- linux-2.6.21.7.orig/security/Kconfig |
1303 |
+++ linux-2.6.21.7/security/Kconfig |
+++ linux-2.6.21.7/security/Kconfig |
1304 |
@@ -95,5 +95,7 @@ config SECURITY_ROOTPLUG |
@@ -95,5 +95,7 @@ config SECURITY_ROOTPLUG |