diff -rc2P linux-2.4.16/Makefile linux-2.4.16-ctx-5/Makefile
*** linux-2.4.16/Makefile       Mon Nov 26 11:00:15 2001
--- linux-2.4.16-ctx-5/Makefile Fri Nov 30 17:11:52 2001
***************
*** 2,6 ****
 PATCHLEVEL = 4
 SUBLEVEL = 16
! EXTRAVERSION =

 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
--- 2,6 ----
 PATCHLEVEL = 4
 SUBLEVEL = 16
! EXTRAVERSION =ctx-5

 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff -rc2P linux-2.4.16/arch/i386/kernel/entry.S linux-2.4.16-ctx-5/arch/i386/kernel/entry.S
*** linux-2.4.16/arch/i386/kernel/entry.S       Fri Nov 23 15:07:20 2001
--- linux-2.4.16-ctx-5/arch/i386/kernel/entry.S Mon Nov 26 11:10:42 2001
***************
*** 623,626 ****
--- 623,628 ----
       .long SYMBOL_NAME(sys_gettid)
       .long SYMBOL_NAME(sys_readahead)        /* 225 */
+       .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.16/arch/i386/kernel/ptrace.c linux-2.4.16-ctx-5/arch/i386/kernel/ptrace.c
*** linux-2.4.16/arch/i386/kernel/ptrace.c      Fri Nov 23 15:07:41 2001
--- linux-2.4.16-ctx-5/arch/i386/kernel/ptrace.c        Mon Nov 26 11:10:42 2001
***************
*** 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.16/fs/exec.c linux-2.4.16-ctx-5/fs/exec.c
*** linux-2.4.16/fs/exec.c      Fri Nov 23 15:07:30 2001
--- linux-2.4.16-ctx-5/fs/exec.c        Mon Nov 26 11:10:42 2001
***************
*** 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.16/fs/ext2/ialloc.c linux-2.4.16-ctx-5/fs/ext2/ialloc.c
*** linux-2.4.16/fs/ext2/ialloc.c       Fri Nov 23 15:07:49 2001
--- linux-2.4.16-ctx-5/fs/ext2/ialloc.c Mon Nov 26 11:10:42 2001
***************
*** 390,394 ****
       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)
--- 390,394 ----
       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.16/fs/ext2/inode.c linux-2.4.16-ctx-5/fs/ext2/inode.c
*** linux-2.4.16/fs/ext2/inode.c        Fri Nov 23 15:07:49 2001
--- linux-2.4.16-ctx-5/fs/ext2/inode.c  Mon Nov 26 11:10:42 2001
***************
*** 802,806 ****
           S_ISLNK(inode->i_mode)))
               return;
!       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
               return;

--- 802,806 ----
           S_ISLNK(inode->i_mode)))
               return;
!       if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
               return;

***************
*** 1008,1014 ****
               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) {
--- 1008,1018 ----
               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.16/fs/ext2/ioctl.c linux-2.4.16-ctx-5/fs/ext2/ioctl.c
*** linux-2.4.16/fs/ext2/ioctl.c        Wed Sep 27 16:41:33 2000
--- linux-2.4.16-ctx-5/fs/ext2/ioctl.c  Mon Nov 26 11:10:42 2001
***************
*** 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.16/fs/ext3/ialloc.c linux-2.4.16-ctx-5/fs/ext3/ialloc.c
*** linux-2.4.16/fs/ext3/ialloc.c       Fri Nov 23 15:07:49 2001
--- linux-2.4.16-ctx-5/fs/ext3/ialloc.c Sun Dec 16 20:03:06 2001
***************
*** 487,491 ****
       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;
--- 487,491 ----
       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.16/fs/ext3/inode.c linux-2.4.16-ctx-5/fs/ext3/inode.c
*** linux-2.4.16/fs/ext3/inode.c        Fri Nov 23 15:07:49 2001
--- linux-2.4.16-ctx-5/fs/ext3/inode.c  Mon Nov 26 11:10:42 2001
***************
*** 1824,1828 ****
           S_ISLNK(inode->i_mode)))
               return;
!       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
               return;

--- 1824,1828 ----
           S_ISLNK(inode->i_mode)))
               return;
!       if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
               return;

