diff -NurpP --minimal linux-2.4.23-vs1.3.0/Makefile linux-2.4.23-vs1.3.1/Makefile --- linux-2.4.23-vs1.3.0/Makefile Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/Makefile Thu Dec 25 22:24:05 2003 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 23 -EXTRAVERSION = -vs1.3.0 +EXTRAVERSION = -vs1.3.1 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/alpha/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/alpha/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/alpha/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/alpha/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -273,7 +273,7 @@ sys_ptrace(long request, long pid, long if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out_notsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/i386/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/i386/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/i386/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/i386/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -170,7 +170,7 @@ asmlinkage int sys_ptrace(long request, if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/ia64/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/ia64/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/ia64/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/ia64/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -1267,7 +1267,7 @@ sys_ptrace (long request, pid_t pid, uns get_task_struct(child); } read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; if (pid == 1) /* no messing around with init! */ diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/m68k/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/m68k/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/m68k/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/m68k/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -122,7 +122,7 @@ asmlinkage int sys_ptrace(long request, if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/mips/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/mips/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/mips/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/mips/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -67,7 +67,7 @@ asmlinkage int sys_ptrace(long request, if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/mips64/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/mips64/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/mips64/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/mips64/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -311,7 +311,7 @@ asmlinkage int sys_ptrace(long request, if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/parisc/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/parisc/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/parisc/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/parisc/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -113,7 +113,7 @@ long sys_ptrace(long request, pid_t pid, if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; if (pid == 1) /* no messing around with init! */ diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/ppc/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/ppc/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/ppc/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/ppc/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -188,7 +188,7 @@ int sys_ptrace(long request, long pid, l if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/ppc64/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/ppc64/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/ppc64/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/ppc64/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -115,7 +115,7 @@ int sys_ptrace(long request, long pid, l if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/s390/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/s390/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/s390/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/s390/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -239,7 +239,7 @@ asmlinkage int sys_ptrace(long request, if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; if (pid == 1) /* you may not mess with init */ diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/s390x/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/s390x/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/s390x/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/s390x/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -448,7 +448,7 @@ asmlinkage int sys_ptrace(long request, if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; if (pid == 1) /* you may not mess with init */ diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/sparc64/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/sparc64/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/sparc64/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/sparc64/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -156,7 +156,7 @@ asmlinkage void do_ptrace(struct pt_regs get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check_id(child->vx_id, VX_WATCH|VX_SAME)) { + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) { pt_error_return(regs, ESRCH); goto out; } diff -NurpP --minimal linux-2.4.23-vs1.3.0/arch/x86_64/kernel/ptrace.c linux-2.4.23-vs1.3.1/arch/x86_64/kernel/ptrace.c --- linux-2.4.23-vs1.3.0/arch/x86_64/kernel/ptrace.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/arch/x86_64/kernel/ptrace.c Thu Dec 25 22:24:05 2003 @@ -194,7 +194,7 @@ asmlinkage long sys_ptrace(long request, if (child) get_task_struct(child); read_unlock(&tasklist_lock); - if (!child || !vx_check(child->vx_info, VX_WATCH|VX_IDENT)) + if (!child || !vx_check(child->vx_id, VX_WATCH|VX_IDENT)) goto out; ret = -EPERM; diff -NurpP --minimal linux-2.4.23-vs1.3.0/fs/devpts/inode.c linux-2.4.23-vs1.3.1/fs/devpts/inode.c --- linux-2.4.23-vs1.3.0/fs/devpts/inode.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/fs/devpts/inode.c Thu Dec 25 22:24:05 2003 @@ -184,7 +184,7 @@ static DECLARE_FSTYPE(devpts_fs_type, "d static int devpts_tty_permission(struct inode *inode, int mask) { int ret = -EACCES; - if (vx_check_id(inode->u.devpts_i.xid, VX_SAME)) + if (vx_check(inode->u.devpts_i.xid, VX_IDENT)) ret = vfs_permission(inode, mask); return ret; } diff -NurpP --minimal linux-2.4.23-vs1.3.0/fs/devpts/root.c linux-2.4.23-vs1.3.1/fs/devpts/root.c --- linux-2.4.23-vs1.3.0/fs/devpts/root.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/fs/devpts/root.c Thu Dec 25 22:24:05 2003 @@ -67,7 +67,7 @@ static int devpts_root_readdir(struct fi int ptynr = nr - 2; struct inode *inode = sbi->inodes[ptynr]; - if (!inode || !vx_check_id(inode->u.devpts_i.xid, VX_WATCH|VX_SAME)) + if (!inode || !vx_check(inode->u.devpts_i.xid, VX_WATCH|VX_IDENT)) goto skip; genptsname(numbuf, ptynr); if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_CHR) < 0 ) @@ -132,7 +132,7 @@ static struct dentry *devpts_root_lookup return NULL; inode = sbi->inodes[entry]; - if (inode && vx_check_id(inode->u.devpts_i.xid, VX_SAME)) + if (inode && vx_check(inode->u.devpts_i.xid, VX_IDENT)) atomic_inc(&inode->i_count); else inode = NULL; diff -NurpP --minimal linux-2.4.23-vs1.3.0/fs/proc/array.c linux-2.4.23-vs1.3.1/fs/proc/array.c --- linux-2.4.23-vs1.3.0/fs/proc/array.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/fs/proc/array.c Thu Dec 25 22:24:05 2003 @@ -286,6 +286,7 @@ int proc_pid_status(struct task_struct * { char * orig = buffer; struct mm_struct *mm; + struct vx_info *vxi; buffer = task_name(task, buffer); buffer = task_state(task, buffer); @@ -300,22 +301,26 @@ int proc_pid_status(struct task_struct * } buffer = task_sig(task, buffer); buffer = task_cap(task, buffer); - if (task->vx_info) { + + vxi = task_get_vx_info(task); + if (vxi) { buffer += sprintf (buffer,"s_context: %d\n", vx_task_id(task)); buffer += sprintf (buffer,"ctxticks: %d %ld %d\n" - ,atomic_read(&task->vx_info->limit.ticks) + ,atomic_read(&vxi->limit.ticks) ,task->counter - ,atomic_read(&task->vx_info->vx_refcount)); + ,atomic_read(&vxi->vx_refcount)); buffer += sprintf (buffer,"ctxflags: %d\n" - ,task->vx_info->vx_flags); + ,vxi->vx_flags); buffer += sprintf (buffer,"initpid: %d\n" - ,task->vx_info->vx_initpid); + ,vxi->vx_initpid); } else { buffer += sprintf (buffer,"s_context: %d\n", vx_task_id(task)); buffer += sprintf (buffer,"ctxticks: none\n"); buffer += sprintf (buffer,"ctxflags: none\n"); buffer += sprintf (buffer,"initpid: none\n"); } + put_vx_info(vxi); + if (task->ip_info) { int i; @@ -329,7 +334,7 @@ int proc_pid_status(struct task_struct * buffer += sprintf (buffer,"ipv4root_bcast: %08x\n" ,task->ip_info->v4_bcast); buffer += sprintf (buffer,"ipv4root_refcnt: %d\n" - ,atomic_read(&task->ip_info->refcount)); + ,atomic_read(&task->ip_info->ip_refcount)); } else { buffer += sprintf (buffer,"ipv4root: 0\n"); buffer += sprintf (buffer,"ipv4root_bcast: 0\n"); diff -NurpP --minimal linux-2.4.23-vs1.3.0/fs/proc/base.c linux-2.4.23-vs1.3.1/fs/proc/base.c --- linux-2.4.23-vs1.3.0/fs/proc/base.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/fs/proc/base.c Thu Dec 25 22:24:05 2003 @@ -1079,7 +1079,7 @@ struct dentry *proc_pid_lookup(struct in if (!task) goto out; - if (pid != 1 && !vx_check(task->vx_info, VX_WATCH|VX_IDENT)) { + if (pid != 1 && !vx_check(task->vx_id, VX_WATCH|VX_IDENT)) { free_task_struct(task); goto out; } @@ -1136,7 +1136,7 @@ static int get_pid_list(int index, unsig /* send any signal either */ /* A process with security context 1 can see all processes */ - if (pid != 1 && !vx_check(p->vx_info, VX_WATCH|VX_IDENT)) + if (pid != 1 && !vx_check(p->vx_id, VX_WATCH|VX_IDENT)) continue; /* We hide the fakeinit process since we show it as process 1 */ if (current->vx_info && current->vx_info->vx_initpid == pid) diff -NurpP --minimal linux-2.4.23-vs1.3.0/fs/proc/generic.c linux-2.4.23-vs1.3.1/fs/proc/generic.c --- linux-2.4.23-vs1.3.0/fs/proc/generic.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/fs/proc/generic.c Thu Dec 25 22:24:05 2003 @@ -332,7 +332,7 @@ int proc_readdir(struct file * filp, } do { - if (de->vx_flags && !vx_check_id(de->xid, de->vx_flags)) + if (de->vx_flags && !vx_check(de->xid, de->vx_flags)) goto skip; if (filldir(dirent, de->name, de->namelen, filp->f_pos, de->low_ino, de->mode >> 12) < 0) diff -NurpP --minimal linux-2.4.23-vs1.3.0/fs/proc/virtual.c linux-2.4.23-vs1.3.1/fs/proc/virtual.c --- linux-2.4.23-vs1.3.0/fs/proc/virtual.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/fs/proc/virtual.c Thu Dec 25 22:24:05 2003 @@ -87,7 +87,7 @@ static int vx_proc_permission(struct ino { dprintk("vx_proc_permission(%p) = #%d,%04x\n", inode, inode->i_xid, inode->u.proc_i.vx_flags); - if (vx_check_id(inode->i_xid, inode->u.proc_i.vx_flags)) + if (vx_check(inode->i_xid, inode->u.proc_i.vx_flags)) return 0; dprintk("vx_proc_permission(%p) #%d != #%d\n", inode, inode->i_xid, vx_current_id()); @@ -108,7 +108,7 @@ int vx_proc_create(struct vx_info *info) snprintf(name, sizeof(name)-1, "%d", info->vx_id); entry = create_proc_entry(name, S_IFDIR|S_IXUGO, proc_virtual); - entry->vx_flags = VX_ADMIN|VX_WATCH|VX_SAME; + entry->vx_flags = VX_ADMIN|VX_WATCH|VX_IDENT; entry->xid = info->vx_id; entry->proc_iops = &vx_proc_inode_operations; info->vx_procent = entry; @@ -125,7 +125,7 @@ int vx_proc_destroy(struct vx_info *info { struct proc_dir_entry *entry = info->vx_procent; if (!entry) - return 0; + return 0; remove_proc_entry(entry->name, proc_virtual); info->vx_procent = NULL; return 0; diff -NurpP --minimal linux-2.4.23-vs1.3.0/include/linux/sched.h linux-2.4.23-vs1.3.1/include/linux/sched.h --- linux-2.4.23-vs1.3.0/include/linux/sched.h Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/include/linux/sched.h Thu Dec 25 22:24:23 2003 @@ -281,7 +281,7 @@ struct user_struct { struct vx_info; -struct iproot_info; +struct ip_info; extern struct user_struct root_user; #define INIT_USER (&root_user) @@ -412,8 +412,9 @@ struct task_struct { int (*notifier)(void *priv); __u32 cap_bset; /* Maximum capability of this process and children */ + xid_t vx_id; struct vx_info *vx_info; - struct iproot_info *ip_info; + struct ip_info *ip_info; void *notifier_data; sigset_t *notifier_mask; @@ -919,8 +920,10 @@ static inline void unhash_process(struct out_of_line_bug(); write_lock_irq(&tasklist_lock); nr_threads--; - if (p->vx_info) + if (p->vx_info) { p->vx_info->virt.nr_threads--; + atomic_dec(&p->vx_info->limit.res[RLIMIT_NPROC]); + } unhash_pid(p); REMOVE_LINKS(p); list_del(&p->thread_group); @@ -968,6 +971,33 @@ static inline void cond_resched(void) if (need_resched()) __cond_resched(); } + +#define task_get_vx_info(i) __task_get_vx_info(i,__FILE__,__LINE__) + +static __inline__ struct vx_info *__task_get_vx_info(struct task_struct *p, + const char *_file, int _line) +{ + struct vx_info *vxi; + + task_lock(p); + vxi = __get_vx_info(p->vx_info, _file, _line); + task_unlock(p); + return vxi; +} + +#define task_get_ip_info(i) __task_get_ip_info(i,__FILE__,__LINE__) + +static __inline__ struct ip_info *__task_get_ip_info(struct task_struct *p, + const char *_file, int _line) +{ + struct ip_info *ipi; + + task_lock(p); + ipi = __get_ip_info(p->ip_info, _file, _line); + task_unlock(p); + return ipi; +} + #endif /* __KERNEL__ */ #endif diff -NurpP --minimal linux-2.4.23-vs1.3.0/include/linux/vcontext.h linux-2.4.23-vs1.3.1/include/linux/vcontext.h --- linux-2.4.23-vs1.3.0/include/linux/vcontext.h Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/include/linux/vcontext.h Thu Dec 25 22:24:23 2003 @@ -23,8 +23,9 @@ /* to become the global limits */ /* of the context */ -#define MAX_S_CONTEXT 65535 /* Arbitrary limit */ -#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */ +#define MAX_S_CONTEXT 65535 /* Arbitrary limit */ +#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */ +#define VX_DYNAMIC_ID (-1UL) /* id for dynamic context */ #define NB_S_CONTEXT 16 @@ -72,40 +73,39 @@ struct vx_info { }; -struct iproot_info { - unsigned long mark; /* Special signature for debugging */ - atomic_t refcount; - int nbipv4; - __u32 ipv4[NB_IPV4ROOT];/* Process can only bind to these IPs */ - /* The first one is used to connect */ - /* and for bind any service */ - /* The other must be used explicity when */ - /* binding */ - __u32 mask[NB_IPV4ROOT];/* Netmask for each ipv4 */ - /* Used to select the proper source address */ - /* for sockets */ - __u32 v4_bcast; /* Broadcast address used to receive UDP packets */ -}; +extern spinlock_t vxlist_lock; +extern struct list_head vx_infos; void free_vx_info(struct vx_info *); + extern int proc_pid_vinfo(struct task_struct *, char *); -static inline struct vx_info *get_vx_info(struct vx_info *vxi) + +#define get_vx_info(i) __get_vx_info(i,__FILE__,__LINE__) + +static __inline__ struct vx_info *__get_vx_info(struct vx_info *vxi, const char *_file, int _line) { - dprintk("get_vx_info(%p[#%d.%d])\n", vxi, - vxi->vx_id, atomic_read(&vxi->vx_refcount)); + /* for now we allow vxi to be null */ + if (!vxi) + return NULL; + dprintk("get_vx_info(%p[#%d.%d])\t%s:%d\n", vxi, + vxi->vx_id, atomic_read(&vxi->vx_refcount), + _file, _line); atomic_inc(&vxi->vx_refcount); return vxi; } -static inline void put_vx_info(struct vx_info *vxi) +#define put_vx_info(i) __put_vx_info(i,__FILE__,__LINE__) + +static __inline__ void __put_vx_info(struct vx_info *vxi, const char *_file, int _line) { /* for now we allow vxi to be null */ if (!vxi) return; - dprintk("put_vx_info(%p[#%d.%d])\n", vxi, - vxi->vx_id, atomic_read(&vxi->vx_refcount)); + dprintk("put_vx_info(%p[#%d.%d])\t%s:%d\n", vxi, + vxi->vx_id, atomic_read(&vxi->vx_refcount), + _file, _line); if (atomic_dec_and_lock(&vxi->vx_refcount, &vxlist_lock)) { list_del(&vxi->vx_list); spin_unlock(&vxlist_lock); @@ -113,65 +113,139 @@ static inline void put_vx_info(struct vx } } +#define vx_verify_info(p,i) \ + __vx_verify_info((p)->vx_info,i,__FILE__,__LINE__) + +static __inline__ void __vx_verify_info( + struct vx_info *vxa, struct vx_info *vxb, + const char *_file, int _line) +{ + if (vxa == vxb) + return; + printk(KERN_ERR "vx bad assumption (%p==%p) at %s:%d\n", + vxa, vxb, _file, _line); +} + #define VX_ADMIN 0x0001 #define VX_WATCH 0x0002 -#define VX_IDENT 0x0010 /* pointer based */ -#define VX_SAME 0x0020 /* id based */ +#define VX_IDENT 0x0010 +#define VX_EQUIV 0x0020 #define VX_PARENT 0x0040 #define VX_CHILD 0x0080 #define VX_ARG_MASK 0x00F0 -#include +#define VX_DYNAMIC 0x0100 +#define VX_STATIC 0x0200 -/* required to resolve recursive dependancies */ -#define vx_task_id(t) __vx_id(t->vx_info) +#define VX_ATR_MASK 0x0F00 -#define vx_current_id() vx_task_id(current) -static inline int __vx_id(struct vx_info *vxi) -{ - if (!vxi) - return 0; - return vxi->vx_id; -} + +#include /* required to resolve recursive dependancies */ -#define vx_check(c,m) \ - __vx_check(current->vx_info,c,__vx_id(c),m) -#define vx_check_id(c,m) \ - __vx_check(current->vx_info,0,c,m) +#define vx_task_id(t) ((t)->vx_id) + +#define vx_current_id() vx_task_id(current) + +#define vx_check(c,m) __vx_check(vx_current_id(),c,m) + /* * check current context for ADMIN/WATCH and * optionally agains supplied argument */ -static inline int __vx_check(struct vx_info *cvxi, - struct vx_info *vxi, int id, unsigned int mode) +static __inline__ int __vx_check(xid_t cid, xid_t id, unsigned int mode) { if (mode & VX_ARG_MASK) { if ((mode & VX_IDENT) && - (vxi == cvxi)) + (id == cid)) return 1; - if ((mode & VX_SAME) && - (__vx_id(cvxi) == id)) + } + if (mode & VX_ATR_MASK) { + if ((mode & VX_DYNAMIC) && + (id >= MIN_D_CONTEXT) && + (id <= MAX_S_CONTEXT)) + return 1; + if ((mode & VX_STATIC) && + (id > 1) && (id < MIN_D_CONTEXT)) return 1; } - return (((mode & VX_ADMIN) && (cvxi == 0)) || - ((mode & VX_WATCH) && (cvxi) && - (__vx_id(cvxi) == 1))); + return (((mode & VX_ADMIN) && (cid == 0)) || + ((mode & VX_WATCH) && (cid == 1))); } -void vx_assign_info(struct task_struct *); -void vx_release_info(struct task_struct *); -void vx_assign_ip_info(struct iproot_info *); -void vx_release_ip_info(struct iproot_info *); +struct ip_info { + struct list_head ip_list; /* linked list of ipinfos */ + atomic_t ip_refcount; + int nbipv4; + __u32 ipv4[NB_IPV4ROOT];/* Process can only bind to these IPs */ + /* The first one is used to connect */ + /* and for bind any service */ + /* The other must be used explicity when */ + /* binding */ + __u32 mask[NB_IPV4ROOT];/* Netmask for each ipv4 */ + /* Used to select the proper source address */ + /* for sockets */ + __u32 v4_bcast; /* Broadcast address used to receive UDP packets */ +}; + + +extern spinlock_t iplist_lock; +extern struct list_head ip_infos; + + +void free_ip_info(struct ip_info *); + +#define get_ip_info(i) __get_ip_info(i,__FILE__,__LINE__) + +static __inline__ struct ip_info *__get_ip_info(struct ip_info *ipi, const char *_file, int _line) +{ + /* for now we allow vxi to be null */ + if (!ipi) + return NULL; + dprintk("get_ip_info(%p[%d])\t%s:%d\n", ipi, + atomic_read(&ipi->ip_refcount), _file, _line); + atomic_inc(&ipi->ip_refcount); + return ipi; +} + +#define put_ip_info(i) __put_ip_info(i,__FILE__,__LINE__) + +static __inline__ void __put_ip_info(struct ip_info *ipi, const char *_file, int _line) +{ + /* for now we allow vxi to be null */ + if (!ipi) + return; + dprintk("put_ip_info(%p[%d])\t%s:%d\n", ipi, + atomic_read(&ipi->ip_refcount), _file, _line); + if (atomic_dec_and_lock(&ipi->ip_refcount, &iplist_lock)) { + list_del(&ipi->ip_list); + spin_unlock(&iplist_lock); + free_ip_info(ipi); + } +} + +#define ip_verify_info(p,i) \ + __ip_verify_info((p)->ip_info,i,__FILE__,__LINE__) + +static __inline__ void __ip_verify_info( + struct ip_info *ipa, struct ip_info *ipb, + const char *_file, int _line) +{ + if (ipa == ipb) + return; + printk(KERN_ERR "ip bad assumption (%p==%p) at %s:%d\n", + ipa, ipb, _file, _line); +} + int vc_new_s_context(uint32_t, void *); int vc_set_ipv4root(uint32_t, void *); diff -NurpP --minimal linux-2.4.23-vs1.3.0/include/net/route.h linux-2.4.23-vs1.3.1/include/net/route.h --- linux-2.4.23-vs1.3.0/include/net/route.h Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/include/net/route.h Thu Dec 25 22:26:33 2003 @@ -167,7 +167,7 @@ static inline char rt_tos2priority(u8 to static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif) { int err; - struct iproot_info *ip_info = current->ip_info; + struct ip_info *ip_info = current->ip_info; if (ip_info != NULL) { __u32 ipv4root = ip_info->ipv4[0]; if (ipv4root != 0) { diff -NurpP --minimal linux-2.4.23-vs1.3.0/include/net/sock.h linux-2.4.23-vs1.3.1/include/net/sock.h --- linux-2.4.23-vs1.3.0/include/net/sock.h Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/include/net/sock.h Thu Dec 25 22:25:12 2003 @@ -523,7 +523,7 @@ struct sock { unsigned char reuse; /* SO_REUSEADDR setting */ unsigned char shutdown; atomic_t refcnt; /* Reference count */ - struct iproot_info *ip_info; + struct ip_info *ip_info; /* End of common section with tcp_tw_bucket */ socket_lock_t lock; /* Synchronizer... */ diff -NurpP --minimal linux-2.4.23-vs1.3.0/include/net/tcp.h linux-2.4.23-vs1.3.1/include/net/tcp.h --- linux-2.4.23-vs1.3.0/include/net/tcp.h Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/include/net/tcp.h Thu Dec 25 22:27:33 2003 @@ -173,7 +173,7 @@ struct tcp_tw_bucket { unsigned char reuse, rcv_wscale; /* It is also TW bucket specific */ atomic_t refcnt; - struct ipv4_info *ip_info; + struct ip_info *ip_info; /* And these are ours. */ int hashent; diff -NurpP --minimal linux-2.4.23-vs1.3.0/ipc/util.c linux-2.4.23-vs1.3.1/ipc/util.c --- linux-2.4.23-vs1.3.0/ipc/util.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/ipc/util.c Thu Dec 25 22:24:05 2003 @@ -93,7 +93,7 @@ int ipc_findkey(struct ipc_ids* ids, key struct kern_ipc_perm* p; for (id = 0; id <= ids->max_id; id++) { - if (!vx_check_id(ids->entries[id].xid, VX_SAME)) + if (!vx_check(ids->entries[id].xid, VX_IDENT)) continue; p = ids->entries[id].p; if(p==NULL) diff -NurpP --minimal linux-2.4.23-vs1.3.0/ipc/util.h linux-2.4.23-vs1.3.1/ipc/util.h --- linux-2.4.23-vs1.3.0/ipc/util.h Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/ipc/util.h Thu Dec 25 22:28:52 2003 @@ -78,7 +78,7 @@ extern inline struct kern_ipc_perm* ipc_ spin_lock(&ids->ary); out = ids->entries[lid].p; if (out==NULL || - !vx_check_id(ids->entries[lid].xid, VX_WATCH|VX_SAME)) { + !vx_check(ids->entries[lid].xid, VX_WATCH|VX_IDENT)) { spin_unlock(&ids->ary); out = NULL; } diff -NurpP --minimal linux-2.4.23-vs1.3.0/kernel/exit.c linux-2.4.23-vs1.3.1/kernel/exit.c --- linux-2.4.23-vs1.3.0/kernel/exit.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/kernel/exit.c Thu Dec 25 22:24:05 2003 @@ -30,6 +30,9 @@ int getrusage(struct task_struct *, int, static void release_task(struct task_struct * p) { if (p != current) { + struct vx_info *vxi = p->vx_info; + struct ip_info *ipi = p->ip_info; + #ifdef CONFIG_SMP /* * Wait to make sure the process isn't on the @@ -67,9 +70,20 @@ static void release_task(struct task_str current->counter += p->counter; if (current->counter >= MAX_COUNTER) current->counter = MAX_COUNTER; - put_vx_info(p->vx_info); - // vx_release_info(p); - vx_release_ip_info(p->ip_info); + + if (vxi) { + task_lock(p); + p->vx_info = NULL; + p->vx_id = 0; + task_unlock(p); + put_vx_info(vxi); + } + if (ipi) { + task_lock(p); + p->ip_info = NULL; + task_unlock(p); + put_ip_info(ipi); + } p->pid = 0; free_task_struct(p); } else { diff -NurpP --minimal linux-2.4.23-vs1.3.0/kernel/fork.c linux-2.4.23-vs1.3.1/kernel/fork.c --- linux-2.4.23-vs1.3.0/kernel/fork.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/kernel/fork.c Thu Dec 25 22:24:05 2003 @@ -660,13 +660,13 @@ int do_fork(unsigned long clone_flags, u if (!p) goto fork_out; + retval = -EAGAIN; *p = *current; - retval = -EAGAIN; - if (p->vx_info && (p->vx_info->vx_flags & VX_INFO_NPROC)) { - if (atomic_read(&p->vx_info->vx_refcount) >= p->rlim[RLIMIT_NPROC].rlim_max) - goto bad_fork_free; - } + if (p->vx_info && + (atomic_read(&p->vx_info->limit.res[RLIMIT_NPROC]) + >= p->vx_info->limit.rlim[RLIMIT_NPROC])) + goto bad_fork_free; /* * Check if we are over our maximum process limit, but be sure to * exclude root. This is needed to make it possible for login and @@ -681,8 +681,11 @@ int do_fork(unsigned long clone_flags, u p->vx_info = get_vx_info(current->vx_info); else p->vx_info = NULL; - // vx_assign_info(p); - vx_assign_ip_info(p->ip_info); + p->vx_id = vx_current_id(); + if (current->ip_info) + p->ip_info = get_ip_info(current->ip_info); + else + p->ip_info = NULL; atomic_inc(&p->user->__count); atomic_inc(&p->user->processes); @@ -818,8 +821,10 @@ int do_fork(unsigned long clone_flags, u SET_LINKS(p); hash_pid(p); nr_threads++; - if (p->vx_info) + if (p->vx_info) { p->vx_info->virt.nr_threads++; + atomic_inc(&p->vx_info->limit.res[RLIMIT_NPROC]); + } write_unlock_irq(&tasklist_lock); if (p->ptrace & PT_PTRACED) diff -NurpP --minimal linux-2.4.23-vs1.3.0/kernel/sched.c linux-2.4.23-vs1.3.1/kernel/sched.c --- linux-2.4.23-vs1.3.0/kernel/sched.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/kernel/sched.c Thu Dec 25 22:24:05 2003 @@ -166,12 +166,16 @@ static inline int goodness(struct task_s * Don't do any other calculations if the time slice is * over.. */ - if (p->vx_info && (p->vx_info->vx_flags & VX_INFO_SCHED)) { - weight = atomic_read(&p->vx_info->limit.ticks) / - atomic_read(&p->vx_info->vx_refcount); + struct vx_info *vxi = p->vx_info; + + if (vxi && (vxi->vx_flags & VX_INFO_SCHED)) { + weight = atomic_read(&vxi->limit.ticks) / + atomic_read(&vxi->limit.res[RLIMIT_NPROC]); weight = (weight+p->counter) >> 1; } else weight = p->counter; + + vx_verify_info(p, vxi); if (!weight) goto out; @@ -621,6 +625,7 @@ repeat_schedule: /* Do we need to re-calculate counters? */ if (unlikely(!c)) { struct task_struct *p; + struct vx_info *vxi; spin_unlock_irq(&runqueue_lock); read_lock(&tasklist_lock); @@ -628,14 +633,18 @@ repeat_schedule: Reset the s_info->ticks to the sum off all member processes p->counter */ + + spin_lock(&vxlist_lock); + list_for_each_entry(vxi, &vx_infos, vx_list) + atomic_set(&vxi->limit.ticks, 0); + spin_unlock(&vxlist_lock); + for_each_task(p) { - if (p->vx_info && (p->vx_info->vx_flags & VX_INFO_SCHED)) - atomic_set(&p->vx_info->limit.ticks, 0); - } - for_each_task(p) { + vxi = p->vx_info; p->counter = (p->counter >> 1) + NICE_TO_TICKS(p->nice); - if (p->vx_info && (p->vx_info->vx_flags & VX_INFO_SCHED)) - atomic_add(p->counter, &p->vx_info->limit.ticks); + if (vxi && (vxi->vx_flags & VX_INFO_SCHED)) + atomic_add(p->counter, &vxi->limit.ticks); + vx_verify_info(p, vxi); } read_unlock(&tasklist_lock); spin_lock_irq(&runqueue_lock); diff -NurpP --minimal linux-2.4.23-vs1.3.0/kernel/signal.c linux-2.4.23-vs1.3.1/kernel/signal.c --- linux-2.4.23-vs1.3.0/kernel/signal.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/kernel/signal.c Thu Dec 25 22:24:05 2003 @@ -624,7 +624,7 @@ kill_pg_info(int sig, struct siginfo *in for_each_task(p) { if (p->pgrp == pgrp && thread_group_leader(p) && ((long)info == 1 || - vx_check(p->vx_info, VX_IDENT))) { + vx_check(p->vx_id, VX_IDENT))) { int err = send_sig_info(sig, info, p); if (retval) retval = err; @@ -680,7 +680,7 @@ kill_proc_info(int sig, struct siginfo * } switch ((unsigned long)info) { case 0: - if (vx_check(p->vx_info, VX_IDENT)) + if (vx_check(p->vx_id, VX_IDENT)) error = send_sig_info(sig, info, p); break; case 1: @@ -688,7 +688,7 @@ kill_proc_info(int sig, struct siginfo * break; default: if ((info->si_code == SI_KERNEL) - || vx_check(p->vx_info, VX_IDENT)) + || vx_check(p->vx_id, VX_IDENT)) error = send_sig_info(sig, info, p); break; } @@ -717,7 +717,7 @@ static int kill_something_info(int sig, for_each_task(p) { if (p->pid > 1 && p != current && thread_group_leader(p) && - vx_check(p->vx_info, VX_IDENT)) { + vx_check(p->vx_id, VX_IDENT)) { int err = send_sig_info(sig, info, p); ++count; if (err != -EPERM) diff -NurpP --minimal linux-2.4.23-vs1.3.0/kernel/sys.c linux-2.4.23-vs1.3.1/kernel/sys.c --- linux-2.4.23-vs1.3.0/kernel/sys.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/kernel/sys.c Thu Dec 25 22:24:05 2003 @@ -298,7 +298,7 @@ long vs_reboot(unsigned int cmd, void * { char id_buf[8], cmd_buf[32]; char uid_buf[32], pid_buf[32]; - char buffer[256]; + char buffer[256]; char *argv[] = {vshelper_path, id_buf, NULL, NULL, 0}; char *envp[] = {"HOME=/", "TERM=linux", @@ -311,8 +311,8 @@ long vs_reboot(unsigned int cmd, void * snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid); snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid); - switch (cmd) { - case LINUX_REBOOT_CMD_RESTART: + switch (cmd) { + case LINUX_REBOOT_CMD_RESTART: argv[2] = "restart"; break; @@ -335,8 +335,8 @@ long vs_reboot(unsigned int cmd, void * if (call_usermodehelper(*argv, argv, envp)) { printk( KERN_WARNING - "vs_reboot(): failed to exec (%s %s %s %s)\n", - vshelper_path, argv[1], argv[2], argv[3]); + "vs_reboot(): failed to exec (%s %s %s %s)\n", + vshelper_path, argv[1], argv[2], argv[3]); return -EPERM; } return 0; @@ -364,7 +364,7 @@ asmlinkage long sys_reboot(int magic1, i magic2 != LINUX_REBOOT_MAGIC2B)) return -EINVAL; - if (!vx_check(0, VX_ADMIN | VX_WATCH)) + if (!vx_check(0, VX_ADMIN|VX_WATCH)) return vs_reboot(cmd, arg); lock_kernel(); diff -NurpP --minimal linux-2.4.23-vs1.3.0/kernel/timer.c linux-2.4.23-vs1.3.1/kernel/timer.c --- linux-2.4.23-vs1.3.0/kernel/timer.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/kernel/timer.c Thu Dec 25 22:24:05 2003 @@ -600,8 +600,11 @@ void update_process_times(int user_tick) update_one_process(p, user_tick, system, cpu); if (p->pid) { - if (p->vx_info && (p->vx_info->vx_flags & VX_INFO_SCHED)) - atomic_dec (&p->vx_info->limit.ticks); + struct vx_info *vxi = p->vx_info; + + if (vxi && (vxi->vx_flags & VX_INFO_SCHED)) + atomic_dec (&vxi->limit.ticks); + if (--p->counter <= 0) { p->counter = 0; /* diff -NurpP --minimal linux-2.4.23-vs1.3.0/kernel/vcontext.c linux-2.4.23-vs1.3.1/kernel/vcontext.c --- linux-2.4.23-vs1.3.0/kernel/vcontext.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/kernel/vcontext.c Thu Dec 25 22:24:05 2003 @@ -6,8 +6,9 @@ * Copyright (C) 2003 Herbert Pötzl * * V0.01 context helper - * V0.02 vx_ctx_kill + * V0.02 vx_ctx_kill syscall command * V0.03 replaced context_info calls + * V0.04 redesign of struct (de)alloc * */ @@ -121,7 +122,7 @@ static struct vx_info *alloc_vx_info(int new = kmalloc(sizeof(struct vx_info), GFP_KERNEL); if (!new) return 0; - + memset (new, 0, sizeof(struct vx_info)); new->vx_id = id; /* rest of init goes here */ @@ -152,10 +153,10 @@ void free_vx_info(struct vx_info *vxi) /* * struct vx_info search by id - * needs the vxlist_lock + * assumes vxlist_lock is held */ -static inline struct vx_info *__find_vx_info(int id) +static __inline__ struct vx_info *__find_vx_info(int id) { struct vx_info *vxi; @@ -181,29 +182,67 @@ static struct vx_info *find_vx_info(int return vxi; } + +/* + * struct vx_info search by id + * assumes vxlist_lock is held + */ + +static __inline__ xid_t __vx_dynamic_id(void) +{ + static xid_t seq = MAX_S_CONTEXT; + xid_t barrier = seq; + + do { + if (++seq > MAX_S_CONTEXT) + seq = MIN_D_CONTEXT; + if (!__find_vx_info(seq)) + return seq; + } while (barrier != seq); + return 0; +} + + extern int vx_proc_create(struct vx_info *); static struct vx_info *find_or_create_vx_info(int id) { - struct vx_info *vxi, *new; + struct vx_info *new, *vxi = NULL; dprintk("find_or_create_vx_info(%d)\n", id); if (!(new = alloc_vx_info(id))) return 0; - atomic_set(&new->vx_refcount, 1); + spin_lock(&vxlist_lock); - if ((vxi = __find_vx_info(id))) { + + /* dynamic context requested */ + if (id == VX_DYNAMIC_ID) { + id = __vx_dynamic_id(); + if (!id) { + printk(KERN_ERR "no dynamic context available.\n"); + goto out_unlock; + } + new->vx_id = id; + } + /* existing context requested */ + else if ((vxi = __find_vx_info(id))) { dprintk("find_or_create_vx_info(%d) = %p (found)\n", id, vxi); get_vx_info(vxi); - spin_unlock(&vxlist_lock); - free_vx_info(new); - return vxi; + goto out_unlock; } + + /* new context requested */ + dprintk("find_or_create_vx_info(%d) = %p (new)\n", id, vxi); + atomic_set(&new->vx_refcount, 1); list_add(&new->vx_list, &vx_infos); vx_proc_create(new); - dprintk("find_or_create_vx_info(%d) = %p (new)\n", id, new); + vxi = new, new = NULL; + +out_unlock: spin_unlock(&vxlist_lock); - return new; + if (new) + free_vx_info(new); + return vxi; } @@ -252,6 +291,7 @@ static int vx_migrate_task(struct task_s old_vxi->virt.nr_threads--; vxi->virt.nr_threads++; p->vx_info = get_vx_info(vxi); + p->vx_id = vxi->vx_id; if (old_vxi) put_vx_info(old_vxi); } @@ -262,45 +302,6 @@ out: -/* - * Alloc a new ip_info to the current process and release - * the one currently owned by the current process. - */ -static void vx_alloc_ip_info(void) -{ - struct iproot_info *ip_info = - kmalloc(sizeof(struct iproot_info), GFP_KERNEL); - - memset(ip_info, 0, sizeof(*ip_info)); - ip_info->mark = 0xdeadbeef; - atomic_set(&ip_info->refcount, 1); - vx_release_ip_info(current->ip_info); - current->ip_info = ip_info; -} - -/* - * Increase the reference count on the ip_info member of a task - */ -void vx_assign_ip_info (struct iproot_info *ip_info) -{ - if (ip_info) { - atomic_inc(&ip_info->refcount); - if (ip_info->mark != 0xdeadbeef) - printk("vx_assign_ip_info: broken signature %08lx\n", ip_info->mark); - } -} - -/* - * Decrease the reference count on the ip_info struct - * Free the struct if the reference count reach 0. - */ -void vx_release_ip_info (struct iproot_info *ip_info) -{ - if (ip_info) - if (atomic_dec_and_test(&ip_info->refcount)) - kfree(ip_info); -} - static int vx_set_initpid(struct vx_info *vxi, int pid) { @@ -320,140 +321,166 @@ int vc_new_s_context(uint32_t ctx, void if (copy_from_user(&vc_data, data, sizeof(vc_data))) return -EFAULT; - switch (ctx) { - case -1: - /* allocate dynamic context */ - if (current->vx_info == NULL - || !(current->vx_info->vx_flags & VX_INFO_LOCK)) { - static int new_xid = MAX_S_CONTEXT; - static spinlock_t alloc_ctx_lock = SPIN_LOCK_UNLOCKED; - int barrier = new_xid; - int done = 0; - - do { - spin_lock(&alloc_ctx_lock); - if (++new_xid > MAX_S_CONTEXT) - new_xid = MIN_D_CONTEXT; - spin_unlock(&alloc_ctx_lock); + printk("post copy: %x\n", vc_data.remove_cap); - new_vxi = find_or_create_vx_info(new_xid); - if (atomic_read(&new_vxi->vx_refcount) > 1) - put_vx_info(new_vxi); - else { - done = 1; - break; - } - } while (barrier != new_xid); - - if (!done) - return -EDEADLK; - - ret = vx_migrate_task(current, new_vxi); - if (ret == 0) { - current->cap_bset &= (~vc_data.remove_cap); - new_vxi->vx_flags |= vc_data.flags; - if (vc_data.flags & VX_INFO_INIT) - vx_set_initpid(new_vxi, current->tgid); - ret = new_vxi->vx_id; - } - put_vx_info(new_vxi); - } - break; - - case -2: + /* legacy hack, will be removed soon */ + if (ctx == -2) { /* assign flags and initpid */ if (!current->vx_info) return -EINVAL; ret = 0; if (vc_data.flags & VX_INFO_INIT) ret = vx_set_initpid(current->vx_info, current->tgid); + printk("post initpid: %d, %x\n", ret, vc_data.remove_cap); if (ret == 0) { /* We keep the same vx_id, but lower the capabilities */ current->cap_bset &= (~vc_data.remove_cap); ret = vx_current_id(); current->vx_info->vx_flags |= vc_data.flags; } - break; + return ret; + } - case 0: + if (!vx_check(0, VX_ADMIN) || + !capable(CAP_SYS_ADMIN) || + (current->vx_info && + (current->vx_info->vx_flags & VX_INFO_LOCK))) + return -EPERM; + if (((ctx > MAX_S_CONTEXT) && (ctx != VX_DYNAMIC_ID)) || + (ctx == 0)) return -EINVAL; - break; - - default: - if (ctx <= 0 || ctx > MAX_S_CONTEXT) - return -EINVAL; - if (!vx_check(0, VX_ADMIN) || - !capable(CAP_SYS_ADMIN) || - (current->vx_info && - (current->vx_info->vx_flags & VX_INFO_LOCK))) - return -EPERM; - if (ctx >= MIN_D_CONTEXT) - new_vxi = find_vx_info(ctx); - else - new_vxi = find_or_create_vx_info(ctx); - if (!new_vxi) - return -EINVAL; - ret = vx_migrate_task(current, new_vxi); - if (ret == 0) { - current->cap_bset &= (~vc_data.remove_cap); - new_vxi->vx_flags |= vc_data.flags; - if (vc_data.flags & VX_INFO_INIT) - vx_set_initpid(new_vxi, current->tgid); - ret = new_vxi->vx_id; - } - put_vx_info(new_vxi); - break; + + if ((ctx == VX_DYNAMIC_ID) || (ctx < MIN_D_CONTEXT)) + new_vxi = find_or_create_vx_info(ctx); + else + new_vxi = find_vx_info(ctx); + + if (!new_vxi) + return -EINVAL; + + ret = vx_migrate_task(current, new_vxi); + printk("post migrate: %d, %x\n", ret, vc_data.remove_cap); + if (ret == 0) { + current->cap_bset &= (~vc_data.remove_cap); + new_vxi->vx_flags |= vc_data.flags; + if (vc_data.flags & VX_INFO_INIT) + vx_set_initpid(new_vxi, current->tgid); + ret = new_vxi->vx_id; } + put_vx_info(new_vxi); return ret; } + +LIST_HEAD(ip_infos); + +spinlock_t iplist_lock + __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; + + +/* + * struct ip_info allocation and deallocation + */ + +static struct ip_info *alloc_ip_info(void) +{ + struct ip_info *new = NULL; + + dprintk("alloc_ip_info()\n"); + /* would this benefit from a slab cache? */ + new = kmalloc(sizeof(struct ip_info), GFP_KERNEL); + if (!new) + return 0; + + memset (new, 0, sizeof(struct ip_info)); + /* rest of init goes here */ + + + dprintk("alloc_ip_info() = %p\n", new); + return new; +} + +// extern int ip_proc_destroy(struct ip_info *); + +void free_ip_info(struct ip_info *ipi) +{ + dprintk("free_ip_info(%p)\n", ipi); +// ip_proc_destroy(ipi); + kfree(ipi); +} + +static struct ip_info *create_ip_info(void) +{ + struct ip_info *new; + + dprintk("create_ip_info()\n"); + if (!(new = alloc_ip_info())) + return 0; + + spin_lock(&iplist_lock); + + /* new ip info */ + atomic_set(&new->ip_refcount, 1); + list_add(&new->ip_list, &ip_infos); +// ip_proc_create(new); + + spin_unlock(&iplist_lock); + return new; +} + + + /* set ipv4 root (syscall) */ int vc_set_ipv4root(uint32_t nbip, void *data) { - int ret = -EPERM; + int i, err = -EPERM; struct vcmd_set_ipv4root_v3 vc_data; - struct iproot_info *ip_info = current->ip_info; + struct ip_info *new_ipi, *ipi = current->ip_info; + if (nbip < 0 || nbip > NB_IPV4ROOT) + return -EINVAL; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - if (nbip < 0 || nbip > NB_IPV4ROOT) - ret = -EINVAL; - if (!ip_info || ip_info->ipv4[0] == 0 || capable(CAP_NET_ADMIN)) + if (!ipi || ipi->ipv4[0] == 0 || capable(CAP_NET_ADMIN)) // We are allowed to change everything - ret = 0; - else if (current->ip_info) { + err = 0; + else if (ipi) { + int found = 0; + // We are allowed to select a subset of the currently // installed IP numbers. No new one allowed // We can't change the broadcast address though - int i; - int found = 0; for (i=0; inbipv4; j++) { - if (ipi == ip_info->ipv4[j]) { + __u32 ipip = vc_data.ip_mask_pair[i].ip; + for (j=0; jnbipv4; j++) { + if (ipip == ipi->ipv4[j]) { found++; break; } } } - if (found == nbip && vc_data.broadcast == ip_info->v4_bcast) - ret = 0; + if ((found == nbip) && + (vc_data.broadcast == ipi->v4_bcast)) + err = 0; } - if (ret == 0) { - int i; + if (err) + return err; - vx_alloc_ip_info(); /* release existing? */ - ip_info = current->ip_info; - ip_info->nbipv4 = nbip; - for (i=0; iipv4[i] = vc_data.ip_mask_pair[i].ip; - ip_info->mask[i] = vc_data.ip_mask_pair[i].mask; - } - ip_info->v4_bcast = vc_data.broadcast; + new_ipi = create_ip_info(); + if (!new_ipi) + return -EINVAL; + + new_ipi->nbipv4 = nbip; + for (i=0; iipv4[i] = vc_data.ip_mask_pair[i].ip; + new_ipi->mask[i] = vc_data.ip_mask_pair[i].mask; } - return ret; + new_ipi->v4_bcast = vc_data.broadcast; + current->ip_info = new_ipi; + put_ip_info(ipi); + return 0; } diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv4/af_inet.c linux-2.4.23-vs1.3.1/net/ipv4/af_inet.c --- linux-2.4.23-vs1.3.0/net/ipv4/af_inet.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv4/af_inet.c Thu Dec 25 22:24:05 2003 @@ -177,7 +177,9 @@ void inet_sock_destruct(struct sock *sk) if (sk->protinfo.af_inet.opt) kfree(sk->protinfo.af_inet.opt); - vx_release_ip_info(sk->ip_info); + + /* check for locking here */ + put_ip_info(sk->ip_info); sk->ip_info = NULL; dst_release(sk->dst_cache); #ifdef INET_REFCNT_DEBUG @@ -486,7 +488,7 @@ int inet_bind(struct socket *sock, struc __u32 s_addr1; __u32 s_addr2 = 0xffffffffl; /* Optional address of the socket */ /* bcast in ipv4root world */ - struct iproot_info *ip_info; + struct ip_info *ip_info; /* If the socket has its own bind function then use it. (RAW) */ if(sk->prot->bind) @@ -563,17 +565,17 @@ int inet_bind(struct socket *sock, struc sk->rcv_saddr = sk->saddr = s_addr1; sk->rcv_saddr2 = s_addr2; - sk->ip_info = ip_info; - if (ip_info) - vx_assign_ip_info(ip_info); + sk->ip_info = get_ip_info(ip_info); + if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) sk->saddr = 0; /* Use device */ /* Make sure we are allowed to bind here. */ if (sk->prot->get_port(sk, snum) != 0) { sk->saddr = sk->rcv_saddr = 0; + /* check for locking here */ sk->ip_info = NULL; - vx_release_ip_info(ip_info); + put_ip_info(ip_info); err = -EADDRINUSE; goto out; } diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv4/devinet.c linux-2.4.23-vs1.3.1/net/ipv4/devinet.c --- linux-2.4.23-vs1.3.0/net/ipv4/devinet.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv4/devinet.c Thu Dec 25 22:24:05 2003 @@ -465,7 +465,7 @@ static __inline__ int inet_abc_len(u32 a static int devinet_notiproot (struct in_ifaddr *ifa) { int ret = 0; - struct iproot_info *info = current->ip_info; + struct ip_info *info = current->ip_info; if (info && !vx_check(0, VX_ADMIN)) { int i; diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv4/raw.c linux-2.4.23-vs1.3.1/net/ipv4/raw.c --- linux-2.4.23-vs1.3.0/net/ipv4/raw.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv4/raw.c Thu Dec 25 22:24:05 2003 @@ -104,7 +104,7 @@ static inline int raw_addr_in_list ( u32 rcv_saddr1, u32 rcv_saddr2, u32 loc_addr, - struct iproot_info *ip_info) + struct ip_info *ip_info) { int ret = 0; if (loc_addr != 0 && @@ -689,7 +689,7 @@ int raw_get_info(char *buffer, char **st for (sk = raw_v4_htable[i]; sk; sk = sk->next, num++) { if (sk->family != PF_INET || - !vx_check_id(sk->xid, VX_WATCH|VX_SAME)) + !vx_check(sk->xid, VX_WATCH|VX_IDENT)) continue; pos += 128; if (pos <= offset) diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv4/tcp_ipv4.c linux-2.4.23-vs1.3.1/net/ipv4/tcp_ipv4.c --- linux-2.4.23-vs1.3.0/net/ipv4/tcp_ipv4.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv4/tcp_ipv4.c Thu Dec 25 22:24:05 2003 @@ -186,7 +186,7 @@ static inline void tcp_bind_hash(struct */ static inline int tcp_in_list (struct sock *sk, u32 addr) { - struct iproot_info *ip_info = sk->ip_info; + struct ip_info *ip_info = sk->ip_info; if (ip_info) { int n = ip_info->nbipv4; @@ -211,7 +211,7 @@ int tcp_ipv4_addr_conflict (struct sock return tcp_in_list (sk2,sk1->rcv_saddr); } else if (sk1->ip_info) { /* A restricted bind(any) */ - struct iproot_info *ip_info = sk1->ip_info; + struct ip_info *ip_info = sk1->ip_info; int n = ip_info->nbipv4; int i; @@ -463,7 +463,7 @@ void tcp_unhash(struct sock *sk) static inline int tcp_addr_in_list ( u32 rcv_saddr, u32 daddr, - struct iproot_info *ip_info) + struct ip_info *ip_info) { if (rcv_saddr == daddr) return 1; @@ -2259,7 +2259,7 @@ int tcp_get_info(char *buffer, char **st int uid; struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - if (!vx_check_id(sk->xid, VX_WATCH|VX_SAME)) + if (!vx_check(sk->xid, VX_WATCH|VX_IDENT)) continue; if (!TCP_INET_FAMILY(sk->family)) @@ -2316,7 +2316,7 @@ skip_listen: read_lock(&head->lock); for(sk = head->chain; sk; sk = sk->next, num++) { if (!TCP_INET_FAMILY(sk->family) || - !vx_check_id(sk->xid, VX_WATCH|VX_SAME)) + !vx_check(sk->xid, VX_WATCH|VX_IDENT)) continue; pos += TMPSZ; if (pos <= offset) @@ -2332,7 +2332,7 @@ skip_listen: tw != NULL; tw = (struct tcp_tw_bucket *)tw->next, num++) { if (!TCP_INET_FAMILY(tw->family) || - !vx_check_id(tw->xid, VX_WATCH|VX_SAME)) + !vx_check(tw->xid, VX_WATCH|VX_IDENT)) continue; pos += TMPSZ; if (pos <= offset) diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv4/tcp_minisocks.c linux-2.4.23-vs1.3.1/net/ipv4/tcp_minisocks.c --- linux-2.4.23-vs1.3.0/net/ipv4/tcp_minisocks.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv4/tcp_minisocks.c Thu Dec 25 22:24:05 2003 @@ -654,7 +654,7 @@ struct sock *tcp_create_openreq_child(st #endif memcpy(newsk, sk, sizeof(*newsk)); - vx_assign_ip_info(newsk->ip_info); + newsk->ip_info = get_ip_info(sk->ip_info); newsk->state = TCP_SYN_RECV; /* SANITY */ diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv4/udp.c linux-2.4.23-vs1.3.1/net/ipv4/udp.c --- linux-2.4.23-vs1.3.0/net/ipv4/udp.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv4/udp.c Thu Dec 25 22:24:05 2003 @@ -213,7 +213,7 @@ static void udp_v4_unhash(struct sock *s write_unlock_bh(&udp_hash_lock); } -static int udp_in_list (struct iproot_info *ip_info, u32 addr) +static int udp_in_list (struct ip_info *ip_info, u32 addr) { int n = ip_info->nbipv4; int i; @@ -551,7 +551,7 @@ int udp_sendmsg(struct sock *sk, struct rt = (struct rtable*)sk_dst_check(sk, 0); if (rt == NULL) { - struct iproot_info *ip_info = current->ip_info; + struct ip_info *ip_info = current->ip_info; if (ip_info != NULL) { __u32 ipv4root = ip_info->ipv4[0]; @@ -1051,7 +1051,7 @@ int udp_get_info(char *buffer, char **st for (sk = udp_hash[i]; sk; sk = sk->next, num++) { if (sk->family != PF_INET || - !vx_check_id(sk->xid, VX_WATCH|VX_SAME)) + !vx_check(sk->xid, VX_WATCH|VX_IDENT)) continue; pos += 128; if (pos <= offset) diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv6/raw.c linux-2.4.23-vs1.3.1/net/ipv6/raw.c --- linux-2.4.23-vs1.3.0/net/ipv6/raw.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv6/raw.c Thu Dec 25 22:24:05 2003 @@ -881,7 +881,7 @@ int raw6_get_info(char *buffer, char **s for (sk = raw_v6_htable[i]; sk; sk = sk->next, num++) { if (sk->family != PF_INET6 || - !vx_check_id(sk->vx_id, VX_WATCH|VX_SAME)) + !vx_check(sk->vx_id, VX_WATCH|VX_IDENT)) continue; pos += LINE_LEN+1; if (pos <= offset) diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv6/tcp_ipv6.c linux-2.4.23-vs1.3.1/net/ipv6/tcp_ipv6.c --- linux-2.4.23-vs1.3.0/net/ipv6/tcp_ipv6.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv6/tcp_ipv6.c Thu Dec 25 22:24:05 2003 @@ -2030,7 +2030,7 @@ int tcp6_get_info(char *buffer, char **s struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); if (sk->family != PF_INET6 || - !vx_check_id(sk->xid, VX_WATCH|VX_SAME)) + !vx_check(sk->xid, VX_WATCH|VX_IDENT)) continue; pos += LINE_LEN+1; if (pos >= offset) { @@ -2081,7 +2081,7 @@ int tcp6_get_info(char *buffer, char **s read_lock(&head->lock); for(sk = head->chain; sk; sk = sk->next, num++) { if (sk->family != PF_INET6 || - !vx_check_id(sk->xid, VX_WATCH|VX_SAME)) + !vx_check(sk->xid, VX_WATCH|VX_IDENT)) continue; pos += LINE_LEN+1; if (pos <= offset) @@ -2097,7 +2097,7 @@ int tcp6_get_info(char *buffer, char **s tw != NULL; tw = (struct tcp_tw_bucket *)tw->next, num++) { if (tw->family != PF_INET6 || - !vx_check_id(tw->xid, VX_WATCH|VX_SAME)) + !vx_check(tw->xid, VX_WATCH|VX_IDENT)) continue; pos += LINE_LEN+1; if (pos <= offset) diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/ipv6/udp.c linux-2.4.23-vs1.3.1/net/ipv6/udp.c --- linux-2.4.23-vs1.3.0/net/ipv6/udp.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/ipv6/udp.c Thu Dec 25 22:24:05 2003 @@ -982,7 +982,7 @@ int udp6_get_info(char *buffer, char **s for (sk = udp_hash[i]; sk; sk = sk->next, num++) { if (sk->family != PF_INET6 || - !vx_check_id(sk->vx_id, VX_WATCH|VX_SAME)) + !vx_check(sk->vx_id, VX_WATCH|VX_IDENT)) continue; pos += LINE_LEN+1; if (pos <= offset) diff -NurpP --minimal linux-2.4.23-vs1.3.0/net/unix/af_unix.c linux-2.4.23-vs1.3.1/net/unix/af_unix.c --- linux-2.4.23-vs1.3.0/net/unix/af_unix.c Thu Dec 25 23:11:06 2003 +++ linux-2.4.23-vs1.3.1/net/unix/af_unix.c Thu Dec 25 22:24:05 2003 @@ -1758,7 +1758,7 @@ static int unix_read_proc(char *buffer, read_lock(&unix_table_lock); forall_unix_sockets (i,s) { - if (!vx_check_id(s->xid, VX_WATCH|VX_SAME)) + if (!vx_check(s->xid, VX_WATCH|VX_IDENT)) continue; unix_state_rlock(s);