Re: [vserver] GR security & CTX

About this list Date view Thread view Subject view Author view Attachment view

From: Stefan van der Eijk (stefan_at_eijk.nu)
Date: Mon May 06 2002 - 16:45:03 EDT


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 = &current->s_info->nodename;
+ }else if (table->data == (void*)&system_utsname.domainname){
+ tmp.data = &current->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);
  


About this list Date view Thread view Subject view Author view Attachment view

This archive was generated by hypermail 2.1.4 : Mon Aug 19 2002 - 12:01:01 EDT