diff -rc2P linux-2.4.18ctx-10/Makefile linux-2.4.18ctx-12/Makefile *** linux-2.4.18ctx-10/Makefile Tue Mar 19 23:20:34 2002 --- linux-2.4.18ctx-12/Makefile Tue Jul 2 12:11:33 2002 *************** *** 2,6 **** PATCHLEVEL = 4 SUBLEVEL = 18 ! EXTRAVERSION =ctx-10 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) --- 2,6 ---- PATCHLEVEL = 4 SUBLEVEL = 18 ! EXTRAVERSION =ctxsmp-12 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -rc2P linux-2.4.18ctx-10/fs/proc/array.c linux-2.4.18ctx-12/fs/proc/array.c *** linux-2.4.18ctx-10/fs/proc/array.c Wed Apr 3 16:41:02 2002 --- linux-2.4.18ctx-12/fs/proc/array.c Mon Jul 1 00:08:26 2002 *************** *** 297,304 **** buffer = task_cap(task, buffer); #ifdef __NR_new_s_context - buffer += sprintf (buffer,"s_context: %d\n",task->s_context); - buffer += sprintf (buffer,"ipv4root: %08x\n",task->ipv4root); - buffer += sprintf (buffer,"ipv4root_bcast: %08x\n",task->ipv4root_bcast); if (task->s_info != NULL){ buffer += sprintf (buffer,"ctxticks: %d %ld %d\n" ,atomic_read(&task->s_info->ticks),task->counter --- 297,310 ---- buffer = task_cap(task, buffer); #ifdef __NR_new_s_context if (task->s_info != NULL){ + int i; + buffer += sprintf (buffer,"s_context: %d [",task->s_context); + for (i=0; is_info->s_context[i]; + if (ctx == 0) break; + buffer += sprintf (buffer," %d",ctx); + } + *buffer++ = ']'; + *buffer++ = '\n'; buffer += sprintf (buffer,"ctxticks: %d %ld %d\n" ,atomic_read(&task->s_info->ticks),task->counter *************** *** 309,318 **** ,task->s_info->initpid); }else{ buffer += sprintf (buffer,"ctxticks: none\n"); buffer += sprintf (buffer,"ctxflags: none\n"); buffer += sprintf (buffer,"initpid: none\n"); } buffer += sprintf (buffer,"__NR_new_s_context: %d\n",__NR_new_s_context); ! buffer += sprintf (buffer,"__NR_set_ipv4root: %d rev1\n",__NR_set_ipv4root); #endif #if defined(CONFIG_ARCH_S390) --- 315,339 ---- ,task->s_info->initpid); }else{ + buffer += sprintf (buffer,"s_context: %d\n",task->s_context); buffer += sprintf (buffer,"ctxticks: none\n"); buffer += sprintf (buffer,"ctxflags: none\n"); buffer += sprintf (buffer,"initpid: none\n"); } + if (task->ip_info != NULL){ + int i; + buffer += sprintf (buffer,"ipv4root:"); + for (i=0; iip_info->nbipv4; i++){ + buffer += sprintf (buffer," %08x" + ,task->ip_info->ipv4[i]); + } + *buffer++ = '\n'; + buffer += sprintf (buffer,"ipv4root_bcast: %08x\n" + ,task->ip_info->v4_bcast); + }else{ + buffer += sprintf (buffer,"ipv4root: 0\n"); + buffer += sprintf (buffer,"ipv4root_bcast: 0\n"); + } buffer += sprintf (buffer,"__NR_new_s_context: %d\n",__NR_new_s_context); ! buffer += sprintf (buffer,"__NR_set_ipv4root: %d rev2\n",__NR_set_ipv4root); #endif #if defined(CONFIG_ARCH_S390) diff -rc2P linux-2.4.18ctx-10/include/linux/sched.h linux-2.4.18ctx-12/include/linux/sched.h *** linux-2.4.18ctx-10/include/linux/sched.h Wed Apr 3 16:41:02 2002 --- linux-2.4.18ctx-12/include/linux/sched.h Tue Jul 2 12:15:42 2002 *************** *** 292,299 **** /* context */ struct context_info{ int refcount; ! int s_context; char nodename[65]; char domainname[65]; --- 292,302 ---- /* context */ + #define NB_IPV4ROOT 16 + #define NB_S_CONTEXT 16 struct context_info{ int refcount; ! short int s_context[NB_S_CONTEXT];/* root is allowed to switch the current */ ! /* security context using any in this table */ char nodename[65]; char domainname[65]; *************** *** 305,308 **** --- 308,322 ---- }; + struct iproot_info{ + int 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 v4_bcast; /* Broadcast address used to receive UDP packets */ + }; + extern struct user_struct root_user; *************** *** 434,440 **** /* with the same s_context */ __u32 cap_bset; /* Maximum capability of this process and children */ - __u32 ipv4root; /* Process can only bind to this iP */ - __u32 ipv4root_bcast; struct context_info *s_info; void *notifier_data; sigset_t *notifier_mask; --- 448,453 ---- /* with the same s_context */ __u32 cap_bset; /* Maximum capability of this process and children */ struct context_info *s_info; + struct iproot_info *ip_info; void *notifier_data; sigset_t *notifier_mask; *************** *** 970,973 **** --- 983,989 ---- void sys_assign_s_info (struct task_struct *); void sys_alloc_s_info (void); + void sys_release_ip_info (struct task_struct *); + void sys_assign_ip_info (struct task_struct *); + void sys_alloc_ip_info (void); #endif /* __KERNEL__ */ diff -rc2P linux-2.4.18ctx-10/include/net/route.h linux-2.4.18ctx-12/include/net/route.h *** linux-2.4.18ctx-10/include/net/route.h Wed Apr 3 16:45:16 2002 --- linux-2.4.18ctx-12/include/net/route.h Tue Jul 2 12:17:34 2002 *************** *** 161,172 **** { int err; ! if (current->ipv4root != 0){ ! if (src == 0){ ! src = current->ipv4root; ! }else if (current->ipv4root != src){ ! return -EPERM; ! } ! if (dst == 0x0100007f && current->s_context != 0){ ! dst = current->ipv4root; } } --- 161,176 ---- { int err; ! if (current->ip_info != NULL){ ! __u32 ipv4root = current->ip_info->ipv4[0]; ! if (ipv4root != 0){ ! if (src == 0){ ! src = dst == 0x0100007f ! ? 0x0100007f: ipv4root; ! }else if (ipv4root != src){ ! return -EPERM; ! } ! if (dst == 0x0100007f && current->s_context != 0){ ! dst = ipv4root; ! } } } diff -rc2P linux-2.4.18ctx-10/kernel/exit.c linux-2.4.18ctx-12/kernel/exit.c *** linux-2.4.18ctx-10/kernel/exit.c Wed Feb 27 14:45:32 2002 --- linux-2.4.18ctx-12/kernel/exit.c Sun Jun 30 07:10:45 2002 *************** *** 67,70 **** --- 67,71 ---- current->counter = MAX_COUNTER; sys_release_s_info(p); + sys_release_ip_info(p); p->pid = 0; free_task_struct(p); diff -rc2P linux-2.4.18ctx-10/kernel/fork.c linux-2.4.18ctx-12/kernel/fork.c *** linux-2.4.18ctx-10/kernel/fork.c Wed Feb 27 14:48:50 2002 --- linux-2.4.18ctx-12/kernel/fork.c Sun Jun 30 07:11:23 2002 *************** *** 604,607 **** --- 604,608 ---- sys_assign_s_info (p); + sys_assign_ip_info (p); atomic_inc(&p->user->__count); diff -rc2P linux-2.4.18ctx-10/kernel/sys.c linux-2.4.18ctx-12/kernel/sys.c *** linux-2.4.18ctx-10/kernel/sys.c Tue Feb 26 22:31:23 2002 --- linux-2.4.18ctx-12/kernel/sys.c Sun Jun 30 23:44:14 2002 *************** *** 1068,1088 **** { struct context_info *s_info = vmalloc(sizeof(struct context_info)); ! // printk ("new s_info %d\n",current->pid); ! s_info->s_context = current->s_context; ! s_info->refcount = 1; ! atomic_set (&s_info->ticks,current->counter); ! s_info->flags = 0; ! s_info->initpid = 0; ! down_read (&uts_sem); ! if (current->s_info != NULL){ ! strcpy (s_info->nodename,current->s_info->nodename); ! strcpy (s_info->domainname,current->s_info->domainname); ! }else{ ! strcpy (s_info->nodename,system_utsname.nodename); ! strcpy (s_info->domainname,system_utsname.domainname); } ! up_read (&uts_sem); ! sys_release_s_info (current); ! current->s_info = s_info; } --- 1068,1131 ---- { struct context_info *s_info = vmalloc(sizeof(struct context_info)); ! if (s_info != NULL){ ! memset (s_info,0,sizeof(*s_info)); ! // printk ("new s_info %d\n",current->pid); ! s_info->s_context[0] = current->s_context; ! s_info->refcount = 1; ! atomic_set (&s_info->ticks,current->counter); ! s_info->flags = 0; ! s_info->initpid = 0; ! down_read (&uts_sem); ! if (current->s_info != NULL){ ! strcpy (s_info->nodename,current->s_info->nodename); ! strcpy (s_info->domainname,current->s_info->domainname); ! }else{ ! strcpy (s_info->nodename,system_utsname.nodename); ! strcpy (s_info->domainname,system_utsname.domainname); ! } ! up_read (&uts_sem); ! sys_release_s_info (current); ! current->s_info = s_info; ! } ! } ! /* ! Decrease the reference count on the ip_info member of a task ! Free the struct if the reference count reach 0. ! */ ! void sys_release_ip_info (struct task_struct *p) ! { ! down_write (&uts_sem); ! if (p->ip_info != NULL){ ! p->ip_info->refcount--; ! if (p->ip_info->refcount == 0){ ! // printk ("vfree s_info %d\n",p->pid); ! vfree (p->ip_info); ! p->ip_info = NULL; ! } } ! up_write (&uts_sem); ! } ! /* ! Increase the reference count on the ip_info member of a task ! */ ! void sys_assign_ip_info (struct task_struct *p) ! { ! down_write (&uts_sem); ! if (p->ip_info != NULL) p->ip_info->refcount++; ! up_write (&uts_sem); ! } ! ! /* ! Alloc a new ip_info to the current process and release ! the one currently owned by the current process. ! */ ! void sys_alloc_ip_info() ! { ! struct iproot_info *ip_info = vmalloc(sizeof(struct iproot_info)); ! // printk ("new s_info %d\n",current->pid); ! memset (ip_info,0,sizeof(*ip_info)); ! ip_info->refcount = 1; ! sys_release_ip_info (current); ! current->ip_info = ip_info; } diff -rc2P linux-2.4.18ctx-10/net/ipv4/af_inet.c linux-2.4.18ctx-12/net/ipv4/af_inet.c *** linux-2.4.18ctx-10/net/ipv4/af_inet.c Mon Mar 18 12:26:22 2002 --- linux-2.4.18ctx-12/net/ipv4/af_inet.c Sun Jun 30 11:47:55 2002 *************** *** 482,485 **** --- 482,486 ---- __u32 s_addr; __u32 bcast_addr = 0xffffffffl; + __u32 ipv4root; /* If the socket has its own bind function then use it. (RAW) */ *************** *** 491,507 **** s_addr = addr->sin_addr.s_addr; ! if (current->ipv4root != 0){ ! // printk ("ipv4root0 %08lx %08x\n",current->ipv4root,s_addr); if (s_addr == 0){ ! s_addr = current->ipv4root; ! bcast_addr = current->ipv4root_bcast; }else if (s_addr == 0x0100007f){ ! s_addr = current->ipv4root; ! }else if (s_addr != current->ipv4root){ ! return -EADDRNOTAVAIL; } } chk_addr_ret = inet_addr_type(s_addr); ! // printk ("ipv4root %08lx %08x %d\n",current->ipv4root,s_addr,chk_addr_ret); /* Not specified by any standard per-se, however it breaks too --- 492,518 ---- s_addr = addr->sin_addr.s_addr; ! ipv4root = current->ip_info != NULL ? current->ip_info->ipv4[0] : 0; ! if (ipv4root != 0){ ! // printk ("ipv4root0 %08lx %08x\n",ipv4root,s_addr); ! __u32 v4_bcast = current->ip_info->v4_bcast; if (s_addr == 0){ ! s_addr = ipv4root; ! bcast_addr = v4_bcast; }else if (s_addr == 0x0100007f){ ! s_addr = ipv4root; ! }else if (s_addr != v4_bcast ! && s_addr != ipv4root){ ! int i; ! int nbipv4 = current->ip_info->nbipv4; ! for (i=0; iip_info->ipv4[i]){ ! break; ! } ! } ! if (i == nbipv4) return -EADDRNOTAVAIL; } } chk_addr_ret = inet_addr_type(s_addr); ! // printk ("ipv4root %08lx %08x %d\n",ipv4root,s_addr,chk_addr_ret); /* Not specified by any standard per-se, however it breaks too diff -rc2P linux-2.4.18ctx-10/net/ipv4/devinet.c linux-2.4.18ctx-12/net/ipv4/devinet.c *** linux-2.4.18ctx-10/net/ipv4/devinet.c Tue Feb 26 22:31:23 2002 --- linux-2.4.18ctx-12/net/ipv4/devinet.c Mon Jul 1 00:06:39 2002 *************** *** 456,459 **** --- 456,485 ---- } + /* + Check that a device is not member of the ipv4root assigned to the process + Return true if this is the case + + If the process is not bound to specific IP, then it returns 0 (all + interface are fine). + */ + static int devinet_notiproot (struct in_ifaddr *ifa) + { + int ret = 0; + struct iproot_info *info = current->ip_info; + if (current->s_context != 0 && info != NULL){ + int i; + int nbip = info->nbipv4; + __u32 addr = ifa->ifa_local; + ret = 1; + for (i=0; iipv4[i] == addr){ + ret = 0; + break; + } + } + } + return ret; + } + int devinet_ioctl(unsigned int cmd, void *arg) *************** *** 560,566 **** } if (ifa != NULL ! && current->s_context != 0 ! && current->ipv4root != 0 ! && current->ipv4root != ifa->ifa_local){ ret = -EADDRNOTAVAIL; goto done; --- 586,590 ---- } if (ifa != NULL ! && devinet_notiproot (ifa)){ ret = -EADDRNOTAVAIL; goto done; *************** *** 699,705 **** for ( ; ifa; ifa = ifa->ifa_next) { // We do not show other IP devices to vservers ! if (current->s_context != 0 ! && current->ipv4root != 0 ! && current->ipv4root != ifa->ifa_local) continue; if (!buf) { done += sizeof(ifr); --- 723,727 ---- for ( ; ifa; ifa = ifa->ifa_next) { // We do not show other IP devices to vservers ! if (devinet_notiproot(ifa)) continue; if (!buf) { done += sizeof(ifr); *************** *** 919,925 **** for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; ifa = ifa->ifa_next, ip_idx++) { ! if (current->s_context != 0 ! && current->ipv4root != 0 ! && current->ipv4root != ifa->ifa_local) continue; if (ip_idx < s_ip_idx) continue; --- 941,945 ---- for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; ifa = ifa->ifa_next, ip_idx++) { ! if (devinet_notiproot(ifa)) continue; if (ip_idx < s_ip_idx) continue; diff -rc2P linux-2.4.18ctx-10/net/socket.c linux-2.4.18ctx-12/net/socket.c *** linux-2.4.18ctx-10/net/socket.c Wed Apr 3 16:41:02 2002 --- linux-2.4.18ctx-12/net/socket.c Sun Jun 30 15:22:04 2002 *************** *** 1765,1776 **** } ! asmlinkage int sys_set_ipv4root (__u32 ip, __u32 bcast) { int ret = -EPERM; ! if (current->ipv4root == 0 ! || capable(CAP_SYS_ADMIN)){ ret = 0; ! current->ipv4root = ip; ! current->ipv4root_bcast = bcast; } return ret; --- 1765,1808 ---- } ! asmlinkage int sys_set_ipv4root (__u32 ip[], int nbip, __u32 bcast) { int ret = -EPERM; ! __u32 tbip[NB_IPV4ROOT]; ! struct iproot_info *ip_info = current->ip_info; ! if (nbip < 0 || nbip > NB_IPV4ROOT){ ! ret = -EINVAL; ! }else if (copy_from_user(tbip,ip,nbip*sizeof(ip[0]))!=0){ ! ret = -EFAULT; ! }else if (ip_info == NULL ! || ip_info->ipv4[0] == 0 ! || capable(CAP_NET_ADMIN)){ ! // We are allowed to change everything ret = 0; ! }else if (current->ip_info != NULL){ ! // 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]){ ! found++; ! break; ! } ! } ! } ! if (found == nbip && bcast == ip_info->v4_bcast){ ! ret = 0; ! } ! ! } ! if (ret == 0){ ! sys_alloc_ip_info(); ! current->ip_info->nbipv4 = nbip; ! memcpy (current->ip_info->ipv4,tbip,nbip*sizeof(tbip[0])); ! current->ip_info->v4_bcast = bcast; } return ret;