+ /*
+ 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 && current->s_context != 0) return -EACCES;
if (mask & MAY_WRITE) {
/*
diff -rc2P linux-2.4.17ctx-5/fs/proc/array.c linux-2.4.17ctx-6/fs/proc/array.c
*** linux-2.4.17ctx-5/fs/proc/array.c Sun Jan 13 21:17:40 2002
--- linux-2.4.17ctx-6/fs/proc/array.c Sun Jan 27 15:23:51 2002
***************
*** 148,153 ****
{
int g;
!
read_lock(&tasklist_lock);
buffer += sprintf(buffer,
"State:\t%s\n"
--- 148,156 ----
{
int g;
! pid_t ppid;
read_lock(&tasklist_lock);
+ ppid = p->p_opptr->pid;
+ if (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);
--- 162,166 ----
"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);
***************
*** 299,305 ****
--- 302,311 ----
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");
}
#if defined(CONFIG_ARCH_S390)
***************
*** 356,359 ****
--- 362,367 ----
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.17ctx-5/fs/proc/base.c linux-2.4.17ctx-6/fs/proc/base.c
*** linux-2.4.17ctx-5/fs/proc/base.c Sun Jan 13 21:17:40 2002
--- linux-2.4.17ctx-6/fs/proc/base.c Sun Jan 27 15:01:44 2002
***************
*** 1028,1031 ****
--- 1028,1034 ----
&& 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;
if (--index >= 0)
continue;
diff -rc2P linux-2.4.17ctx-5/include/linux/devpts_fs_info.h linux-2.4.17ctx-6/include/linux/devpts_fs_info.h
*** linux-2.4.17ctx-5/include/linux/devpts_fs_info.h Wed Dec 31 19:00:00 1969
--- linux-2.4.17ctx-6/include/linux/devpts_fs_info.h Thu Jan 24 23:28:00 2002
***************
*** 0 ****
--- 1,4 ----
+ struct devpts_inode_info{
+ int s_context;
+ };
+
diff -rc2P linux-2.4.17ctx-5/include/linux/fs.h linux-2.4.17ctx-6/include/linux/fs.h
*** linux-2.4.17ctx-5/include/linux/fs.h Sun Jan 13 21:17:40 2002
--- linux-2.4.17ctx-6/include/linux/fs.h Thu Jan 24 23:27:35 2002
***************
*** 318,321 ****
--- 318,322 ----
#include <linux/jffs2_fs_i.h>
#include <linux/cramfs_fs_sb.h>
+ #include <linux/devpts_fs_info.h>
/*
***************
*** 509,512 ****
--- 510,514 ----
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.17ctx-5/include/linux/sched.h linux-2.4.17ctx-6/include/linux/sched.h
*** linux-2.4.17ctx-5/include/linux/sched.h Sun Jan 13 21:17:40 2002
--- linux-2.4.17ctx-6/include/linux/sched.h Thu Jan 24 23:30:50 2002
***************
*** 287,290 ****
--- 287,293 ----
#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 */
***************
*** 297,300 ****
--- 300,305 ----
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 */
};
diff -rc2P linux-2.4.17ctx-5/ipc/util.c linux-2.4.17ctx-6/ipc/util.c
*** linux-2.4.17ctx-5/ipc/util.c Sun Aug 12 20:37:53 2001
--- linux-2.4.17ctx-6/ipc/util.c Thu Jan 24 16:28:58 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.17ctx-5/ipc/util.h linux-2.4.17ctx-6/ipc/util.h
*** linux-2.4.17ctx-5/ipc/util.h Mon Feb 19 13:18:18 2001
--- linux-2.4.17ctx-6/ipc/util.h Sun Jan 27 00:51:19 2002
***************
*** 26,29 ****
--- 26,30 ----
struct ipc_id {
struct kern_ipc_perm* p;
+ int s_context; // Context owning this ID
};
+ 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;
+ }
+
/*
Change to a new security context and reduce the capability
***************
*** 1302,1305 ****
--- 1335,1339 ----
sys_alloc_s_info();
if (current->s_info != NULL){
+ set_initpid (flags);
current->s_info->flags |= flags;
}
***************
*** 1307,1315 ****
}
}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){
--- 1341,1355 ----
}
}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){
diff -rc2P linux-2.4.17ctx-5/kernel/sys.c linux-2.4.17ctx-6/kernel/sys.c
*** linux-2.4.17ctx-5/kernel/sys.c Sun Jan 13 21:17:41 2002
--- linux-2.4.17ctx-6/kernel/sys.c Wed Jan 9 14:09:08 2002
***************
*** 1073,1076 ****
--- 1073,1077 ----
atomic_set (&s_info->ticks,current->counter);
s_info->flags = 0;
+ s_info->initpid = 0;
down_read (&uts_sem);
if (current->s_info != NULL){
diff -rc2P linux-2.4.17ctx-5/kernel/timer.c linux-2.4.17ctx-6/kernel/timer.c
*** linux-2.4.17ctx-5/kernel/timer.c Sun Jan 13 21:17:41 2002
--- linux-2.4.17ctx-6/kernel/timer.c Sun Jan 27 14:49:24 2002
***************
*** 725,728 ****
--- 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;
}
***************
*** 770,773 ****
--- 775,783 ----
#endif
break;
+ }
+ if (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.17ctx-5/net/ipv4/devinet.c linux-2.4.17ctx-6/net/ipv4/devinet.c
*** linux-2.4.17ctx-5/net/ipv4/devinet.c Sat Dec 22 22:38:46 2001
--- linux-2.4.17ctx-6/net/ipv4/devinet.c Thu Jan 24 12:06:09 2002
***************
*** 559,563 ****
goto done;
}
!
switch(cmd) {
case SIOCGIFADDR: /* Get interface address */
--- 559,568 ----
goto done;
}
! if (ifa != NULL
! && current->ipv4root != 0
! && current->ipv4root != ifa->ifa_local){
! ret = -EADDRNOTAVAIL;
! goto done;
! }
switch(cmd) {
case SIOCGIFADDR: /* Get interface address */
***************
*** 692,695 ****
--- 697,703 ----
for ( ; ifa; ifa = ifa->ifa_next) {
+ // We do not show other IP devices to vservers
+ if (current->ipv4root != 0
+ && current->ipv4root != ifa->ifa_local) continue;
if (!buf) {
done += sizeof(ifr);