diff -rc2P linux-2.4.13/Makefile linux-2.4.13-ctx-4/Makefile
*** linux-2.4.13/Makefile Wed Oct 31 15:32:24 2001
--- linux-2.4.13-ctx-4/Makefile Fri Nov 16 14:35:23 2001
***************
*** 2,6 ****
PATCHLEVEL = 4
SUBLEVEL = 13
! EXTRAVERSION =
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
--- 2,6 ----
PATCHLEVEL = 4
SUBLEVEL = 13
! EXTRAVERSION =ctx-4
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff -rc2P linux-2.4.13/arch/i386/kernel/entry.S linux-2.4.13-ctx-4/arch/i386/kernel/entry.S
*** linux-2.4.13/arch/i386/kernel/entry.S Wed Oct 31 15:32:24 2001
--- linux-2.4.13-ctx-4/arch/i386/kernel/entry.S Wed Oct 31 16:11:22 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.13/arch/i386/kernel/ptrace.c linux-2.4.13-ctx-4/arch/i386/kernel/ptrace.c
*** linux-2.4.13/arch/i386/kernel/ptrace.c Tue Sep 18 20:04:23 2001
--- linux-2.4.13-ctx-4/arch/i386/kernel/ptrace.c Wed Oct 31 16:05:00 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.13/fs/exec.c linux-2.4.13-ctx-4/fs/exec.c
*** linux-2.4.13/fs/exec.c Tue Sep 18 16:39:32 2001
--- linux-2.4.13-ctx-4/fs/exec.c Wed Oct 31 16:05:00 2001
***************
*** 685,689 ****
int do_unlock = 0;
! new_permitted = cap_intersect(bprm->cap_permitted, cap_bset);
working = cap_intersect(bprm->cap_inheritable,
current->cap_inheritable);
--- 685,689 ----
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.13/fs/ext2/ialloc.c linux-2.4.13-ctx-4/fs/ext2/ialloc.c
*** linux-2.4.13/fs/ext2/ialloc.c Wed Oct 10 11:58:19 2001
--- linux-2.4.13-ctx-4/fs/ext2/ialloc.c Mon Nov 5 14:54:21 2001
***************
*** 439,443 ****
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_faddr = 0;
inode->u.ext2_i.i_frag_no = 0;
--- 439,443 ----
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_faddr = 0;
inode->u.ext2_i.i_frag_no = 0;
diff -rc2P linux-2.4.13/fs/ext2/inode.c linux-2.4.13-ctx-4/fs/ext2/inode.c
*** linux-2.4.13/fs/ext2/inode.c Wed Oct 31 15:32:41 2001
--- linux-2.4.13-ctx-4/fs/ext2/inode.c Mon Nov 5 14:54:21 2001
***************
*** 797,801 ****
S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
--- 797,801 ----
S_ISLNK(inode->i_mode)))
return;
! if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
return;
***************
*** 1003,1009 ****
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) {
--- 1003,1013 ----
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.13/fs/ext2/ioctl.c linux-2.4.13-ctx-4/fs/ext2/ioctl.c
*** linux-2.4.13/fs/ext2/ioctl.c Wed Sep 27 16:41:33 2000
--- linux-2.4.13-ctx-4/fs/ext2/ioctl.c Mon Nov 5 14:54:21 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.13/fs/fat/file.c linux-2.4.13-ctx-4/fs/fat/file.c
*** linux-2.4.13/fs/fat/file.c Sun Aug 12 13:56:56 2001
--- linux-2.4.13-ctx-4/fs/fat/file.c Mon Nov 5 14:54:21 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.13/fs/fat/inode.c linux-2.4.13-ctx-4/fs/fat/inode.c
*** linux-2.4.13/fs/fat/inode.c Wed Oct 31 15:32:41 2001
--- linux-2.4.13-ctx-4/fs/fat/inode.c Mon Nov 5 14:54:21 2001
***************
*** 946,950 ****
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 ... */
--- 946,950 ----
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.13/fs/hpfs/file.c linux-2.4.13-ctx-4/fs/hpfs/file.c
*** linux-2.4.13/fs/hpfs/file.c Sun Aug 12 20:37:53 2001
--- linux-2.4.13-ctx-4/fs/hpfs/file.c Mon Nov 5 14:54:21 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.13/fs/namei.c linux-2.4.13-ctx-4/fs/namei.c
*** linux-2.4.13/fs/namei.c Wed Oct 31 15:32:41 2001
--- linux-2.4.13-ctx-4/fs/namei.c Mon Nov 5 14:54:21 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.13/fs/nfsd/vfs.c linux-2.4.13-ctx-4/fs/nfsd/vfs.c
*** linux-2.4.13/fs/nfsd/vfs.c Wed Oct 10 11:58:19 2001
--- linux-2.4.13-ctx-4/fs/nfsd/vfs.c Mon Nov 5 14:54:21 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.13/fs/open.c linux-2.4.13-ctx-4/fs/open.c
*** linux-2.4.13/fs/open.c Wed Oct 31 15:32:41 2001
--- linux-2.4.13-ctx-4/fs/open.c Mon Nov 5 15:07:36 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.13/fs/proc/array.c linux-2.4.13-ctx-4/fs/proc/array.c
*** linux-2.4.13/fs/proc/array.c Wed Oct 31 15:32:41 2001
--- linux-2.4.13-ctx-4/fs/proc/array.c Wed Oct 31 16:05:00 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.13/fs/proc/base.c linux-2.4.13-ctx-4/fs/proc/base.c
*** linux-2.4.13/fs/proc/base.c Tue Oct 16 09:33:55 2001
--- linux-2.4.13-ctx-4/fs/proc/base.c Wed Nov 14 12:04:44 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.13/fs/udf/inode.c linux-2.4.13-ctx-4/fs/udf/inode.c
*** linux-2.4.13/fs/udf/inode.c Wed Oct 31 15:32:42 2001
--- linux-2.4.13-ctx-4/fs/udf/inode.c Mon Nov 5 14:54:21 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.13/fs/ufs/truncate.c linux-2.4.13-ctx-4/fs/ufs/truncate.c
*** linux-2.4.13/fs/ufs/truncate.c Mon Sep 10 12:06:10 2001
--- linux-2.4.13-ctx-4/fs/ufs/truncate.c Mon Nov 5 14:54:21 2001
***************
*** 443,447 ****
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) {
--- 443,447 ----
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.13/include/asm-i386/unistd.h linux-2.4.13-ctx-4/include/asm-i386/unistd.h
*** linux-2.4.13/include/asm-i386/unistd.h Wed Oct 31 15:32:43 2001
--- linux-2.4.13-ctx-4/include/asm-i386/unistd.h Wed Oct 31 16:08:10 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.13/include/linux/capability.h linux-2.4.13-ctx-4/include/linux/capability.h
*** linux-2.4.13/include/linux/capability.h Sun Sep 23 13:31:02 2001
--- linux-2.4.13-ctx-4/include/linux/capability.h Thu Nov 8 00:42:42 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
***************
*** 277,280 ****
--- 278,285 ----
#define CAP_LEASE 28
+
+ /* Allow opening special device file */
+
+ #define CAP_OPENDEV 29
#ifdef __KERNEL__
diff -rc2P linux-2.4.13/include/linux/ext2_fs.h linux-2.4.13-ctx-4/include/linux/ext2_fs.h
*** linux-2.4.13/include/linux/ext2_fs.h Wed Oct 31 15:32:45 2001
--- linux-2.4.13-ctx-4/include/linux/ext2_fs.h Thu Nov 8 00:43:17 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.13/include/linux/fs.h linux-2.4.13-ctx-4/include/linux/fs.h
*** linux-2.4.13/include/linux/fs.h Wed Oct 31 15:32:45 2001
--- linux-2.4.13-ctx-4/include/linux/fs.h Thu Nov 8 00:42:42 2001
***************
*** 127,137 ****
/* 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 */
/*
--- 127,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_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 */
/*
***************
*** 157,161 ****
#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)
--- 158,163 ----
#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)
***************
*** 354,362 ****
* 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 */
/*
--- 356,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_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.13/include/linux/sched.h linux-2.4.13-ctx-4/include/linux/sched.h
*** linux-2.4.13/include/linux/sched.h Tue Oct 16 09:33:55 2001
--- linux-2.4.13-ctx-4/include/linux/sched.h Fri Nov 16 14:36:27 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 ----
/* Protection of (de-)allocation: mm, files, fs, tty */
spinlock_t alloc_lock;
+ /* 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;
};
***************
*** 486,490 ****
pending: { NULL, &tsk.pending.head, {{0}}}, \
blocked: {{0}}, \
! alloc_lock: SPIN_LOCK_UNLOCKED \
}
--- 516,521 ----
pending: { NULL, &tsk.pending.head, {{0}}}, \
blocked: {{0}}, \
! alloc_lock: SPIN_LOCK_UNLOCKED, \
! cap_bset: CAP_INIT_EFF_SET, \
}
***************
*** 899,902 ****
--- 930,938 ----
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.13/include/net/route.h linux-2.4.13-ctx-4/include/net/route.h
*** linux-2.4.13/include/net/route.h Wed Oct 31 15:32:45 2001
--- linux-2.4.13-ctx-4/include/net/route.h Fri Nov 16 14:50:01 2001
***************
*** 165,168 ****
--- 165,175 ----
{
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.13/kernel/exit.c linux-2.4.13-ctx-4/kernel/exit.c
*** linux-2.4.13/kernel/exit.c Wed Oct 31 15:32:45 2001
--- linux-2.4.13-ctx-4/kernel/exit.c Wed Oct 31 16:05:00 2001
***************
*** 65,68 ****
--- 65,69 ----
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.13/kernel/fork.c linux-2.4.13-ctx-4/kernel/fork.c
*** linux-2.4.13/kernel/fork.c Tue Sep 18 00:46:04 2001
--- linux-2.4.13-ctx-4/kernel/fork.c Wed Nov 14 12:49:45 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.13/kernel/sched.c linux-2.4.13-ctx-4/kernel/sched.c
*** linux-2.4.13/kernel/sched.c Wed Oct 31 15:32:46 2001
--- linux-2.4.13-ctx-4/kernel/sched.c Wed Oct 31 16:05:00 2001
***************
*** 165,169 ****
* over..
*/
! weight = p->counter;
if (!weight)
goto out;
--- 165,175 ----
* 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;
***************
*** 687,692 ****
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);
--- 693,713 ----
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.13/kernel/signal.c linux-2.4.13-ctx-4/kernel/signal.c
*** linux-2.4.13/kernel/signal.c Mon Sep 17 19:40:01 2001
--- linux-2.4.13-ctx-4/kernel/signal.c Fri Nov 16 20:31:46 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.13/kernel/sys.c linux-2.4.13-ctx-4/kernel/sys.c
*** linux-2.4.13/kernel/sys.c Tue Sep 18 17:10:43 2001
--- linux-2.4.13-ctx-4/kernel/sys.c Wed Oct 31 16:05:00 2001
***************
*** 1016,1022 ****
{
int errno = 0;
down_read(&uts_sem);
! if (copy_to_user(name,&system_utsname,sizeof *name))
errno = -EFAULT;
up_read(&uts_sem);
--- 1016,1031 ----
{
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 ****
--- 1033,1093 ----
}
+ /*
+ 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;
}
--- 1097,1104 ----
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);
--- 1110,1125 ----
{
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 ****
--- 1134,1138 ----
{
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);
--- 1142,1151 ----
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.13/kernel/sysctl.c linux-2.4.13-ctx-4/kernel/sysctl.c
*** linux-2.4.13/kernel/sysctl.c Wed Oct 10 11:58:22 2001
--- linux-2.4.13-ctx-4/kernel/sysctl.c Wed Oct 31 16:05:00 2001
***************
*** 375,378 ****
--- 375,379 ----
static int test_perm(int mode, int op)
{
+ if (!capable(CAP_SYS_ADMIN)) mode &= ~(0222);
if (!current->euid)
mode >>= 6;
***************
*** 789,793 ****
--- 790,805 ----
{
int r;
+ ctl_table tmp;
+ /* HACK for per s_context hostname and domainname */
+ if (current->s_info != NULL){
+ tmp = *table;
+ table = &tmp;
+ if (table->data == (void*)&system_utsname.nodename){
+ tmp.data = ¤t->s_info->nodename;
+ }else if (table->data == (void*)&system_utsname.domainname){
+ tmp.data = ¤t->s_info->domainname;
+ }
+ }
if (!write) {
down_read(&uts_sem);
diff -rc2P linux-2.4.13/kernel/timer.c linux-2.4.13-ctx-4/kernel/timer.c
*** linux-2.4.13/kernel/timer.c Wed Oct 10 11:58:22 2001
--- linux-2.4.13-ctx-4/kernel/timer.c Wed Nov 14 12:08:22 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.13/net/ipv4/af_inet.c linux-2.4.13-ctx-4/net/ipv4/af_inet.c
*** linux-2.4.13/net/ipv4/af_inet.c Tue Aug 7 11:30:50 2001
--- linux-2.4.13-ctx-4/net/ipv4/af_inet.c Wed Oct 31 16:05:00 2001
***************
*** 474,477 ****
--- 474,478 ----
int chk_addr_ret;
int err;
+ __u32 s_addr;
/* If the socket has its own bind function then use it. (RAW) */
***************
*** 482,486 ****
return -EINVAL;
! chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
/* Not specified by any standard per-se, however it breaks too
--- 483,497 ----
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
***************
*** 493,497 ****
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 &&
--- 504,508 ----
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 &&
***************
*** 518,522 ****
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 */
--- 529,533 ----
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.13/net/socket.c linux-2.4.13-ctx-4/net/socket.c
*** linux-2.4.13/net/socket.c Wed Oct 31 15:32:46 2001
--- linux-2.4.13-ctx-4/net/socket.c Wed Oct 31 16:05:00 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;
+ }
+