***************
*** 2128,2134 ****
               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) {
--- 2128,2137 ----
               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.16/fs/ext3/ioctl.c linux-2.4.16-ctx-5/fs/ext3/ioctl.c
*** linux-2.4.16/fs/ext3/ioctl.c        Fri Nov 23 15:07:49 2001
--- linux-2.4.16-ctx-5/fs/ext3/ioctl.c  Mon Nov 26 11:10:43 2001
***************
*** 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.16/fs/fat/file.c linux-2.4.16-ctx-5/fs/fat/file.c
*** linux-2.4.16/fs/fat/file.c  Sun Aug 12 13:56:56 2001
--- linux-2.4.16-ctx-5/fs/fat/file.c    Mon Nov 26 11:10:43 2001
***************
*** 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.16/fs/fat/inode.c linux-2.4.16-ctx-5/fs/fat/inode.c
*** linux-2.4.16/fs/fat/inode.c Fri Nov 23 15:07:49 2001
--- linux-2.4.16-ctx-5/fs/fat/inode.c   Mon Nov 26 11:10:43 2001
***************
*** 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.16/fs/hpfs/file.c linux-2.4.16-ctx-5/fs/hpfs/file.c
*** linux-2.4.16/fs/hpfs/file.c Sun Aug 12 20:37:53 2001
--- linux-2.4.16-ctx-5/fs/hpfs/file.c   Mon Nov 26 11:10:43 2001
***************
*** 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.16/fs/intermezzo/vfs.c linux-2.4.16-ctx-5/fs/intermezzo/vfs.c
*** linux-2.4.16/fs/intermezzo/vfs.c    Fri Nov 23 15:07:49 2001
--- linux-2.4.16-ctx-5/fs/intermezzo/vfs.c      Wed Dec  5 13:33:45 2001
***************
*** 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;
***************
*** 610,614 ****
          */
         error = -EPERM;
!         if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
                 EXIT;
                 goto exit_lock;
--- 610,614 ----
          */
         error = -EPERM;
!         if (IS_APPEND(inode) || IS_IMMUTABLE_LINK(inode)) {
                 EXIT;
                 goto exit_lock;
***************
*** 2202,2206 ****
         }

!         if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
                 EXIT;
                 return -EPERM;
--- 2202,2206 ----
         }

!         if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode)) {
                 EXIT;
                 return -EPERM;
diff -rc2P linux-2.4.16/fs/namei.c linux-2.4.16-ctx-5/fs/namei.c
*** linux-2.4.16/fs/namei.c     Wed Oct 31 15:32:41 2001
--- linux-2.4.16-ctx-5/fs/namei.c       Mon Nov 26 11:10:43 2001
***************
*** 163,167 ****
                * Nobody gets write access to an immutable file.
                */
!               if (IS_IMMUTABLE(inode))
                       return -EACCES;
       }
--- 163,167 ----
                * Nobody gets write access to an immutable file.
                */
!               if (IS_IMMUTABLE_FILE(inode))
                       return -EACCES;
       }
***************
*** 878,883 ****
       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) {
--- 878,882 ----
       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) {
***************
*** 1595,1599 ****
        */
       error = -EPERM;
!       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
               goto exit_lock;
       if (!dir->i_op || !dir->i_op->link)
--- 1594,1598 ----
        */
       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.16/fs/nfsd/vfs.c linux-2.4.16-ctx-5/fs/nfsd/vfs.c
*** linux-2.4.16/fs/nfsd/vfs.c  Wed Oct 10 11:58:19 2001
--- linux-2.4.16-ctx-5/fs/nfsd/vfs.c    Mon Nov 26 11:10:43 2001
***************
*** 1481,1485 ****
               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"  : "",
--- 1481,1485 ----
               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"  : "",
***************
*** 1491,1495 ****
               (acc & MAY_OWNER_OVERRIDE)? " owneroverride" : "",
               inode->i_mode,
!               IS_IMMUTABLE(inode)?    " immut" : "",
               IS_APPEND(inode)?       " append" : "",
               IS_RDONLY(inode)?       " ro" : "");
--- 1491,1496 ----
               (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" : "");
***************
*** 1506,1510 ****
                       if (EX_RDONLY(exp) || IS_RDONLY(inode))
                               return nfserr_rofs;
!                       if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
                               return nfserr_perm;
               }
--- 1507,1511 ----
                       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.16/fs/open.c linux-2.4.16-ctx-5/fs/open.c
*** linux-2.4.16/fs/open.c      Wed Oct 31 15:32:41 2001
--- linux-2.4.16-ctx-5/fs/open.c        Mon Nov 26 11:10:43 2001
***************
*** 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.16/fs/proc/array.c linux-2.4.16-ctx-5/fs/proc/array.c
*** linux-2.4.16/fs/proc/array.c        Wed Oct 31 15:32:41 2001
--- linux-2.4.16-ctx-5/fs/proc/array.c  Mon Nov 26 11:10:43 2001
***************
*** 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));
 }

