From: Stefan van der Eijk (stefan_at_eijk.nu)
Date: Mon 06 May 2002 - 21:45:03 BST
Jesper Andersen wrote:
>On Sunday 05 May 2002 23:19, you wrote:
>
>
>
>>I'm trying to get the CTX patch to work with Mandrake's development
>>kernels. While applying the patch I noticed that the CTX patch conflicts
>>with an earlier applied patch (the gr security patch, see
>>http://www.grsecurity.org/ ). Before I continue trying to figure things
>>out I've got a few questions:
>>
>>
>
>If you get et working please tell.
>
I'm trying to compile it, but the build is hanging on:
/usr/bin/gcc -D__KERNEL__ -I/home/cooker/RPM/BUILD/linux/include -Wall
-Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common
-fomit-frame-pointer -pipe -mpre
ferred-stack-boundary=2 -march=i586 -DMODULE -DMODVERSIONS -include
/home/cooker/RPM/BUILD/linux/include/linux/modversions.h -nostdinc -I
/usr/l
ib/gcc-lib/i586-mandrake-linux-gnu/2.96/include -DKBUILD_BASENAME=inode
-c -o inode.o inode.c
inode.c: In function `reiserfs_new_inode':
inode.c:1528: `EXT2_IMMUTABLE_FL' undeclared (first use in this function)
inode.c:1528: (Each undeclared identifier is reported only once
inode.c:1528: for each function it appears in.)
inode.c:1590: `S_IMMUTABLE' undeclared (first use in this function)
inode.c: In function `sd_attrs_to_i_attrs':
inode.c:2127: `EXT2_IMMUTABLE_FL' undeclared (first use in this function)
inode.c:2128: `S_IMMUTABLE' undeclared (first use in this function)
inode.c: In function `i_attrs_to_sd_attrs':
inode.c:2145: `S_IMMUTABLE' undeclared (first use in this function)
inode.c:2146: `EXT2_IMMUTABLE_FL' undeclared (first use in this function)
make[2]: *** [inode.o] Error 1
make[2]: Leaving directory `/home/cooker/RPM/BUILD/linux/fs/reiserfs'
make[1]: *** [_modsubdir_reiserfs] Error 2
make[1]: Leaving directory `/home/cooker/RPM/BUILD/linux/fs'
make: *** [_mod_fs] Error 2
error: Bad exit status from /home/cooker/tmp/rpm-tmp.25008 (%build)
RPM build errors:
Bad exit status from /home/cooker/tmp/rpm-tmp.25008 (%build)
See:
http://node-d-0565.a2000.nl/build/new_i586/i586/problem/kernel-2.4.18.13mdk_ctx10-1-1mdk.src.rpm.txt
src.rpm:
http://node-d-0565.a2000.nl/new_i586/kernel-2.4.18.13mdk_ctx10-1-1mdk.src.rpm
>I tried the same thing on a 2.4.18 kernel and after resolving a few conflicts
>it compiled fine, but during boot something went wrong during the load of the
>unix module as far as I remember. I didn't do any more to figure out what
>went wrong.
>
I've succeeded in compiling it once (against 2.4.18-7mdk I beleive) but
the kernel didn't boot...
>>- Does the GR security functionality conflict with CTX?
>>- Is there a smart way to merge GR security and CTX patches?
>>
>>
>
>I can't remember which order but there is a difference in applying the one
>before the other.
>
Neither do I...
Attached is my modified patch, which probably doesn't work :-/
Stefan
diff -rc2P linux-2.4.18/Makefile linux-2.4.18ctx-10/Makefile
*** linux-2.4.18/Makefile Tue Feb 26 22:21:48 2002
--- linux-2.4.18ctx-10/Makefile Tue Mar 19 23:20:34 2002
***************
*** 2,6 ****
PATCHLEVEL = 4
SUBLEVEL = 18
! EXTRAVERSION = -pre6
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
--- 2,6 ----
PATCHLEVEL = 4
SUBLEVEL = 18
! EXTRAVERSION = pre6-ctx-10
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff -rc2P linux-2.4.18/arch/i386/kernel/entry.S linux-2.4.18ctx-10/arch/i386/kernel/entry.S
*** linux-2.4.18/arch/i386/kernel/entry.S Tue Feb 26 22:21:49 2002
--- linux-2.4.18ctx-10/arch/i386/kernel/entry.S Wed Feb 27 14:36:44 2002
***************
*** 635,638 ****
--- 635,640 ----
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for lremovexattr */
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for fremovexattr */
+ .long SYMBOL_NAME(sys_new_s_context)
+ .long SYMBOL_NAME(sys_set_ipv4root)
.rept NR_syscalls-(.-sys_call_table)/4
diff -rc2P linux-2.4.18/arch/i386/kernel/ptrace.c linux-2.4.18ctx-10/arch/i386/kernel/ptrace.c
*** linux-2.4.18/arch/i386/kernel/ptrace.c Fri Nov 23 15:07:41 2001
--- linux-2.4.18ctx-10/arch/i386/kernel/ptrace.c Tue Feb 26 22:31:23 2002
***************
*** 171,175 ****
get_task_struct(child);
read_unlock(&tasklist_lock);
! if (!child)
goto out;
--- 171,175 ----
get_task_struct(child);
read_unlock(&tasklist_lock);
! if (!child || child->s_context != current->s_context)
goto out;
diff -rc2P linux-2.4.18/fs/devpts/inode.c linux-2.4.18ctx-10/fs/devpts/inode.c
*** linux-2.4.18/fs/devpts/inode.c Wed Oct 10 11:58:19 2001
--- linux-2.4.18ctx-10/fs/devpts/inode.c Tue Feb 26 22:31:23 2002
***************
*** 25,28 ****
--- 25,29 ----
#include <asm/bitops.h>
#include <asm/uaccess.h>
+ #include <linux/sched.h>
#include "devpts_i.h"
***************
*** 153,157 ****
inode->i_fop = &devpts_root_operations;
inode->i_nlink = 2;
-
s->u.generic_sbp = (void *) sbi;
s->s_blocksize = 1024;
--- 154,157 ----
***************
*** 181,184 ****
--- 181,197 ----
static DECLARE_FSTYPE(devpts_fs_type, "devpts", devpts_read_super, FS_SINGLE);
+ static int devpts_tty_permission(struct inode *inode, int mask)
+ {
+ int ret = -EACCES;
+ if (current->s_context == inode->u.devpts_i.s_context){
+ ret = vfs_permission(inode, mask);
+ }
+ return ret;
+ }
+
+ struct inode_operations devpts_tty_inode_operations = {
+ permission: devpts_tty_permission,
+ };
+
void devpts_pty_new(int number, kdev_t device)
{
***************
*** 199,202 ****
--- 212,217 ----
inode->i_gid = sbi->setgid ? sbi->gid : current->fsgid;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ inode->u.devpts_i.s_context = current->s_context;
+ inode->i_op = &devpts_tty_inode_operations;
init_special_inode(inode, S_IFCHR|sbi->mode, kdev_t_to_nr(device));
diff -rc2P linux-2.4.18/fs/devpts/root.c linux-2.4.18ctx-10/fs/devpts/root.c
*** linux-2.4.18/fs/devpts/root.c Sat Dec 22 22:38:37 2001
--- linux-2.4.18ctx-10/fs/devpts/root.c Tue Feb 26 22:31:23 2002
***************
*** 15,18 ****
--- 15,19 ----
#include <linux/param.h>
#include <linux/string.h>
+ #include <linux/sched.h>
#include "devpts_i.h"
***************
*** 65,69 ****
while ( nr - 2 < sbi->max_ptys ) {
int ptynr = nr - 2;
! if ( sbi->inodes[ptynr] ) {
genptsname(numbuf, ptynr);
if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_CHR) < 0 )
--- 66,73 ----
while ( nr - 2 < sbi->max_ptys ) {
int ptynr = nr - 2;
! struct inode *inode = sbi->inodes[ptynr];
! if ( inode != NULL
! && (current->s_context == 1
! || inode->u.devpts_i.s_context == current->s_context)) {
genptsname(numbuf, ptynr);
if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_CHR) < 0 )
***************
*** 101,104 ****
--- 105,109 ----
int i;
const char *p;
+ struct inode *inode;
dentry->d_op = &devpts_dentry_operations;
***************
*** 127,135 ****
return NULL;
! if ( sbi->inodes[entry] )
! atomic_inc(&sbi->inodes[entry]->i_count);
! d_add(dentry, sbi->inodes[entry]);
return NULL;
}
--- 132,147 ----
return NULL;
! inode = sbi->inodes[entry];
! if (inode != NULL
! && inode->u.devpts_i.s_context == current->s_context){
! atomic_inc(&inode->i_count);
! }else{
! inode = NULL;
! }
! d_add(dentry, inode);
return NULL;
}
+
+
diff -rc2P linux-2.4.18/fs/exec.c linux-2.4.18ctx-10/fs/exec.c
*** linux-2.4.18/fs/exec.c Sat Dec 22 22:38:37 2001
--- linux-2.4.18ctx-10/fs/exec.c Tue Feb 26 22:31:23 2002
***************
*** 686,690 ****
int do_unlock = 0;
! new_permitted = cap_intersect(bprm->cap_permitted, cap_bset);
working = cap_intersect(bprm->cap_inheritable,
current->cap_inheritable);
--- 686,690 ----
int do_unlock = 0;
! new_permitted = cap_intersect(bprm->cap_permitted, current->cap_bset);
working = cap_intersect(bprm->cap_inheritable,
current->cap_inheritable);
diff -rc2P linux-2.4.18/fs/ext2/ialloc.c linux-2.4.18ctx-10/fs/ext2/ialloc.c
*** linux-2.4.18/fs/ext2/ialloc.c Tue Feb 26 22:22:03 2002
--- linux-2.4.18ctx-10/fs/ext2/ialloc.c Tue Feb 26 22:31:23 2002
***************
*** 389,393 ****
inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags;
if (S_ISLNK(mode))
! inode->u.ext2_i.i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
inode->u.ext2_i.i_block_group = group;
if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
--- 389,393 ----
inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags;
if (S_ISLNK(mode))
! inode->u.ext2_i.i_flags &= ~(EXT2_IMMUTABLE_FILE_FL | EXT2_IMMUTABLE_LINK_FL | EXT2_APPEND_FL);
inode->u.ext2_i.i_block_group = group;
if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
diff -rc2P linux-2.4.18/fs/ext2/inode.c linux-2.4.18ctx-10/fs/ext2/inode.c
*** linux-2.4.18/fs/ext2/inode.c Tue Feb 26 22:22:03 2002
--- linux-2.4.18ctx-10/fs/ext2/inode.c Tue Feb 26 22:31:23 2002
***************
*** 801,805 ****
S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
--- 801,805 ----
S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
return;
***************
*** 1007,1013 ****
inode->i_flags |= S_APPEND;
}
! if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL) {
! inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE;
! inode->i_flags |= S_IMMUTABLE;
}
if (inode->u.ext2_i.i_flags & EXT2_NOATIME_FL) {
--- 1007,1017 ----
inode->i_flags |= S_APPEND;
}
! if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FILE_FL) {
! inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE_FILE;
! inode->i_flags |= S_IMMUTABLE_FILE;
! }
! if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_LINK_FL) {
! inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE_LINK;
! inode->i_flags |= S_IMMUTABLE_LINK;
}
if (inode->u.ext2_i.i_flags & EXT2_NOATIME_FL) {
diff -rc2P linux-2.4.18/fs/ext2/ioctl.c linux-2.4.18ctx-10/fs/ext2/ioctl.c
*** linux-2.4.18/fs/ext2/ioctl.c Wed Sep 27 16:41:33 2000
--- linux-2.4.18ctx-10/fs/ext2/ioctl.c Tue Feb 26 22:31:23 2002
***************
*** 45,49 ****
* This test looks nicer. Thanks to Pauline Middelink
*/
! if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
if (!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
--- 45,49 ----
* This test looks nicer. Thanks to Pauline Middelink
*/
! if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FILE_FL | EXT2_IMMUTABLE_LINK_FL)) {
if (!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
***************
*** 62,69 ****
else
inode->i_flags &= ~S_APPEND;
! if (flags & EXT2_IMMUTABLE_FL)
! inode->i_flags |= S_IMMUTABLE;
else
! inode->i_flags &= ~S_IMMUTABLE;
if (flags & EXT2_NOATIME_FL)
inode->i_flags |= S_NOATIME;
--- 62,76 ----
else
inode->i_flags &= ~S_APPEND;
!
! if (flags & EXT2_IMMUTABLE_FILE_FL)
! inode->i_flags |= S_IMMUTABLE_FILE;
! else
! inode->i_flags &= ~S_IMMUTABLE_FILE;
!
! if (flags & EXT2_IMMUTABLE_LINK_FL)
! inode->i_flags |= S_IMMUTABLE_LINK;
else
! inode->i_flags &= ~S_IMMUTABLE_LINK;
!
if (flags & EXT2_NOATIME_FL)
inode->i_flags |= S_NOATIME;
diff -rc2P linux-2.4.18/fs/ext3/ialloc.c linux-2.4.18ctx-10/fs/ext3/ialloc.c
*** linux-2.4.18/fs/ext3/ialloc.c Tue Feb 26 22:22:04 2002
--- linux-2.4.18ctx-10/fs/ext3/ialloc.c Tue Feb 26 22:31:23 2002
***************
*** 486,490 ****
inode->u.ext3_i.i_flags = dir->u.ext3_i.i_flags & ~EXT3_INDEX_FL;
if (S_ISLNK(mode))
! inode->u.ext3_i.i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
#ifdef EXT3_FRAGMENTS
inode->u.ext3_i.i_faddr = 0;
--- 486,490 ----
inode->u.ext3_i.i_flags = dir->u.ext3_i.i_flags & ~EXT3_INDEX_FL;
if (S_ISLNK(mode))
! inode->u.ext3_i.i_flags &= ~(EXT3_IMMUTABLE_FILE_FL | EXT3_IMMUTABLE_LINK_FL | EXT3_APPEND_FL);
#ifdef EXT3_FRAGMENTS
inode->u.ext3_i.i_faddr = 0;
diff -rc2P linux-2.4.18/fs/ext3/inode.c linux-2.4.18ctx-10/fs/ext3/inode.c
*** linux-2.4.18/fs/ext3/inode.c Tue Feb 26 22:22:04 2002
--- linux-2.4.18ctx-10/fs/ext3/inode.c Tue Feb 26 22:31:23 2002
***************
*** 1846,1850 ****
S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
--- 1846,1850 ----
S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
return;
***************
*** 2150,2156 ****
inode->i_flags |= S_APPEND;
}
! if (inode->u.ext3_i.i_flags & EXT3_IMMUTABLE_FL) {
/* inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE; unused */
! inode->i_flags |= S_IMMUTABLE;
}
if (inode->u.ext3_i.i_flags & EXT3_NOATIME_FL) {
--- 2150,2159 ----
inode->i_flags |= S_APPEND;
}
! if (inode->u.ext3_i.i_flags & EXT3_IMMUTABLE_FILE_FL) {
/* inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE; unused */
! inode->i_flags |= S_IMMUTABLE_FILE;
! }
! if (inode->u.ext3_i.i_flags & EXT3_IMMUTABLE_LINK_FL) {
! inode->i_flags |= S_IMMUTABLE_LINK;
}
if (inode->u.ext3_i.i_flags & EXT3_NOATIME_FL) {
diff -rc2P linux-2.4.18/fs/ext3/ioctl.c linux-2.4.18ctx-10/fs/ext3/ioctl.c
*** linux-2.4.18/fs/ext3/ioctl.c Fri Nov 23 15:07:49 2001
--- linux-2.4.18ctx-10/fs/ext3/ioctl.c Tue Feb 26 22:31:23 2002
***************
*** 54,58 ****
* This test looks nicer. Thanks to Pauline Middelink
*/
! if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
if (!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
--- 54,58 ----
* This test looks nicer. Thanks to Pauline Middelink
*/
! if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FILE_FL | EXT3_IMMUTABLE_LINK_FL)) {
if (!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
***************
*** 90,97 ****
else
inode->i_flags &= ~S_APPEND;
! if (flags & EXT3_IMMUTABLE_FL)
! inode->i_flags |= S_IMMUTABLE;
else
! inode->i_flags &= ~S_IMMUTABLE;
if (flags & EXT3_NOATIME_FL)
inode->i_flags |= S_NOATIME;
--- 90,101 ----
else
inode->i_flags &= ~S_APPEND;
! if (flags & EXT3_IMMUTABLE_FILE_FL)
! inode->i_flags |= S_IMMUTABLE_FILE;
else
! inode->i_flags &= ~S_IMMUTABLE_FILE;
! if (flags & EXT3_IMMUTABLE_LINK_FL)
! inode->i_flags |= S_IMMUTABLE_LINK;
! else
! inode->i_flags &= ~S_IMMUTABLE_LINK;
if (flags & EXT3_NOATIME_FL)
inode->i_flags |= S_NOATIME;
diff -rc2P linux-2.4.18/fs/fat/file.c linux-2.4.18ctx-10/fs/fat/file.c
*** linux-2.4.18/fs/fat/file.c Sun Aug 12 13:56:56 2001
--- linux-2.4.18ctx-10/fs/fat/file.c Tue Feb 26 22:31:23 2002
***************
*** 120,124 ****
if (IS_RDONLY (inode))
return /* -EPERM */;
! if (IS_IMMUTABLE(inode))
return /* -EPERM */;
cluster = 1 << sbi->cluster_bits;
--- 120,124 ----
if (IS_RDONLY (inode))
return /* -EPERM */;
! if (IS_IMMUTABLE_FILE(inode))
return /* -EPERM */;
cluster = 1 << sbi->cluster_bits;
diff -rc2P linux-2.4.18/fs/fat/inode.c linux-2.4.18ctx-10/fs/fat/inode.c
*** linux-2.4.18/fs/fat/inode.c Tue Feb 26 22:22:04 2002
--- linux-2.4.18ctx-10/fs/fat/inode.c Tue Feb 26 22:31:23 2002
***************
*** 948,952 ****
if(de->attr & ATTR_SYS)
if (sbi->options.sys_immutable)
! inode->i_flags |= S_IMMUTABLE;
MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
/* this is as close to the truth as we can get ... */
--- 948,952 ----
if(de->attr & ATTR_SYS)
if (sbi->options.sys_immutable)
! inode->i_flags |= S_IMMUTABLE_FILE;
MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
/* this is as close to the truth as we can get ... */
diff -rc2P linux-2.4.18/fs/hpfs/file.c linux-2.4.18ctx-10/fs/hpfs/file.c
*** linux-2.4.18/fs/hpfs/file.c Sun Aug 12 20:37:53 2001
--- linux-2.4.18ctx-10/fs/hpfs/file.c Tue Feb 26 22:31:23 2002
***************
*** 61,65 ****
void hpfs_truncate(struct inode *i)
{
! if (IS_IMMUTABLE(i)) return /*-EPERM*/;
i->i_hpfs_n_secs = 0;
i->i_blocks = 1 + ((i->i_size + 511) >> 9);
--- 61,65 ----
void hpfs_truncate(struct inode *i)
{
! if (IS_IMMUTABLE_FILE(i)) return /*-EPERM*/;
i->i_hpfs_n_secs = 0;
i->i_blocks = 1 + ((i->i_size + 511) >> 9);
diff -rc2P linux-2.4.18/fs/intermezzo/vfs.c linux-2.4.18ctx-10/fs/intermezzo/vfs.c
*** linux-2.4.18/fs/intermezzo/vfs.c Tue Feb 26 22:22:04 2002
--- linux-2.4.18ctx-10/fs/intermezzo/vfs.c Tue Feb 26 22:31:23 2002
***************
*** 90,94 ****
return -EPERM;
if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
! IS_IMMUTABLE(victim->d_inode))
return -EPERM;
if (isdir) {
--- 90,94 ----
return -EPERM;
if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
! IS_IMMUTABLE_LINK(victim->d_inode))
return -EPERM;
if (isdir) {
***************
*** 191,195 ****
}
! if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
EXIT;
return -EPERM;
--- 191,195 ----
}
! if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode)) {
EXIT;
return -EPERM;
***************
*** 232,236 ****
}
! if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
EXIT;
return -EPERM;
--- 232,236 ----
}
! if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode)) {
EXIT;
return -EPERM;
***************
*** 619,623 ****
*/
error = -EPERM;
! if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
EXIT;
goto exit_lock;
--- 619,623 ----
*/
error = -EPERM;
! if (IS_APPEND(inode) || IS_IMMUTABLE_LINK(inode)) {
EXIT;
goto exit_lock;
***************
*** 2221,2225 ****
}
! if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
EXIT;
return -EPERM;
--- 2221,2225 ----
}
! if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode)) {
EXIT;
return -EPERM;
diff -rc2P linux-2.4.18/fs/namei.c linux-2.4.18ctx-10/fs/namei.c
*** linux-2.4.18/fs/namei.c Tue Feb 26 22:22:07 2002
--- linux-2.4.18ctx-10/fs/namei.c Tue Feb 26 22:31:23 2002
***************
*** 153,156 ****
--- 153,165 ----
umode_t mode = inode->i_mode;
+ /*
+ A dir with permission bit all 0s is a dead zone for
+ process running in a vserver. By doing
+ chmod 000 /vservers
+ you fix the "escape from chroot" bug.
+ */
+ if ((mode & 0777) == 0
+ && S_ISDIR(mode)
+ && current->s_context != 0) return -EACCES;
if (mask & MAY_WRITE) {
/*
***************
*** 164,168 ****
* Nobody gets write access to an immutable file.
*/
! if (IS_IMMUTABLE(inode))
return -EACCES;
}
--- 173,177 ----
* Nobody gets write access to an immutable file.
*/
! if (IS_IMMUTABLE_FILE(inode))
return -EACCES;
}
***************
*** 879,884 ****
if (IS_APPEND(dir))
return -EPERM;
! if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
! IS_IMMUTABLE(victim->d_inode))
return -EPERM;
if (isdir) {
--- 888,892 ----
if (IS_APPEND(dir))
return -EPERM;
! if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||IS_IMMUTABLE_LINK(victim->d_inode))
return -EPERM;
if (isdir) {
***************
*** 1596,1600 ****
*/
error = -EPERM;
! if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
goto exit_lock;
if (!dir->i_op || !dir->i_op->link)
--- 1604,1608 ----
*/
error = -EPERM;
! if (IS_APPEND(inode) || IS_IMMUTABLE_LINK(inode))
goto exit_lock;
if (!dir->i_op || !dir->i_op->link)
diff -rc2P linux-2.4.18/fs/nfsd/vfs.c linux-2.4.18ctx-10/fs/nfsd/vfs.c
*** linux-2.4.18/fs/nfsd/vfs.c Sat Dec 22 22:38:38 2001
--- linux-2.4.18ctx-10/fs/nfsd/vfs.c Tue Feb 26 22:31:23 2002
***************
*** 1485,1489 ****
return 0;
#if 0
! dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s\n",
acc,
(acc & MAY_READ)? " read" : "",
--- 1485,1489 ----
return 0;
#if 0
! dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s%s\n",
acc,
(acc & MAY_READ)? " read" : "",
***************
*** 1495,1499 ****
(acc & MAY_OWNER_OVERRIDE)? " owneroverride" : "",
inode->i_mode,
! IS_IMMUTABLE(inode)? " immut" : "",
IS_APPEND(inode)? " append" : "",
IS_RDONLY(inode)? " ro" : "");
--- 1495,1500 ----
(acc & MAY_OWNER_OVERRIDE)? " owneroverride" : "",
inode->i_mode,
! IS_IMMUTABLE_FILE(inode)? " immut(F)" : "",
! IS_IMMUTABLE_LINK(inode)? " immut(L)" : "",
IS_APPEND(inode)? " append" : "",
IS_RDONLY(inode)? " ro" : "");
***************
*** 1510,1514 ****
if (EX_RDONLY(exp) || IS_RDONLY(inode))
return nfserr_rofs;
! if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
return nfserr_perm;
}
--- 1511,1515 ----
if (EX_RDONLY(exp) || IS_RDONLY(inode))
return nfserr_rofs;
! if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE_FILE(inode))
return nfserr_perm;
}
diff -rc2P linux-2.4.18/fs/open.c linux-2.4.18ctx-10/fs/open.c
*** linux-2.4.18/fs/open.c Wed Oct 31 15:32:41 2001
--- linux-2.4.18ctx-10/fs/open.c Tue Feb 26 22:31:23 2002
***************
*** 123,127 ****
error = -EPERM;
! if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto dput_and_out;
--- 123,127 ----
error = -EPERM;
! if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode))
goto dput_and_out;
***************
*** 471,475 ****
goto out_putf;
err = -EPERM;
! if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto out_putf;
if (mode == (mode_t) -1)
--- 471,475 ----
goto out_putf;
err = -EPERM;
! if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode))
goto out_putf;
if (mode == (mode_t) -1)
***************
*** 502,506 ****
error = -EPERM;
! if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto dput_and_out;
--- 502,506 ----
error = -EPERM;
! if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode))
goto dput_and_out;
***************
*** 532,536 ****
goto out;
error = -EPERM;
! if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto out;
if (user == (uid_t) -1)
--- 532,536 ----
goto out;
error = -EPERM;
! if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode))
goto out;
if (user == (uid_t) -1)
diff -rc2P linux-2.4.18/fs/proc/array.c linux-2.4.18ctx-10/fs/proc/array.c
*** linux-2.4.18/fs/proc/array.c Wed Oct 31 15:32:41 2001
--- linux-2.4.18ctx-10/fs/proc/array.c Wed Apr 3 16:41:02 2002
***************
*** 76,79 ****
--- 76,80 ----
#include <asm/io.h>
#include <asm/processor.h>
+ #include <asm/unistd.h>
/* Gcc optimizes away "strlen(x)" for constant x */
***************
*** 148,153 ****
{
int g;
!
read_lock(&tasklist_lock);
buffer += sprintf(buffer,
"State:\t%s\n"
--- 149,158 ----
{
int g;
! pid_t ppid;
read_lock(&tasklist_lock);
+ ppid = p->p_opptr->pid;
+ if (ppid != 0
+ && current->s_info != NULL
+ && current->s_info->initpid == ppid) ppid = 1;
buffer += sprintf(buffer,
"State:\t%s\n"
***************
*** 159,163 ****
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p), p->tgid,
! p->pid, p->pid ? p->p_opptr->pid : 0, 0,
p->uid, p->euid, p->suid, p->fsuid,
p->gid, p->egid, p->sgid, p->fsgid);
--- 164,168 ----
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p), p->tgid,
! p->pid, p->pid ? ppid : 0, 0,
p->uid, p->euid, p->suid, p->fsuid,
p->gid, p->egid, p->sgid, p->fsgid);
***************
*** 264,271 ****
return buffer + sprintf(buffer, "CapInh:\t%016x\n"
"CapPrm:\t%016x\n"
! "CapEff:\t%016x\n",
cap_t(p->cap_inheritable),
cap_t(p->cap_permitted),
! cap_t(p->cap_effective));
}
--- 269,278 ----
return buffer + sprintf(buffer, "CapInh:\t%016x\n"
"CapPrm:\t%016x\n"
! "CapEff:\t%016x\n"
! "CapBset:\t%016x\n",
cap_t(p->cap_inheritable),
cap_t(p->cap_permitted),
! cap_t(p->cap_effective),
! cap_t(p->cap_bset));
}
***************
*** 289,292 ****
--- 296,319 ----
buffer = task_sig(task, buffer);
buffer = task_cap(task, buffer);
+ #ifdef __NR_new_s_context
+ buffer += sprintf (buffer,"s_context: %d\n",task->s_context);
+ buffer += sprintf (buffer,"ipv4root: %08x\n",task->ipv4root);
+ buffer += sprintf (buffer,"ipv4root_bcast: %08x\n",task->ipv4root_bcast);
+ if (task->s_info != NULL){
+ buffer += sprintf (buffer,"ctxticks: %d %ld %d\n"
+ ,atomic_read(&task->s_info->ticks),task->counter
+ ,task->s_info->refcount);
+ buffer += sprintf (buffer,"ctxflags: %d\n"
+ ,task->s_info->flags);
+ buffer += sprintf (buffer,"initpid: %d\n"
+ ,task->s_info->initpid);
+ }else{
+ buffer += sprintf (buffer,"ctxticks: none\n");
+ buffer += sprintf (buffer,"ctxflags: none\n");
+ buffer += sprintf (buffer,"initpid: none\n");
+ }
+ buffer += sprintf (buffer,"__NR_new_s_context: %d\n",__NR_new_s_context);
+ buffer += sprintf (buffer,"__NR_set_ipv4root: %d rev1\n",__NR_set_ipv4root);
+ #endif
#if defined(CONFIG_ARCH_S390)
buffer = task_show_regs(task, buffer);
***************
*** 342,345 ****
--- 369,374 ----
read_lock(&tasklist_lock);
ppid = task->pid ? task->p_opptr->pid : 0;
+ if (current->s_info != NULL
+ && current->s_info->initpid == ppid) ppid = 1;
read_unlock(&tasklist_lock);
res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
diff -rc2P linux-2.4.18/fs/proc/base.c linux-2.4.18ctx-10/fs/proc/base.c
*** linux-2.4.18/fs/proc/base.c Tue Feb 26 22:22:07 2002
--- linux-2.4.18ctx-10/fs/proc/base.c Tue Feb 26 22:31:23 2002
***************
*** 973,976 ****
--- 973,982 ----
goto out;
+ if (pid != 1
+ && current->s_context != 1
+ && task->s_context != current->s_context){
+ free_task_struct(task);
+ goto out;
+ }
inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
***************
*** 983,987 ****
inode->i_fop = &proc_base_operations;
inode->i_nlink = 3;
! inode->i_flags|=S_IMMUTABLE;
dentry->d_op = &pid_base_dentry_operations;
--- 989,993 ----
inode->i_fop = &proc_base_operations;
inode->i_nlink = 3;
! inode->i_flags|=S_IMMUTABLE_FILE;
dentry->d_op = &pid_base_dentry_operations;
***************
*** 1089,1092 ****
--- 1095,1111 ----
if (!pid)
continue;
+ /* Even if the pid 1 is not part of the security context */
+ /* we show it anyway. This makes the security box */
+ /* more standard (and helps pstree do its job) */
+ /* So current process "knows" pid 1 exist anyway and can't */
+ /* send any signal either */
+
+ /* A process with security context 1 can see all processes */
+ if (pid != 1
+ && current->s_context != 1
+ && p->s_context != current->s_context) continue;
+ /* We hide the fakeinit process since we show it as process 1 */
+ if (current->s_info != NULL
+ && current->s_info->initpid == pid) continue;
#ifdef CONFIG_GRKERNSEC_ACL
if(gr_check_hidden_task(p))
continue;
diff -rc2P linux-2.4.18/fs/udf/inode.c linux-2.4.18ctx-10/fs/udf/inode.c
*** linux-2.4.18/fs/udf/inode.c Tue Feb 26 22:22:08 2002
--- linux-2.4.18ctx-10/fs/udf/inode.c Tue Feb 26 22:31:23 2002
***************
*** 864,868 ****
S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
--- 864,868 ----
S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
return;
diff -rc2P linux-2.4.18/fs/ufs/truncate.c linux-2.4.18ctx-10/fs/ufs/truncate.c
*** linux-2.4.18/fs/ufs/truncate.c Tue Feb 26 22:22:08 2002
--- linux-2.4.18ctx-10/fs/ufs/truncate.c Tue Feb 26 22:31:23 2002
***************
*** 435,439 ****
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
while (1) {
--- 435,439 ----
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
return;
while (1) {
diff -rc2P linux-2.4.18/include/asm-i386/unistd.h linux-2.4.18ctx-10/include/asm-i386/unistd.h
*** linux-2.4.18/include/asm-i386/unistd.h Tue Feb 26 22:22:08 2002
--- linux-2.4.18ctx-10/include/asm-i386/unistd.h Wed Feb 27 14:36:00 2002
***************
*** 243,246 ****
--- 243,248 ----
#define __NR_lremovexattr 236
#define __NR_fremovexattr 237
+ #define __NR_new_s_context 238
+ #define __NR_set_ipv4root 239
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
diff -rc2P linux-2.4.18/include/linux/capability.h linux-2.4.18ctx-10/include/linux/capability.h
*** linux-2.4.18/include/linux/capability.h Fri Nov 23 15:07:52 2001
--- linux-2.4.18ctx-10/include/linux/capability.h Tue Mar 19 23:24:38 2002
***************
*** 232,235 ****
--- 232,236 ----
arbitrary SCSI commands */
/* Allow setting encryption key on loopback filesystem */
+ /* Allow the selection of a security context */
#define CAP_SYS_ADMIN 21
***************
*** 279,282 ****
--- 280,287 ----
#define CAP_LEASE 28
+
+ /* Allow opening special device file */
+
+ #define CAP_OPENDEV 29
#ifdef __KERNEL__
diff -rc2P linux-2.4.18/include/linux/devpts_fs_info.h linux-2.4.18ctx-10/include/linux/devpts_fs_info.h
*** linux-2.4.18/include/linux/devpts_fs_info.h Wed Dec 31 19:00:00 1969
--- linux-2.4.18ctx-10/include/linux/devpts_fs_info.h Tue Feb 26 22:31:23 2002
***************
*** 0 ****
--- 1,4 ----
+ struct devpts_inode_info{
+ int s_context;
+ };
+
diff -rc2P linux-2.4.18/include/linux/ext2_fs.h linux-2.4.18ctx-10/include/linux/ext2_fs.h
*** linux-2.4.18/include/linux/ext2_fs.h Wed Oct 31 15:32:45 2001
--- linux-2.4.18ctx-10/include/linux/ext2_fs.h Tue Mar 19 23:25:19 2002
***************
*** 188,192 ****
#define EXT2_COMPR_FL 0x00000004 /* Compress file */
#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
! #define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
--- 188,192 ----
#define EXT2_COMPR_FL 0x00000004 /* Compress file */
#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
! #define EXT2_IMMUTABLE_FILE_FL 0x00000010 /* Immutable file */
#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
***************
*** 199,206 ****
/* End compression flags --- maybe not all used */
#define EXT2_BTREE_FL 0x00001000 /* btree format dir */
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
! #define EXT2_FL_USER_VISIBLE 0x00001FFF /* User visible flags */
! #define EXT2_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */
/*
--- 199,207 ----
/* End compression flags --- maybe not all used */
#define EXT2_BTREE_FL 0x00001000 /* btree format dir */
+ #define EXT2_IMMUTABLE_LINK_FL 0x00008000 /* Immutable link */
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
! #define EXT2_FL_USER_VISIBLE 0x00009FFF /* User visible flags */
! #define EXT2_FL_USER_MODIFIABLE 0x000080FF /* User modifiable flags */
/*
diff -rc2P linux-2.4.18/include/linux/ext3_fs.h linux-2.4.18ctx-10/include/linux/ext3_fs.h
*** linux-2.4.18/include/linux/ext3_fs.h Tue Feb 26 22:22:11 2002
--- linux-2.4.18ctx-10/include/linux/ext3_fs.h Tue Mar 19 23:28:09 2002
***************
*** 191,195 ****
#define EXT3_COMPR_FL 0x00000004 /* Compress file */
#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */
! #define EXT3_IMMUTABLE_FL 0x00000010 /* Immutable file */
#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */
#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */
--- 191,195 ----
#define EXT3_COMPR_FL 0x00000004 /* Compress file */
#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */
! #define EXT3_IMMUTABLE_FILE_FL 0x00000010 /* Immutable file */
#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */
#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */
***************
*** 204,211 ****
#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */
#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */
#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */
! #define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */
! #define EXT3_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */
/*
--- 204,212 ----
#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */
#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */
+ #define EXT3_IMMUTABLE_LINK_FL 0x00008000 /* Immutable link */
#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */
! #define EXT3_FL_USER_VISIBLE 0x0000DFFF /* User visible flags */
! #define EXT3_FL_USER_MODIFIABLE 0x000080FF /* User modifiable flags */
/*
diff -rc2P linux-2.4.18/include/linux/fs.h linux-2.4.18ctx-10/include/linux/fs.h
*** linux-2.4.18/include/linux/fs.h Tue Feb 26 22:22:11 2002
--- linux-2.4.18ctx-10/include/linux/fs.h Tue Mar 19 23:24:38 2002
***************
*** 129,139 ****
/* Inode flags - they have nothing to superblock flags now */
! #define S_SYNC 1 /* Writes are synced at once */
! #define S_NOATIME 2 /* Do not update access times */
! #define S_QUOTA 4 /* Quota initialized for file */
! #define S_APPEND 8 /* Append-only file */
! #define S_IMMUTABLE 16 /* Immutable file */
! #define S_DEAD 32 /* removed, but still open directory */
! #define S_NOQUOTA 64 /* Inode is not counted to quota */
/*
--- 129,140 ----
/* Inode flags - they have nothing to superblock flags now */
! #define S_SYNC 1 /* Writes are synced at once */
! #define S_NOATIME 2 /* Do not update access times */
! #define S_QUOTA 4 /* Quota initialized for file */
! #define S_APPEND 8 /* Append-only file */
! #define S_IMMUTABLE_FILE 16 /* Immutable file */
! #define S_DEAD 32 /* removed, but still open directory */
! #define S_NOQUOTA 64 /* Inode is not counted to quota */
! #define S_IMMUTABLE_LINK 128 /* Immutable links */
/*
***************
*** 159,163 ****
#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
! #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
#define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
#define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME)
--- 160,165 ----
#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
! #define IS_IMMUTABLE_FILE(inode) ((inode)->i_flags & S_IMMUTABLE_FILE)
! #define IS_IMMUTABLE_LINK(inode) ((((inode)->i_flags & S_IMMUTABLE_FILE) << 3) ^ ((inode)->i_flags & S_IMMUTABLE_LINK) )
#define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
#define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME)
***************
*** 317,320 ****
--- 319,323 ----
#include <linux/jffs2_fs_i.h>
#include <linux/cramfs_fs_sb.h>
+ #include <linux/devpts_fs_info.h>
/*
***************
*** 358,366 ****
* This is the inode attributes flag definitions
*/
! #define ATTR_FLAG_SYNCRONOUS 1 /* Syncronous write */
! #define ATTR_FLAG_NOATIME 2 /* Don't update atime */
! #define ATTR_FLAG_APPEND 4 /* Append-only file */
! #define ATTR_FLAG_IMMUTABLE 8 /* Immutable file */
! #define ATTR_FLAG_NODIRATIME 16 /* Don't update atime for directory */
/*
--- 361,370 ----
* This is the inode attributes flag definitions
*/
! #define ATTR_FLAG_SYNCRONOUS 1 /* Syncronous write */
! #define ATTR_FLAG_NOATIME 2 /* Don't update atime */
! #define ATTR_FLAG_APPEND 4 /* Append-only file */
! #define ATTR_FLAG_IMMUTABLE_FILE 8 /* Immutable file */
! #define ATTR_FLAG_NODIRATIME 16 /* Don't update atime for directory */
! #define ATTR_FLAG_IMMUTABLE_LINK 32 /* Immutable file */
/*
***************
*** 507,510 ****
--- 511,515 ----
struct usbdev_inode_info usbdev_i;
struct jffs2_inode_info jffs2_i;
+ struct devpts_inode_info devpts_i;
void *generic_ip;
} u;
diff -rc2P linux-2.4.18/include/linux/sched.h linux-2.4.18ctx-10/include/linux/sched.h
*** linux-2.4.18/include/linux/sched.h Sat Dec 22 22:38:45 2001
--- linux-2.4.18ctx-10/include/linux/sched.h Wed Apr 3 16:41:02 2002
***************
*** 269,272 ****
--- 269,273 ----
struct user_struct *next, **pprev;
uid_t uid;
+ int s_context;
};
***************
*** 276,279 ****
--- 277,309 ----
__user; })
+
+ /*
+ We may have a different domainname and nodename for each security
+ context. By default, a security context share the same as its
+ parent, potentially the information in system_utsname
+ */
+ #define S_CTX_INFO_LOCK 1 /* Can't request a new s_context */
+ #define S_CTX_INFO_SCHED 2 /* All process in the s_context */
+ /* Contribute to the schedular */
+ #define S_CTX_INFO_NPROC 4 /* Limit number of processes in a context */
+ #define S_CTX_INFO_PRIVATE 8 /* Noone can join this security context */
+ #define S_CTX_INFO_INIT 16 /* This process wants to become the */
+ /* logical process 1 of the security */
+ /* context */
+
+
+ struct context_info{
+ int refcount;
+ int s_context;
+ char nodename[65];
+ char domainname[65];
+ int flags; /* S_CTX_INFO_xxx */
+ atomic_t ticks; /* Number of ticks used by all process */
+ /* in the s_context */
+ int initpid; /* PID of the logical process 1 of the */
+ /* of the context */
+ };
+
+
extern struct user_struct root_user;
#define INIT_USER (&root_user)
***************
*** 400,403 ****
--- 430,440 ----
size_t sas_ss_size;
int (*notifier)(void *priv);
+ /* Field to make virtual server running in chroot more isolated */
+ int s_context; /* Process can only deal with other processes */
+ /* with the same s_context */
+ __u32 cap_bset; /* Maximum capability of this process and children */
+ __u32 ipv4root; /* Process can only bind to this iP */
+ __u32 ipv4root_bcast;
+ struct context_info *s_info;
void *notifier_data;
sigset_t *notifier_mask;
***************
*** 502,505 ****
--- 539,543 ----
alloc_lock: SPIN_LOCK_UNLOCKED, \
journal_info: NULL, \
+ cap_bset: CAP_INIT_EFF_SET, \
}
***************
*** 566,570 ****
/* per-UID process charging. */
! extern struct user_struct * alloc_uid(uid_t);
extern void free_uid(struct user_struct *);
--- 604,608 ----
/* per-UID process charging. */
! extern struct user_struct * alloc_uid(int, uid_t);
extern void free_uid(struct user_struct *);
***************
*** 927,930 ****
--- 965,973 ----
return res;
}
+
+ /* Manage the reference count of the context_info pointer */
+ void sys_release_s_info (struct task_struct *);
+ void sys_assign_s_info (struct task_struct *);
+ void sys_alloc_s_info (void);
#endif /* __KERNEL__ */
diff -rc2P linux-2.4.18/include/net/route.h linux-2.4.18ctx-10/include/net/route.h
*** linux-2.4.18/include/net/route.h Tue Feb 26 22:22:12 2002
--- linux-2.4.18ctx-10/include/net/route.h Wed Apr 3 16:45:16 2002
***************
*** 161,164 ****
--- 161,174 ----
{
int err;
+ if (current->ipv4root != 0){
+ if (src == 0){
+ src = current->ipv4root;
+ }else if (current->ipv4root != src){
+ return -EPERM;
+ }
+ if (dst == 0x0100007f && current->s_context != 0){
+ dst = current->ipv4root;
+ }
+ }
err = ip_route_output(rp, dst, src, tos, oif);
if (err || (dst && src))
diff -rc2P linux-2.4.18/include/net/sock.h linux-2.4.18ctx-10/include/net/sock.h
*** linux-2.4.18/include/net/sock.h Sat Dec 22 22:38:45 2001
--- linux-2.4.18ctx-10/include/net/sock.h Wed Apr 3 16:45:16 2002
***************
*** 526,529 ****
--- 526,530 ----
unsigned int allocation; /* Allocation mode */
int sndbuf; /* Size of send buffer in bytes */
+ __u32 bcast_addr; /* Local bcast addr, for ipv4root */
struct sock *prev;
***************
*** 669,673 ****
/* RPC layer private data */
void *user_data;
!
/* Callbacks */
void (*state_change)(struct sock *sk);
--- 670,677 ----
/* RPC layer private data */
void *user_data;
!
! /* Context of process creating this socket */
! int s_context;
!
/* Callbacks */
void (*state_change)(struct sock *sk);
diff -rc2P linux-2.4.18/include/net/tcp.h linux-2.4.18ctx-10/include/net/tcp.h
*** linux-2.4.18/include/net/tcp.h Wed Oct 10 11:58:22 2001
--- linux-2.4.18ctx-10/include/net/tcp.h Wed Apr 3 16:50:08 2002
***************
*** 191,194 ****
--- 191,195 ----
struct in6_addr v6_rcv_saddr;
#endif
+ int s_context;
};
diff -rc2P linux-2.4.18/ipc/util.c linux-2.4.18ctx-10/ipc/util.c
*** linux-2.4.18/ipc/util.c Sun Aug 12 20:37:53 2001
--- linux-2.4.18ctx-10/ipc/util.c Tue Feb 26 22:31:23 2002
***************
*** 94,97 ****
--- 94,98 ----
for (id = 0; id <= ids->max_id; id++) {
+ if (ids->entries[id].s_context != current->s_context) continue;
p = ids->entries[id].p;
if(p==NULL)
***************
*** 168,171 ****
--- 169,173 ----
spin_lock(&ids->ary);
ids->entries[id].p = new;
+ ids->entries[id].s_context = current->s_context;
return id;
}
diff -rc2P linux-2.4.18/ipc/util.h linux-2.4.18ctx-10/ipc/util.h
*** linux-2.4.18/ipc/util.h Mon Feb 19 13:18:18 2001
--- linux-2.4.18ctx-10/ipc/util.h Tue Feb 26 22:31:23 2002
***************
*** 26,29 ****
--- 26,30 ----
struct ipc_id {
struct kern_ipc_perm* p;
+ int s_context; // Context owning this ID
};
***************
*** 75,80 ****
spin_lock(&ids->ary);
out = ids->entries[lid].p;
! if(out==NULL)
spin_unlock(&ids->ary);
return out;
}
--- 76,85 ----
spin_lock(&ids->ary);
out = ids->entries[lid].p;
! if(out==NULL
! || (ids->entries[lid].s_context != current->s_context
! && current->s_context != 1)){
spin_unlock(&ids->ary);
+ out = NULL;
+ }
return out;
}
diff -rc2P linux-2.4.18/kernel/exit.c linux-2.4.18ctx-10/kernel/exit.c
*** linux-2.4.18/kernel/exit.c Tue Feb 26 22:22:12 2002
--- linux-2.4.18ctx-10/kernel/exit.c Wed Feb 27 14:45:32 2002
***************
*** 66,69 ****
--- 66,70 ----
if (current->counter >= MAX_COUNTER)
current->counter = MAX_COUNTER;
+ sys_release_s_info(p);
p->pid = 0;
free_task_struct(p);
***************
*** 159,169 ****
{
struct task_struct * p, *reaper;
read_lock(&tasklist_lock);
!
/* Next in our thread group */
reaper = next_thread(father);
if (reaper == father)
! reaper = child_reaper;
for_each_task(p) {
--- 160,178 ----
{
struct task_struct * p, *reaper;
+ struct task_struct *vchild_reaper = child_reaper;
read_lock(&tasklist_lock);
! if (father->s_info != NULL){
! pid_t initpid = father->s_info->initpid;
! if (initpid != 0
! && father->pid != initpid){
! struct task_struct *r = find_task_by_pid(initpid);
! if (r != NULL) vchild_reaper = r;
! }
! }
/* Next in our thread group */
reaper = next_thread(father);
if (reaper == father)
! reaper = vchild_reaper;
for_each_task(p) {
***************
*** 175,179 ****
/* Make sure we're not reparenting to ourselves */
if (p == reaper)
! p->p_opptr = child_reaper;
else
p->p_opptr = reaper;
--- 184,188 ----
/* Make sure we're not reparenting to ourselves */
if (p == reaper)
! p->p_opptr = vchild_reaper;
else
p->p_opptr = reaper;
diff -rc2P linux-2.4.18/kernel/fork.c linux-2.4.18ctx-10/kernel/fork.c
*** linux-2.4.18/kernel/fork.c Tue Feb 26 22:22:12 2002
--- linux-2.4.18ctx-10/kernel/fork.c Wed Feb 27 14:48:50 2002
***************
*** 589,592 ****
--- 589,596 ----
retval = -EAGAIN;
+ if (p->s_info != NULL && (p->s_info->flags & S_CTX_INFO_NPROC)!=0){
+ if (p->s_info->refcount >= p->rlim[RLIMIT_NPROC].rlim_max)
+ goto bad_fork_free;
+ }
/*
* Check if we are over our maximum process limit, but be sure to
***************
*** 598,601 ****
--- 602,607 ----
&& !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
goto bad_fork_free;
+
+ sys_assign_s_info (p);
atomic_inc(&p->user->__count);
diff -rc2P linux-2.4.18/kernel/printk.c linux-2.4.18ctx-10/kernel/printk.c
*** linux-2.4.18/kernel/printk.c Tue Feb 26 22:22:12 2002
--- linux-2.4.18ctx-10/kernel/printk.c Tue Feb 26 22:31:23 2002
***************
*** 173,176 ****
--- 173,178 ----
int error = 0;
+ if (!capable(CAP_SYS_ADMIN) && current->s_context != 0) return -EPERM;
+
switch (type) {
case 0: /* Close log */
diff -rc2P linux-2.4.18/kernel/sched.c linux-2.4.18ctx-10/kernel/sched.c
*** linux-2.4.18/kernel/sched.c Sat Dec 22 22:38:45 2001
--- linux-2.4.18ctx-10/kernel/sched.c Tue Feb 26 22:31:23 2002
***************
*** 166,170 ****
* over..
*/
! weight = p->counter;
if (!weight)
goto out;
--- 166,176 ----
* over..
*/
! if (p->s_info != NULL
! && (p->s_info->flags & S_CTX_INFO_SCHED)!=0){
! weight = atomic_read (&p->s_info->ticks)/p->s_info->refcount;
! weight = (weight+p->counter)>>1;
! }else{
! weight = p->counter;
! }
if (!weight)
goto out;
***************
*** 621,626 ****
spin_unlock_irq(&runqueue_lock);
read_lock(&tasklist_lock);
! for_each_task(p)
p->counter = (p->counter >> 1) + NICE_TO_TICKS(p->nice);
read_unlock(&tasklist_lock);
spin_lock_irq(&runqueue_lock);
--- 627,647 ----
spin_unlock_irq(&runqueue_lock);
read_lock(&tasklist_lock);
! /*
! Reset the s_info->ticks to the sum off all
! member processes p->counter
! */
! for_each_task(p){
! if (p->s_info != NULL
! && (p->s_info->flags & S_CTX_INFO_SCHED)!=0){
! atomic_set (&p->s_info->ticks,0);
! }
! }
! for_each_task(p){
p->counter = (p->counter >> 1) + NICE_TO_TICKS(p->nice);
+ if (p->s_info != NULL
+ && (p->s_info->flags & S_CTX_INFO_SCHED)!=0){
+ atomic_add (p->counter,&p->s_info->ticks);
+ }
+ }
read_unlock(&tasklist_lock);
spin_lock_irq(&runqueue_lock);
*** linux-2.4.18/kernel/signal.c Fri Nov 23 15:07:52 2001
--- linux-2.4.18ctx-10/kernel/signal.c Tue Feb 26 22:31:23 2002
***************
*** 593,597 ****
read_lock(&tasklist_lock);
for_each_task(p) {
! if (p->pgrp == pgrp && thread_group_leader(p)) {
int err = send_sig_info(sig, info, p);
if (retval)
--- 593,599 ----
read_lock(&tasklist_lock);
for_each_task(p) {
! if (p->pgrp == pgrp
! && ((long)info==1
! || p->s_context == current->s_context)) {
int err = send_sig_info(sig, info, p);
if (retval)
***************
*** 712,717 ****
p = find_task_by_pid(pid);
error = -ESRCH;
! if (p) {
#ifdef CONFIG_GRKERNSEC_ACL
if( !(gr_check_protected_task(p)) || current->pid == 1)
#endif
--- 712,718 ----
p = find_task_by_pid(pid);
error = -ESRCH;
! if (p != NULL)
#ifdef CONFIG_GRKERNSEC_ACL
+ {
if( !(gr_check_protected_task(p)) || current->pid == 1)
#endif
***************
*** 723,727 ****
p = tg;
}
! error = send_sig_info(sig, info, p);
}
}
--- 724,742 ----
p = tg;
}
! switch((unsigned long)info) {
! case 0:
! if(p->s_context == current->s_context){
! error = send_sig_info(sig, info, p);
! }
! break;
! case 1:
! error = send_sig_info(sig, info, p);
! break;
! default:
! if( info->si_code == SI_KERNEL
! || p->s_context == current->s_context){
! error = send_sig_info(sig, info, p);
! }
! break;
}
}
***************
*** 766,770 ****
if(!(gr_check_protected_task(p) || current->pid == 1))
#endif
! if (p->pid > 1 && p != current && thread_group_leader(p)) {
int err = send_sig_info(sig, info, p);
++count;
--- 766,770 ----
if(!(gr_check_protected_task(p) || current->pid == 1))
#endif
! if (p->pid > 1 && p != current && thread_group_leader(p) && p->s_context == current->s_context) {
int err = send_sig_info(sig, info, p);
++count;
***************
*** 1257,1258 ****
--- 1275,1420 ----
}
#endif /* !alpha && !__ia64__ && !defined(__mips__) */
+
+ static int set_initpid (int flags)
+ {
+ int ret = 0;
+ if ((flags & S_CTX_INFO_INIT)!=0){
+ if (current->s_info == NULL){
+ ret = -EINVAL;
+ }else if (current->s_info->initpid != 0){
+ ret = -EPERM;
+ }else{
+ current->s_info->initpid = current->tgid;
+ }
+ }
+ return ret;
+ }
+
+ static inline int switch_user_struct(int new_context)
+ {
+ struct user_struct *new_user;
+
+ new_user = alloc_uid(new_context, current->uid);
+ if (!new_user)
+ return -ENOMEM;
+
+ if (new_user != current->user) {
+ struct user_struct *old_user = current->user;
+
+ atomic_inc(&new_user->processes);
+ atomic_dec(&old_user->processes);
+ current->user = new_user;
+ free_uid(old_user);
+ }
+ return 0;
+ }
+
+ /*
+ Change to a new security context and reduce the capability
+ basic set of the current process
+ */
+ asmlinkage int
+ sys_new_s_context(int ctx, __u32 remove_cap, int flags)
+ {
+ #define MAX_S_CONTEXT 65535 /* Arbitrary limit */
+ int ret = -EPERM;
+ if (ctx == -1){
+ if (current->s_info == NULL
+ || (current->s_info->flags & S_CTX_INFO_LOCK) == 0){
+ /* Ok we allocate a new context. For now, we just increase */
+ /* it. Wrap around possible, so we loop */
+ static int alloc_ctx=1;
+ static spinlock_t alloc_ctx_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock(&alloc_ctx_lock);
+ while (1){
+ int found = 0;
+ struct task_struct *p;
+ alloc_ctx++;
+ /* The s_context 1 is special. It sess all processes */
+ if (alloc_ctx == 1){
+ alloc_ctx++;
+ }else if (alloc_ctx > MAX_S_CONTEXT){
+ // No need to grow and grow
+ alloc_ctx = 2;
+ }
+ /* Check if in use */
+ read_lock(&tasklist_lock);
+ for_each_task(p) {
+ if (p->s_context == alloc_ctx){
+ found = 1;
+ break;
+ }
+ }
+ read_unlock(&tasklist_lock);
+ if (!found) break;
+ }
+ ret = switch_user_struct(alloc_ctx);
+ if (ret == 0) {
+ current->s_context = alloc_ctx;
+ current->cap_bset &= (~remove_cap);
+ ret = alloc_ctx;
+ sys_alloc_s_info();
+ if (current->s_info != NULL) {
+ set_initpid (flags);
+ current->s_info->flags |= flags;
+ }
+ }
+ spin_unlock(&alloc_ctx_lock);
+ }
+ }else if (ctx == -2){
+ ret = set_initpid(flags);
+ if (ret == 0){
+ /* We keep the same s_context, but lower the capabilities */
+ current->cap_bset &= (~remove_cap);
+ ret = current->s_context;
+ if (current->s_info != NULL){
+ if ((flags & S_CTX_INFO_INIT)!=0){
+ current->s_info->initpid = current->tgid;
+ }
+ current->s_info->flags |= flags;
+ }
+ }
+ }else if (ctx <= 0 || ctx > MAX_S_CONTEXT){
+ ret = -EINVAL;
+ }else if (current->s_context == 0
+ && capable(CAP_SYS_ADMIN)
+ && (current->s_info == NULL
+ ||(current->s_info->flags & S_CTX_INFO_LOCK) == 0)){
+ /* The root context can become any context it wants */
+ int found = 0;
+ struct task_struct *p;
+ /* Check if in use so we reuse the same context_info */
+ read_lock(&tasklist_lock);
+ ret = ctx;
+ for_each_task(p) {
+ if (p->s_context == ctx){
+ found = 1;
+ if (p->s_info == NULL
+ || (p->s_info->flags & S_CTX_INFO_PRIVATE)==0){
+ sys_release_s_info(current);
+ sys_assign_s_info (p);
+ current->s_info = p->s_info;
+ }else{
+ ret = -EPERM;
+ }
+ break;
+ }
+ }
+ read_unlock(&tasklist_lock);
+ if (ret == ctx) {
+ ret = switch_user_struct(ctx);
+ if (ret == 0) {
+ current->s_context = ctx;
+ current->cap_bset &= (~remove_cap);
+ if (!found) {
+ sys_alloc_s_info();
+ }
+ if (current->s_info != NULL) {
+ current->s_info->flags |= flags;
+ }
+ }
+ }
+ }
+ return ret;
+ }
+
diff -rc2P linux-2.4.18/kernel/sys.c linux-2.4.18ctx-10/kernel/sys.c
*** linux-2.4.18/kernel/sys.c Tue Feb 26 22:22:12 2002
--- linux-2.4.18ctx-10/kernel/sys.c Tue Feb 26 22:31:23 2002
***************
*** 7,10 ****
--- 7,11 ----
#include <linux/module.h>
#include <linux/mm.h>
+ #include <linux/vmalloc.h>
#include <linux/utsname.h>
#include <linux/mman.h>
***************
*** 500,504 ****
* we should be checking for it. -DaveM
*/
! new_user = alloc_uid(new_ruid);
if (!new_user)
return -EAGAIN;
--- 501,505 ----
* we should be checking for it. -DaveM
*/
! new_user = alloc_uid(current->s_context, new_ruid);
if (!new_user)
return -EAGAIN;
***************
*** 1016,1022 ****
{
int errno = 0;
down_read(&uts_sem);
! if (copy_to_user(name,&system_utsname,sizeof *name))
errno = -EFAULT;
up_read(&uts_sem);
--- 1017,1032 ----
{
int errno = 0;
+ struct new_utsname tmp,*pttmp;
down_read(&uts_sem);
! if (current->s_info != NULL){
! tmp = system_utsname;
! strcpy (tmp.nodename,current->s_info->nodename);
! strcpy (tmp.domainname,current->s_info->domainname);
! pttmp = &tmp;
! }else{
! pttmp = &system_utsname;
! }
! if (copy_to_user(name,pttmp,sizeof *name))
errno = -EFAULT;
up_read(&uts_sem);
***************
*** 1024,1030 ****
--- 1034,1095 ----
}
+ /*
+ Decrease the reference count on the context_info member of a task
+ Free the struct if the reference count reach 0.
+ */
+ void sys_release_s_info (struct task_struct *p)
+ {
+ down_write (&uts_sem);
+ if (p->s_info != NULL){
+ p->s_info->refcount--;
+ if (p->s_info->refcount == 0){
+ // printk ("vfree s_info %d\n",p->pid);
+ vfree (p->s_info);
+ p->s_info = NULL;
+ }
+ }
+ up_write (&uts_sem);
+ }
+ /*
+ Increase the reference count on the context_info member of a task
+ */
+ void sys_assign_s_info (struct task_struct *p)
+ {
+ down_write (&uts_sem);
+ if (p->s_info != NULL) p->s_info->refcount++;
+ up_write (&uts_sem);
+ }
+
+ /*
+ Alloc a new s_info to the current process and release
+ the one currently owned by the current process.
+ */
+ void sys_alloc_s_info()
+ {
+ struct context_info *s_info = vmalloc(sizeof(struct context_info));
+ // printk ("new s_info %d\n",current->pid);
+ s_info->s_context = current->s_context;
+ s_info->refcount = 1;
+ atomic_set (&s_info->ticks,current->counter);
+ s_info->flags = 0;
+ s_info->initpid = 0;
+ down_read (&uts_sem);
+ if (current->s_info != NULL){
+ strcpy (s_info->nodename,current->s_info->nodename);
+ strcpy (s_info->domainname,current->s_info->domainname);
+ }else{
+ strcpy (s_info->nodename,system_utsname.nodename);
+ strcpy (s_info->domainname,system_utsname.domainname);
+ }
+ up_read (&uts_sem);
+ sys_release_s_info (current);
+ current->s_info = s_info;
+ }
+
+
asmlinkage long sys_sethostname(char *name, int len)
{
int errno;
+ char *nodename;
if (!capable(CAP_SYS_ADMIN))
***************
*** 1034,1039 ****
down_write(&uts_sem);
errno = -EFAULT;
! if (!copy_from_user(system_utsname.nodename, name, len)) {
! system_utsname.nodename[len] = 0;
errno = 0;
}
--- 1099,1106 ----
down_write(&uts_sem);
errno = -EFAULT;
! nodename = system_utsname.nodename;
! if (current->s_info) nodename = current->s_info->nodename;
! if (!copy_from_user(nodename, name, len)) {
! nodename[len] = 0;
errno = 0;
}
***************
*** 1045,1057 ****
{
int i, errno;
if (len < 0)
return -EINVAL;
down_read(&uts_sem);
! i = 1 + strlen(system_utsname.nodename);
if (i > len)
i = len;
errno = 0;
! if (copy_to_user(name, system_utsname.nodename, i))
errno = -EFAULT;
up_read(&uts_sem);
--- 1112,1127 ----
{
int i, errno;
+ char *nodename;
if (len < 0)
return -EINVAL;
down_read(&uts_sem);
! nodename = system_utsname.nodename;
! if (current->s_info != NULL) nodename = current->s_info->nodename;
! i = 1 + strlen(nodename);
if (i > len)
i = len;
errno = 0;
! if (copy_to_user(name, nodename, i))
errno = -EFAULT;
up_read(&uts_sem);
***************
*** 1268,1271 ****
--- 1268,1272 ----
{
int errno;
+ char *domainname;
if (!capable(CAP_SYS_ADMIN))
***************
*** 1073,1080 ****
down_write(&uts_sem);
errno = -EFAULT;
! if (!copy_from_user(system_utsname.domainname, name, len)) {
errno = 0;
! system_utsname.domainname[len] = 0;
}
up_write(&uts_sem);
--- 1144,1153 ----
down_write(&uts_sem);
+ domainname = system_utsname.domainname;
+ if (current->s_info) domainname = current->s_info->domainname;
errno = -EFAULT;
! if (!copy_from_user(domainname, name, len)) {
errno = 0;
! domainname[len] = 0;
}
up_write(&uts_sem);
diff -rc2P linux-2.4.18/kernel/sysctl.c linux-2.4.18ctx-10/kernel/sysctl.c
*** linux-2.4.18/kernel/sysctl.c Sat Dec 22 22:38:45 2001
--- linux-2.4.18ctx-10/kernel/sysctl.c Tue Feb 26 22:31:23 2002
***************
*** 380,383 ****
--- 380,384 ----
static int test_perm(int mode, int op)
{
+ if (!capable(CAP_SYS_ADMIN)) mode &= ~(0222);
if (!current->euid)
mode >>= 6;
***************
*** 794,798 ****
--- 795,810 ----
{
int r;
+ ctl_table tmp;
+ /* HACK for per s_context hostname and domainname */
+ if (current->s_info != NULL){
+ tmp = *table;
+ table = &tmp;
+ if (table->data == (void*)&system_utsname.nodename){
+ tmp.data = ¤t->s_info->nodename;
+ }else if (table->data == (void*)&system_utsname.domainname){
+ tmp.data = ¤t->s_info->domainname;
+ }
+ }
if (!write) {
down_read(&uts_sem);
diff -rc2P linux-2.4.18/kernel/timer.c linux-2.4.18ctx-10/kernel/timer.c
*** linux-2.4.18/kernel/timer.c Wed Oct 10 11:58:22 2001
--- linux-2.4.18ctx-10/kernel/timer.c Tue Feb 26 22:31:23 2002
***************
*** 584,587 ****
--- 584,592 ----
update_one_process(p, user_tick, system, cpu);
if (p->pid) {
+ if (p->s_info != NULL
+ && (p->s_info->flags & S_CTX_INFO_SCHED)!=0){
+ // atomic_sub (ticks*p->s_info->refcount, &p->s_info->ticks);
+ atomic_dec (&p->s_info->ticks);
+ }
if (--p->counter <= 0) {
p->counter = 0;
***************
*** 720,723 ****
--- 725,733 ----
{
/* This is SMP safe - current->pid doesn't change */
+ if (current->s_info != NULL
+ && current->s_info->initpid == current->tgid){
+ /* We are faking process 1 for this security context */
+ return 1;
+ }
return current->tgid;
}
***************
*** 765,768 ****
--- 775,784 ----
#endif
break;
+ }
+ if (pid != 0
+ && current->s_info != NULL
+ && current->s_info->initpid == pid){
+ /* We are faking process 1 for this security context */
+ pid = 1;
}
return pid;
diff -rc2P linux-2.4.18/kernel/user.c linux-2.4.18ctx-10/kernel/user.c
*** linux-2.4.18/kernel/user.c Wed Nov 29 01:43:39 2000
--- linux-2.4.18ctx-10/kernel/user.c Tue Feb 26 22:31:23 2002
***************
*** 7,10 ****
--- 7,23 ----
* processes, files etc the user has claimed, in order to be
* able to have per-user limits for system resources.
+ *
+ * For the vserver project, the key is extended from UID to (SC,UID),
+ * with SC being the security context ID. Thus, each security context
+ * has independant per-UID resource usage counters.
+ *
+ * As a consequence, even if two UIDs are the same, the 'struct user *'
+ * in their task_struct could be different. I don't think any code cares.
+ *
+ * (vserver modifications done Sun Jan 13 08:48:45 CET 2002 by bof_at_bof.de)
+ *
+ * NOTE: For now, the hash function is unmodified: the same uid in several
+ * security contexts, will always sit on the same hash chain. This could
+ * be changed easily.
*/
***************
*** 57,61 ****
}
! static inline struct user_struct *uid_hash_find(uid_t uid, struct user_struct **hashent)
{
struct user_struct *next;
--- 70,74 ----
}
! static inline struct user_struct *uid_hash_find(int s_context, uid_t uid, struct user_struct **hashent)
{
struct user_struct *next;
***************
*** 66,70 ****
if (next) {
next = up->next;
! if (up->uid != uid)
continue;
atomic_inc(&up->__count);
--- 79,83 ----
if (next) {
next = up->next;
! if (up->uid != uid || up->s_context != s_context)
continue;
atomic_inc(&up->__count);
***************
*** 83,87 ****
}
! struct user_struct * alloc_uid(uid_t uid)
{
struct user_struct **hashent = uidhashentry(uid);
--- 96,100 ----
}
! struct user_struct * alloc_uid(int s_context, uid_t uid)
{
struct user_struct **hashent = uidhashentry(uid);
***************
*** 89,93 ****
spin_lock(&uidhash_lock);
! up = uid_hash_find(uid, hashent);
spin_unlock(&uidhash_lock);
--- 102,106 ----
spin_lock(&uidhash_lock);
! up = uid_hash_find(s_context, uid, hashent);
spin_unlock(&uidhash_lock);
***************
*** 99,102 ****
--- 112,116 ----
return NULL;
new->uid = uid;
+ new->s_context = s_context;
atomic_set(&new->__count, 1);
atomic_set(&new->processes, 0);
***************
*** 108,112 ****
*/
spin_lock(&uidhash_lock);
! up = uid_hash_find(uid, hashent);
if (up) {
kmem_cache_free(uid_cachep, new);
--- 122,126 ----
*/
spin_lock(&uidhash_lock);
! up = uid_hash_find(s_context, uid, hashent);
if (up) {
kmem_cache_free(uid_cachep, new);
diff -rc2P linux-2.4.18/net/ipv4/af_inet.c linux-2.4.18ctx-10/net/ipv4/af_inet.c
*** linux-2.4.18/net/ipv4/af_inet.c Sat Dec 22 22:38:46 2001
--- linux-2.4.18ctx-10/net/ipv4/af_inet.c Mon Mar 18 12:26:22 2002
***************
*** 394,397 ****
--- 394,399 ----
sk->protinfo.af_inet.mc_list = NULL;
+ sk->s_context = current->s_context;
+
#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet_sock_nr);
***************
*** 478,481 ****
--- 480,485 ----
int chk_addr_ret;
int err;
+ __u32 s_addr;
+ __u32 bcast_addr = 0xffffffffl;
/* If the socket has its own bind function then use it. (RAW) */
***************
*** 486,490 ****
return -EINVAL;
! chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
/* Not specified by any standard per-se, however it breaks too
--- 490,507 ----
return -EINVAL;
! s_addr = addr->sin_addr.s_addr;
! if (current->ipv4root != 0){
! // printk ("ipv4root0 %08lx %08x\n",current->ipv4root,s_addr);
! if (s_addr == 0){
! s_addr = current->ipv4root;
! bcast_addr = current->ipv4root_bcast;
! }else if (s_addr == 0x0100007f){
! s_addr = current->ipv4root;
! }else if (s_addr != current->ipv4root){
! return -EADDRNOTAVAIL;
! }
! }
! chk_addr_ret = inet_addr_type(s_addr);
! // printk ("ipv4root %08lx %08x %d\n",current->ipv4root,s_addr,chk_addr_ret);
/* Not specified by any standard per-se, however it breaks too
***************
*** 497,501 ****
if (sysctl_ip_nonlocal_bind == 0 &&
sk->protinfo.af_inet.freebind == 0 &&
! addr->sin_addr.s_addr != INADDR_ANY &&
chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST &&
--- 514,518 ----
if (sysctl_ip_nonlocal_bind == 0 &&
sk->protinfo.af_inet.freebind == 0 &&
! s_addr != INADDR_ANY &&
chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST &&
***************
*** 522,526 ****
goto out;
! sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr;
if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
sk->saddr = 0; /* Use device */
--- 539,544 ----
goto out;
! sk->rcv_saddr = sk->saddr = s_addr;
! sk->bcast_addr = bcast_addr;
if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
sk->saddr = 0; /* Use device */
diff -rc2P linux-2.4.18/net/ipv4/devinet.c linux-2.4.18ctx-10/net/ipv4/devinet.c
*** linux-2.4.18/net/ipv4/devinet.c Sat Dec 22 22:38:46 2001
--- linux-2.4.18ctx-10/net/ipv4/devinet.c Tue Feb 26 22:31:23 2002
***************
*** 559,563 ****
goto done;
}
!
switch(cmd) {
case SIOCGIFADDR: /* Get interface address */
--- 559,569 ----
goto done;
}
! if (ifa != NULL
! && current->s_context != 0
! && current->ipv4root != 0
! && current->ipv4root != ifa->ifa_local){
! ret = -EADDRNOTAVAIL;
! goto done;
! }
switch(cmd) {
case SIOCGIFADDR: /* Get interface address */
***************
*** 692,695 ****
--- 698,705 ----
for ( ; ifa; ifa = ifa->ifa_next) {
+ // We do not show other IP devices to vservers
+ if (current->s_context != 0
+ && current->ipv4root != 0
+ && current->ipv4root != ifa->ifa_local) continue;
if (!buf) {
done += sizeof(ifr);
***************
*** 909,912 ****
--- 919,925 ----
for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
ifa = ifa->ifa_next, ip_idx++) {
+ if (current->s_context != 0
+ && current->ipv4root != 0
+ && current->ipv4root != ifa->ifa_local) continue;
if (ip_idx < s_ip_idx)
continue;
diff -rc2P linux-2.4.18/net/ipv4/raw.c linux-2.4.18ctx-10/net/ipv4/raw.c
*** linux-2.4.18/net/ipv4/raw.c Tue Jul 10 19:11:43 2001
--- linux-2.4.18ctx-10/net/ipv4/raw.c Tue Feb 26 22:31:23 2002
***************
*** 658,662 ****
for (sk = raw_v4_htable[i]; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET)
continue;
pos += 128;
--- 658,662 ----
for (sk = raw_v4_htable[i]; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET || (current->s_context != 1 && sk->s_context != current->s_context))
continue;
pos += 128;
diff -rc2P linux-2.4.18/net/ipv4/tcp_ipv4.c linux-2.4.18ctx-10/net/ipv4/tcp_ipv4.c
*** linux-2.4.18/net/ipv4/tcp_ipv4.c Tue Feb 26 22:22:12 2002
--- linux-2.4.18ctx-10/net/ipv4/tcp_ipv4.c Tue Feb 26 22:31:23 2002
***************
*** 2074,2077 ****
--- 2074,2080 ----
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ if (current->s_context != 1 && sk->s_context != current->s_context)
+ continue;
+
if (!TCP_INET_FAMILY(sk->family))
goto skip_listen;
***************
*** 2127,2131 ****
read_lock(&head->lock);
for(sk = head->chain; sk; sk = sk->next, num++) {
! if (!TCP_INET_FAMILY(sk->family))
continue;
pos += TMPSZ;
--- 2130,2134 ----
read_lock(&head->lock);
for(sk = head->chain; sk; sk = sk->next, num++) {
! if (!TCP_INET_FAMILY(sk->family) || (current->s_context != 1 && sk->s_context != current->s_context))
continue;
pos += TMPSZ;
***************
*** 2142,2146 ****
tw != NULL;
tw = (struct tcp_tw_bucket *)tw->next, num++) {
! if (!TCP_INET_FAMILY(tw->family))
continue;
pos += TMPSZ;
--- 2145,2149 ----
tw != NULL;
tw = (struct tcp_tw_bucket *)tw->next, num++) {
! if (!TCP_INET_FAMILY(tw->family) || (current->s_context != 1 && tw->s_context != current->s_context))
continue;
pos += TMPSZ;
diff -rc2P linux-2.4.18/net/ipv4/tcp_minisocks.c linux-2.4.18ctx-10/net/ipv4/tcp_minisocks.c
*** linux-2.4.18/net/ipv4/tcp_minisocks.c Wed Oct 10 11:58:23 2001
--- linux-2.4.18ctx-10/net/ipv4/tcp_minisocks.c Tue Feb 26 22:31:23 2002
***************
*** 382,385 ****
--- 382,387 ----
tw->pprev_death = NULL;
+ tw->s_context = sk->s_context;
+
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
if(tw->family == PF_INET6) {
diff -rc2P linux-2.4.18/net/ipv4/udp.c linux-2.4.18ctx-10/net/ipv4/udp.c
*** linux-2.4.18/net/ipv4/udp.c Tue Feb 26 22:22:12 2002
--- linux-2.4.18ctx-10/net/ipv4/udp.c Mon Mar 18 13:26:18 2002
***************
*** 273,277 ****
(s->daddr && s->daddr!=rmt_addr) ||
(s->dport != rmt_port && s->dport != 0) ||
! (s->rcv_saddr && s->rcv_saddr != loc_addr) ||
(s->bound_dev_if && s->bound_dev_if != dif))
continue;
--- 273,277 ----
(s->daddr && s->daddr!=rmt_addr) ||
(s->dport != rmt_port && s->dport != 0) ||
! (s->rcv_saddr && s->rcv_saddr != loc_addr && s->bcast_addr != loc_addr) ||
(s->bound_dev_if && s->bound_dev_if != dif))
continue;
***************
*** 988,992 ****
for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET)
continue;
pos += 128;
--- 988,992 ----
for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET || (current->s_context != 1 && sk->s_context != current->s_context))
continue;
pos += 128;
diff -rc2P linux-2.4.18/net/ipv6/raw.c linux-2.4.18ctx-10/net/ipv6/raw.c
*** linux-2.4.18/net/ipv6/raw.c Thu Sep 20 17:12:56 2001
--- linux-2.4.18ctx-10/net/ipv6/raw.c Tue Feb 26 22:31:23 2002
***************
*** 798,802 ****
for (sk = raw_v6_htable[i]; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET6)
continue;
pos += LINE_LEN+1;
--- 798,802 ----
for (sk = raw_v6_htable[i]; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET6 || (current->s_context != 1 && sk->s_context != current->s_context))
continue;
pos += LINE_LEN+1;
diff -rc2P linux-2.4.18/net/ipv6/tcp_ipv6.c linux-2.4.18ctx-10/net/ipv6/tcp_ipv6.c
*** linux-2.4.18/net/ipv6/tcp_ipv6.c Tue Feb 26 22:22:13 2002
--- linux-2.4.18ctx-10/net/ipv6/tcp_ipv6.c Tue Feb 26 22:31:23 2002
***************
*** 2007,2011 ****
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
! if (sk->family != PF_INET6)
continue;
pos += LINE_LEN+1;
--- 2007,2011 ----
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
! if (sk->family != PF_INET6 || (current->s_context != 1 && sk->s_context != current->s_context))
continue;
pos += LINE_LEN+1;
***************
*** 2057,2061 ****
read_lock(&head->lock);
for(sk = head->chain; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET6)
continue;
pos += LINE_LEN+1;
--- 2057,2061 ----
read_lock(&head->lock);
for(sk = head->chain; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET6 || (current->s_context != 1 && sk->s_context != current->s_context))
continue;
pos += LINE_LEN+1;
***************
*** 2072,2076 ****
tw != NULL;
tw = (struct tcp_tw_bucket *)tw->next, num++) {
! if (tw->family != PF_INET6)
continue;
pos += LINE_LEN+1;
--- 2072,2076 ----
tw != NULL;
tw = (struct tcp_tw_bucket *)tw->next, num++) {
! if (tw->family != PF_INET6 || (current->s_context != 1 && tw->s_context != current->s_context))
continue;
pos += LINE_LEN+1;
diff -rc2P linux-2.4.18/net/ipv6/udp.c linux-2.4.18ctx-10/net/ipv6/udp.c
*** linux-2.4.18/net/ipv6/udp.c Fri Sep 7 14:01:21 2001
--- linux-2.4.18ctx-10/net/ipv6/udp.c Tue Feb 26 22:31:23 2002
***************
*** 953,957 ****
for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET6)
continue;
pos += LINE_LEN+1;
--- 953,957 ----
for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
! if (sk->family != PF_INET6 || (current->s_context != 1 && sk->s_context != current->s_context))
continue;
pos += LINE_LEN+1;
diff -rc2P linux-2.4.18/net/socket.c linux-2.4.18ctx-10/net/socket.c
*** linux-2.4.18/net/socket.c Sat Dec 22 22:38:47 2001
--- linux-2.4.18ctx-10/net/socket.c Wed Apr 3 16:41:02 2002
***************
*** 1764,1765 ****
--- 1764,1778 ----
return len;
}
+
+ asmlinkage int sys_set_ipv4root (__u32 ip, __u32 bcast)
+ {
+ int ret = -EPERM;
+ if (current->ipv4root == 0
+ || capable(CAP_SYS_ADMIN)){
+ ret = 0;
+ current->ipv4root = ip;
+ current->ipv4root_bcast = bcast;
+ }
+ return ret;
+ }
+
diff -rc2P linux-2.4.18/net/unix/af_unix.c linux-2.4.18ctx-10/net/unix/af_unix.c
*** linux-2.4.18/net/unix/af_unix.c Tue Feb 26 22:22:13 2002
--- linux-2.4.18ctx-10/net/unix/af_unix.c Tue Feb 26 22:31:23 2002
***************
*** 480,483 ****
--- 480,485 ----
sk->write_space = unix_write_space;
+ sk->s_context = current->s_context;
+
sk->max_ack_backlog = sysctl_unix_max_dgram_qlen;
sk->destruct = unix_sock_destructor;
***************
*** 1751,1754 ****
--- 1753,1759 ----
forall_unix_sockets (i,s)
{
+ if (current->s_context != 1 && s->s_context != current->s_context)
+ continue;
+
unix_state_rlock(s);