--- 264,273 ----
     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 ****
--- 291,306 ----
       buffer = task_sig(task, buffer);
       buffer = task_cap(task, buffer);
+       buffer += sprintf (buffer,"s_context: %d\n",task->s_context);
+       buffer += sprintf (buffer,"ipv4root: %08lx\n",task->ipv4root);
+       if (task->s_info != NULL){
+               buffer += sprintf (buffer,"ctxticks: %d %d %d\n"
+                       ,atomic_read(&task->s_info->ticks),task->counter
+                       ,task->s_info->refcount);
+               buffer += sprintf (buffer,"ctxflags: %d\n"
+                       ,task->s_info->flags);
+       }else{
+               buffer += sprintf (buffer,"ctxticks: none\n");
+               buffer += sprintf (buffer,"ctxflags: none\n");
+       }
 #if defined(CONFIG_ARCH_S390)
       buffer = task_show_regs(task, buffer);
diff -rc2P linux-2.4.16/fs/proc/base.c linux-2.4.16-ctx-5/fs/proc/base.c
*** linux-2.4.16/fs/proc/base.c Tue Oct 16 09:33:55 2001
--- linux-2.4.16-ctx-5/fs/proc/base.c   Mon Nov 26 11:10:43 2001
***************
*** 967,970 ****
--- 967,975 ----
               goto out;

+       if (pid != 1
+               && current->s_context != 1
+               && task->s_context != current->s_context){
+               goto out;
+       }
       inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);

***************
*** 977,981 ****
       inode->i_fop = &proc_base_operations;
       inode->i_nlink = 3;
!       inode->i_flags|=S_IMMUTABLE;

       dentry->d_op = &pid_base_dentry_operations;
--- 982,986 ----
       inode->i_fop = &proc_base_operations;
       inode->i_nlink = 3;
!       inode->i_flags|=S_IMMUTABLE_FILE;

       dentry->d_op = &pid_base_dentry_operations;
***************
*** 1013,1016 ****
--- 1018,1031 ----
               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;
               if (--index >= 0)
                       continue;
diff -rc2P linux-2.4.16/fs/udf/inode.c linux-2.4.16-ctx-5/fs/udf/inode.c
*** linux-2.4.16/fs/udf/inode.c Wed Oct 31 15:32:42 2001
--- linux-2.4.16-ctx-5/fs/udf/inode.c   Mon Nov 26 11:10:43 2001
***************
*** 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.16/fs/ufs/truncate.c linux-2.4.16-ctx-5/fs/ufs/truncate.c
*** linux-2.4.16/fs/ufs/truncate.c      Fri Nov 23 15:07:50 2001
--- linux-2.4.16-ctx-5/fs/ufs/truncate.c        Mon Nov 26 11:10:43 2001
***************
*** 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.16/include/asm-i386/unistd.h linux-2.4.16-ctx-5/include/asm-i386/unistd.h
*** linux-2.4.16/include/asm-i386/unistd.h      Wed Oct 31 15:32:43 2001
--- linux-2.4.16-ctx-5/include/asm-i386/unistd.h        Mon Nov 26 11:10:43 2001
***************
*** 231,234 ****
--- 231,236 ----
 #define __NR_gettid           224
 #define __NR_readahead                225
+ #define __NR_new_s_context      226
+ #define __NR_set_ipv4root       227

 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
diff -rc2P linux-2.4.16/include/linux/capability.h linux-2.4.16-ctx-5/include/linux/capability.h
*** linux-2.4.16/include/linux/capability.h     Fri Nov 23 15:07:52 2001
--- linux-2.4.16-ctx-5/include/linux/capability.h       Wed Dec  5 13:39:21 2001
***************
*** 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.16/include/linux/ext2_fs.h linux-2.4.16-ctx-5/include/linux/ext2_fs.h
*** linux-2.4.16/include/linux/ext2_fs.h        Wed Oct 31 15:32:45 2001
--- linux-2.4.16-ctx-5/include/linux/ext2_fs.h  Wed Dec  5 13:40:07 2001
***************
*** 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.16/include/linux/ext3_fs.h linux-2.4.16-ctx-5/include/linux/ext3_fs.h
*** linux-2.4.16/include/linux/ext3_fs.h        Fri Nov 23 15:07:52 2001
--- linux-2.4.16-ctx-5/include/linux/ext3_fs.h  Sun Dec 16 23:07:32 2001
***************
*** 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.16/include/linux/fs.h linux-2.4.16-ctx-5/include/linux/fs.h
*** linux-2.4.16/include/linux/fs.h     Mon Nov 26 11:00:16 2001
--- linux-2.4.16-ctx-5/include/linux/fs.h       Wed Dec  5 13:39:21 2001
***************
*** 128,138 ****
 /* 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 */

 /*
--- 128,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_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 */

 /*
***************
*** 158,162 ****
 #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)
--- 159,164 ----
 #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)
***************
*** 357,365 ****
  * 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 */

 /*
--- 359,368 ----
  * 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 */

 /*
diff -rc2P linux-2.4.16/include/linux/sched.h linux-2.4.16-ctx-5/include/linux/sched.h
*** linux-2.4.16/include/linux/sched.h  Fri Nov 23 15:07:52 2001
--- linux-2.4.16-ctx-5/include/linux/sched.h    Wed Dec  5 13:39:22 2001
***************
*** 276,279 ****
--- 276,303 ----
       __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 */
+
+
+ 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 */
+ };
+
+
 extern struct user_struct root_user;
 #define INIT_USER (&root_user)
***************
*** 400,403 ****
--- 424,433 ----
       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 */
+       unsigned long ipv4root; /* Process can only bind to this iP */
+       struct context_info *s_info;
       void *notifier_data;
       sigset_t *notifier_mask;
***************
*** 501,504 ****
--- 531,535 ----
     alloc_lock:               SPIN_LOCK_UNLOCKED,                             \
     journal_info:     NULL,                                           \
+     cap_bset:         CAP_INIT_EFF_SET,                               \
 }

***************
*** 926,929 ****
--- 957,965 ----
       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.16/include/net/route.h linux-2.4.16-ctx-5/include/net/route.h
*** linux-2.4.16/include/net/route.h    Fri Nov 23 15:07:32 2001
--- linux-2.4.16-ctx-5/include/net/route.h      Wed Dec  5 13:41:20 2001
***************
*** 160,163 ****
--- 160,170 ----
 {
       int err;
+       if (current->ipv4root != 0){
+               if (src == 0){
+                       src = current->ipv4root;
+               }else if (current->ipv4root != src){
+                       return -EPERM;
+               }
+       }
       err = ip_route_output(rp, dst, src, tos, oif);
       if (err || (dst && src))
diff -rc2P linux-2.4.16/kernel/exit.c linux-2.4.16-ctx-5/kernel/exit.c
*** linux-2.4.16/kernel/exit.c  Fri Nov 23 15:07:52 2001
--- linux-2.4.16-ctx-5/kernel/exit.c    Mon Nov 26 11:10:43 2001
***************
*** 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);
diff -rc2P linux-2.4.16/kernel/fork.c linux-2.4.16-ctx-5/kernel/fork.c
*** linux-2.4.16/kernel/fork.c  Fri Nov 23 15:07:52 2001
--- linux-2.4.16-ctx-5/kernel/fork.c    Mon Nov 26 11:10:43 2001
***************
*** 586,591 ****
--- 586,597 ----

       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;
+       }
       if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur)
               goto bad_fork_free;
+
+       sys_assign_s_info (p);

       atomic_inc(&p->user->__count);
diff -rc2P linux-2.4.16/kernel/sched.c linux-2.4.16-ctx-5/kernel/sched.c
*** linux-2.4.16/kernel/sched.c Fri Nov 23 15:07:52 2001
--- linux-2.4.16-ctx-5/kernel/sched.c   Mon Nov 26 11:10:43 2001
***************
*** 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;
***************
*** 606,611 ****
               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);
--- 612,632 ----
               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);
diff -rc2P linux-2.4.16/kernel/signal.c linux-2.4.16-ctx-5/kernel/signal.c
*** linux-2.4.16/kernel/signal.c        Fri Nov 23 15:07:52 2001
--- linux-2.4.16-ctx-5/kernel/signal.c  Mon Nov 26 11:10:43 2001
***************
*** 593,597 ****
               read_lock(&tasklist_lock);
               for_each_task(p) {
!                       if (p->pgrp == pgrp) {
                               int err = send_sig_info(sig, info, p);
                               if (retval)
--- 593,597 ----
               read_lock(&tasklist_lock);
               for_each_task(p) {
!                       if (p->pgrp == pgrp && p->s_context == current->s_context) {
                               int err = send_sig_info(sig, info, p);
                               if (retval)
***************
*** 640,644 ****
       p = find_task_by_pid(pid);
       error = -ESRCH;
!       if (p)
               error = send_sig_info(sig, info, p);
       read_unlock(&tasklist_lock);
--- 640,644 ----
       p = find_task_by_pid(pid);
       error = -ESRCH;
!       if (p && p->s_context == current->s_context)
               error = send_sig_info(sig, info, p);
       read_unlock(&tasklist_lock);
***************
*** 664,668 ****
               read_lock(&tasklist_lock);
               for_each_task(p) {
!                       if (p->pid > 1 && p != current) {
                               int err = send_sig_info(sig, info, p);
                               ++count;
--- 664,668 ----
               read_lock(&tasklist_lock);
               for_each_task(p) {
!                       if (p->pid > 1 && p != current && p->s_context == current->s_context) {
                               int err = send_sig_info(sig, info, p);
                               ++count;
***************
*** 1257,1258 ****
--- 1257,1355 ----
 }
 #endif /* !alpha && !__ia64__ && !defined(__mips__) */
+
+ /*
+       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;
+                       }
+                       current->s_context = alloc_ctx;
+                       current->cap_bset &= (~remove_cap);
+                       ret = alloc_ctx;
+                       sys_alloc_s_info();
+                       if (current->s_info != NULL){
+                               current->s_info->flags |= flags;
+                       }
+                       spin_unlock(&alloc_ctx_lock);
+               }
+       }else if (ctx == -2){
+               /* We keep the same s_context, but lower the capabilities */
+               current->cap_bset &= (~remove_cap);
+               ret = current->s_context;
+               if (current->s_info != NULL){
+                       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){
+                       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.16/kernel/sys.c linux-2.4.16-ctx-5/kernel/sys.c
*** linux-2.4.16/kernel/sys.c   Tue Sep 18 17:10:43 2001
--- linux-2.4.16-ctx-5/kernel/sys.c     Fri Nov 30 17:12:44 2001
***************
*** 7,10 ****
--- 7,11 ----
 #include <linux/module.h>
 #include <linux/mm.h>
+ #include <linux/vmalloc.h>
 #include <linux/utsname.h>
 #include <linux/mman.h>
***************
*** 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,1094 ----
 }

+ /*
+       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;
+       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;
       }
--- 1098,1105 ----
       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);
--- 1111,1126 ----
 {
       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);
***************
*** 1066,1069 ****
--- 1135,1139 ----
 {
       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);
--- 1143,1152 ----

       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.16/kernel/sysctl.c linux-2.4.16-ctx-5/kernel/sysctl.c
*** linux-2.4.16/kernel/sysctl.c        Mon Nov 26 11:00:16 2001
--- linux-2.4.16-ctx-5/kernel/sysctl.c  Mon Nov 26 11:10:43 2001
***************
*** 379,382 ****
--- 379,383 ----
 static int test_perm(int mode, int op)
 {
+       if (!capable(CAP_SYS_ADMIN)) mode &= ~(0222);
       if (!current->euid)
               mode >>= 6;
***************
*** 793,797 ****
--- 794,809 ----
 {
       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.16/kernel/timer.c linux-2.4.16-ctx-5/kernel/timer.c
*** linux-2.4.16/kernel/timer.c Wed Oct 10 11:58:22 2001
--- linux-2.4.16-ctx-5/kernel/timer.c   Mon Nov 26 11:10:43 2001
***************
*** 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;
diff -rc2P linux-2.4.16/net/ipv4/af_inet.c linux-2.4.16-ctx-5/net/ipv4/af_inet.c
*** linux-2.4.16/net/ipv4/af_inet.c     Fri Nov 23 15:07:32 2001
--- linux-2.4.16-ctx-5/net/ipv4/af_inet.c       Mon Nov 26 11:10:43 2001
***************
*** 478,481 ****
--- 478,482 ----
       int chk_addr_ret;
       int err;
+       __u32 s_addr;

       /* 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
--- 487,501 ----
               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;
!               }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 &&
--- 508,512 ----
       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 */
--- 533,537 ----
               goto out;

!       sk->rcv_saddr = sk->saddr = s_addr;
       if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
               sk->saddr = 0;  /* Use device */
diff -rc2P linux-2.4.16/net/socket.c linux-2.4.16-ctx-5/net/socket.c
*** linux-2.4.16/net/socket.c   Wed Oct 31 15:32:46 2001
--- linux-2.4.16-ctx-5/net/socket.c     Mon Nov 26 11:10:43 2001
***************
*** 1766,1767 ****
--- 1766,1779 ----
       return len;
 }
+
+ asmlinkage int sys_set_ipv4root (unsigned long ip)
+ {
+       int ret = -EPERM;
+       if (current->ipv4root == 0
+               || capable(CAP_SYS_ADMIN)){
+               ret = 0;
+               current->ipv4root = ip;
+       }
+       return ret;
+ }
+