diff -rc2P linux-2.4.17ctx-7/Makefile linux-2.4.17ctx-8/Makefile *** linux-2.4.17ctx-7/Makefile Wed Feb 6 15:28:08 2002 --- linux-2.4.17ctx-8/Makefile Wed Feb 6 15:52:50 2002 *************** *** 2,6 **** PATCHLEVEL = 4 SUBLEVEL = 17 ! EXTRAVERSION =ctx-7 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) --- 2,6 ---- PATCHLEVEL = 4 SUBLEVEL = 17 ! EXTRAVERSION =ctx-8 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -rc2P linux-2.4.17ctx-7/fs/proc/array.c linux-2.4.17ctx-8/fs/proc/array.c *** linux-2.4.17ctx-7/fs/proc/array.c Wed Feb 6 12:33:49 2002 --- linux-2.4.17ctx-8/fs/proc/array.c Thu Feb 7 23:15:24 2002 *************** *** 76,79 **** --- 76,80 ---- #include #include + #include /* Gcc optimizes away "strlen(x)" for constant x */ *************** *** 298,302 **** 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); --- 299,303 ---- buffer += sprintf (buffer,"ipv4root: %08lx\n",task->ipv4root); if (task->s_info != NULL){ ! buffer += sprintf (buffer,"ctxticks: %d %ld %d\n" ,atomic_read(&task->s_info->ticks),task->counter ,task->s_info->refcount); *************** *** 310,313 **** --- 311,316 ---- 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\n",__NR_set_ipv4root); #if defined(CONFIG_ARCH_S390) buffer = task_show_regs(task, buffer); diff -rc2P linux-2.4.17ctx-7/include/linux/sched.h linux-2.4.17ctx-8/include/linux/sched.h *** linux-2.4.17ctx-7/include/linux/sched.h Wed Feb 6 13:31:58 2002 --- linux-2.4.17ctx-8/include/linux/sched.h Wed Feb 20 20:39:33 2002 *************** *** 269,272 **** --- 269,273 ---- struct user_struct *next, **pprev; uid_t uid; + int s_context; }; *************** *** 602,606 **** /* per-UID process charging. */ ! extern struct user_struct * alloc_uid(uid_t); extern void free_uid(struct user_struct *); --- 603,607 ---- /* per-UID process charging. */ ! extern struct user_struct * alloc_uid(int, uid_t); extern void free_uid(struct user_struct *); diff -rc2P linux-2.4.17ctx-7/include/net/route.h linux-2.4.17ctx-8/include/net/route.h *** linux-2.4.17ctx-7/include/net/route.h Wed Feb 6 13:33:57 2002 --- linux-2.4.17ctx-8/include/net/route.h Wed Feb 20 20:49:58 2002 *************** *** 166,169 **** --- 166,172 ---- return -EPERM; } + if (dst == 0x0100007f && current->s_context != 0){ + dst = current->ipv4root; + } } err = ip_route_output(rp, dst, src, tos, oif); diff -rc2P linux-2.4.17ctx-7/include/net/sock.h linux-2.4.17ctx-8/include/net/sock.h *** linux-2.4.17ctx-7/include/net/sock.h Wed Feb 6 13:33:57 2002 --- linux-2.4.17ctx-8/include/net/sock.h Thu Feb 21 14:42:39 2002 *************** *** 669,673 **** /* RPC layer private data */ void *user_data; ! /* Callbacks */ void (*state_change)(struct sock *sk); --- 669,676 ---- /* RPC layer private data */ void *user_data; ! ! /* Context of process creating this socket */ ! int s_context; ! /* Callbacks */ void (*state_change)(struct sock *sk); diff -rc2P linux-2.4.17ctx-7/include/net/tcp.h linux-2.4.17ctx-8/include/net/tcp.h *** linux-2.4.17ctx-7/include/net/tcp.h Wed Feb 6 13:40:14 2002 --- linux-2.4.17ctx-8/include/net/tcp.h Thu Feb 21 14:52:49 2002 *************** *** 191,194 **** --- 191,195 ---- struct in6_addr v6_rcv_saddr; #endif + int s_context; }; diff -rc2P linux-2.4.17ctx-7/kernel/signal.c linux-2.4.17ctx-8/kernel/signal.c *** linux-2.4.17ctx-7/kernel/signal.c Wed Jan 9 14:18:51 2002 --- linux-2.4.17ctx-8/kernel/signal.c Wed Feb 20 20:43:06 2002 *************** *** 1291,1294 **** --- 1291,1313 ---- } + static inline int switch_user_struct(int new_context) + { + struct user_struct *new_user; + + new_user = alloc_uid(new_context, current->uid); + if (!new_user) + return -ENOMEM; + + if (new_user != current->user) { + struct user_struct *old_user = current->user; + + atomic_inc(&new_user->processes); + atomic_dec(&old_user->processes); + current->user = new_user; + free_uid(old_user); + } + return 0; + } + /* Change to a new security context and reduce the capability *************** *** 1330,1340 **** 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){ ! set_initpid (flags); ! current->s_info->flags |= flags; } spin_unlock(&alloc_ctx_lock); --- 1349,1362 ---- if (!found) break; } ! ret = switch_user_struct(alloc_ctx); ! if (ret == 0) { ! current->s_context = alloc_ctx; ! current->cap_bset &= (~remove_cap); ! ret = alloc_ctx; ! sys_alloc_s_info(); ! if (current->s_info != NULL) { ! set_initpid (flags); ! current->s_info->flags |= flags; ! } } spin_unlock(&alloc_ctx_lock); *************** *** 1380,1391 **** } 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; } } --- 1402,1416 ---- } read_unlock(&tasklist_lock); ! if (ret == ctx) { ! ret = switch_user_struct(ctx); ! if (ret == 0) { ! 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; ! } } } diff -rc2P linux-2.4.17ctx-7/kernel/sys.c linux-2.4.17ctx-8/kernel/sys.c *** linux-2.4.17ctx-7/kernel/sys.c Wed Jan 9 14:09:08 2002 --- linux-2.4.17ctx-8/kernel/sys.c Wed Feb 20 20:39:33 2002 *************** *** 501,505 **** * we should be checking for it. -DaveM */ ! new_user = alloc_uid(new_ruid); if (!new_user) return -EAGAIN; --- 501,505 ---- * we should be checking for it. -DaveM */ ! new_user = alloc_uid(current->s_context, new_ruid); if (!new_user) return -EAGAIN; diff -rc2P linux-2.4.17ctx-7/kernel/user.c linux-2.4.17ctx-8/kernel/user.c *** linux-2.4.17ctx-7/kernel/user.c Wed Nov 29 01:43:39 2000 --- linux-2.4.17ctx-8/kernel/user.c Wed Feb 20 20:39:33 2002 *************** *** 7,10 **** --- 7,23 ---- * processes, files etc the user has claimed, in order to be * able to have per-user limits for system resources. + * + * For the vserver project, the key is extended from UID to (SC,UID), + * with SC being the security context ID. Thus, each security context + * has independant per-UID resource usage counters. + * + * As a consequence, even if two UIDs are the same, the 'struct user *' + * in their task_struct could be different. I don't think any code cares. + * + * (vserver modifications done Sun Jan 13 08:48:45 CET 2002 by bof@bof.de) + * + * NOTE: For now, the hash function is unmodified: the same uid in several + * security contexts, will always sit on the same hash chain. This could + * be changed easily. */ *************** *** 57,61 **** } ! static inline struct user_struct *uid_hash_find(uid_t uid, struct user_struct **hashent) { struct user_struct *next; --- 70,74 ---- } ! static inline struct user_struct *uid_hash_find(int s_context, uid_t uid, struct user_struct **hashent) { struct user_struct *next; *************** *** 66,70 **** if (next) { next = up->next; ! if (up->uid != uid) continue; atomic_inc(&up->__count); --- 79,83 ---- if (next) { next = up->next; ! if (up->uid != uid || up->s_context != s_context) continue; atomic_inc(&up->__count); *************** *** 83,87 **** } ! struct user_struct * alloc_uid(uid_t uid) { struct user_struct **hashent = uidhashentry(uid); --- 96,100 ---- } ! struct user_struct * alloc_uid(int s_context, uid_t uid) { struct user_struct **hashent = uidhashentry(uid); *************** *** 89,93 **** spin_lock(&uidhash_lock); ! up = uid_hash_find(uid, hashent); spin_unlock(&uidhash_lock); --- 102,106 ---- spin_lock(&uidhash_lock); ! up = uid_hash_find(s_context, uid, hashent); spin_unlock(&uidhash_lock); *************** *** 99,102 **** --- 112,116 ---- return NULL; new->uid = uid; + new->s_context = s_context; atomic_set(&new->__count, 1); atomic_set(&new->processes, 0); *************** *** 108,112 **** */ spin_lock(&uidhash_lock); ! up = uid_hash_find(uid, hashent); if (up) { kmem_cache_free(uid_cachep, new); --- 122,126 ---- */ spin_lock(&uidhash_lock); ! up = uid_hash_find(s_context, uid, hashent); if (up) { kmem_cache_free(uid_cachep, new); diff -rc2P linux-2.4.17ctx-7/net/ipv4/af_inet.c linux-2.4.17ctx-8/net/ipv4/af_inet.c *** linux-2.4.17ctx-7/net/ipv4/af_inet.c Sat Dec 22 22:52:48 2001 --- linux-2.4.17ctx-8/net/ipv4/af_inet.c Thu Feb 21 14:42:39 2002 *************** *** 394,397 **** --- 394,399 ---- sk->protinfo.af_inet.mc_list = NULL; + sk->s_context = current->s_context; + #ifdef INET_REFCNT_DEBUG atomic_inc(&inet_sock_nr); *************** *** 490,494 **** 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){ --- 492,496 ---- if (current->ipv4root != 0){ // printk ("ipv4root0 %08lx %08x\n",current->ipv4root,s_addr); ! if (s_addr == 0 || s_addr == 0x0100007f){ s_addr = current->ipv4root; }else if (s_addr != current->ipv4root){ diff -rc2P linux-2.4.17ctx-7/net/ipv4/devinet.c linux-2.4.17ctx-8/net/ipv4/devinet.c *** linux-2.4.17ctx-7/net/ipv4/devinet.c Thu Jan 31 14:37:27 2002 --- linux-2.4.17ctx-8/net/ipv4/devinet.c Wed Feb 13 13:33:31 2002 *************** *** 919,922 **** --- 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; diff -rc2P linux-2.4.17ctx-7/net/ipv4/raw.c linux-2.4.17ctx-8/net/ipv4/raw.c *** linux-2.4.17ctx-7/net/ipv4/raw.c Tue Jul 10 19:11:43 2001 --- linux-2.4.17ctx-8/net/ipv4/raw.c Thu Feb 21 14:42:39 2002 *************** *** 658,662 **** for (sk = raw_v4_htable[i]; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET) continue; pos += 128; --- 658,662 ---- for (sk = raw_v4_htable[i]; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET || (current->s_context != 1 && sk->s_context != current->s_context)) continue; pos += 128; diff -rc2P linux-2.4.17ctx-7/net/ipv4/tcp_ipv4.c linux-2.4.17ctx-8/net/ipv4/tcp_ipv4.c *** linux-2.4.17ctx-7/net/ipv4/tcp_ipv4.c Sat Dec 22 22:38:46 2001 --- linux-2.4.17ctx-8/net/ipv4/tcp_ipv4.c Thu Feb 21 14:42:39 2002 *************** *** 2074,2077 **** --- 2074,2080 ---- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + if (current->s_context != 1 && sk->s_context != current->s_context) + continue; + if (!TCP_INET_FAMILY(sk->family)) goto skip_listen; *************** *** 2127,2131 **** read_lock(&head->lock); for(sk = head->chain; sk; sk = sk->next, num++) { ! if (!TCP_INET_FAMILY(sk->family)) continue; pos += TMPSZ; --- 2130,2134 ---- read_lock(&head->lock); for(sk = head->chain; sk; sk = sk->next, num++) { ! if (!TCP_INET_FAMILY(sk->family) || (current->s_context != 1 && sk->s_context != current->s_context)) continue; pos += TMPSZ; *************** *** 2142,2146 **** tw != NULL; tw = (struct tcp_tw_bucket *)tw->next, num++) { ! if (!TCP_INET_FAMILY(tw->family)) continue; pos += TMPSZ; --- 2145,2149 ---- tw != NULL; tw = (struct tcp_tw_bucket *)tw->next, num++) { ! if (!TCP_INET_FAMILY(tw->family) || (current->s_context != 1 && tw->s_context != current->s_context)) continue; pos += TMPSZ; diff -rc2P linux-2.4.17ctx-7/net/ipv4/tcp_minisocks.c linux-2.4.17ctx-8/net/ipv4/tcp_minisocks.c *** linux-2.4.17ctx-7/net/ipv4/tcp_minisocks.c Wed Oct 10 11:58:23 2001 --- linux-2.4.17ctx-8/net/ipv4/tcp_minisocks.c Thu Feb 21 14:42:39 2002 *************** *** 382,385 **** --- 382,387 ---- tw->pprev_death = NULL; + tw->s_context = sk->s_context; + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) if(tw->family == PF_INET6) { diff -rc2P linux-2.4.17ctx-7/net/ipv4/udp.c linux-2.4.17ctx-8/net/ipv4/udp.c *** linux-2.4.17ctx-7/net/ipv4/udp.c Wed Oct 31 15:32:46 2001 --- linux-2.4.17ctx-8/net/ipv4/udp.c Thu Feb 21 14:42:39 2002 *************** *** 984,988 **** for (sk = udp_hash[i]; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET) continue; pos += 128; --- 984,988 ---- for (sk = udp_hash[i]; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET || (current->s_context != 1 && sk->s_context != current->s_context)) continue; pos += 128; diff -rc2P linux-2.4.17ctx-7/net/ipv6/raw.c linux-2.4.17ctx-8/net/ipv6/raw.c *** linux-2.4.17ctx-7/net/ipv6/raw.c Thu Sep 20 17:12:56 2001 --- linux-2.4.17ctx-8/net/ipv6/raw.c Thu Feb 21 14:42:39 2002 *************** *** 798,802 **** for (sk = raw_v6_htable[i]; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET6) continue; pos += LINE_LEN+1; --- 798,802 ---- for (sk = raw_v6_htable[i]; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET6 || (current->s_context != 1 && sk->s_context != current->s_context)) continue; pos += LINE_LEN+1; diff -rc2P linux-2.4.17ctx-7/net/ipv6/tcp_ipv6.c linux-2.4.17ctx-8/net/ipv6/tcp_ipv6.c *** linux-2.4.17ctx-7/net/ipv6/tcp_ipv6.c Sat Dec 22 22:38:46 2001 --- linux-2.4.17ctx-8/net/ipv6/tcp_ipv6.c Thu Feb 21 14:42:39 2002 *************** *** 2006,2010 **** struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); ! if (sk->family != PF_INET6) continue; pos += LINE_LEN+1; --- 2006,2010 ---- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); ! if (sk->family != PF_INET6 || (current->s_context != 1 && sk->s_context != current->s_context)) continue; pos += LINE_LEN+1; *************** *** 2056,2060 **** read_lock(&head->lock); for(sk = head->chain; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET6) continue; pos += LINE_LEN+1; --- 2056,2060 ---- read_lock(&head->lock); for(sk = head->chain; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET6 || (current->s_context != 1 && sk->s_context != current->s_context)) continue; pos += LINE_LEN+1; *************** *** 2071,2075 **** tw != NULL; tw = (struct tcp_tw_bucket *)tw->next, num++) { ! if (tw->family != PF_INET6) continue; pos += LINE_LEN+1; --- 2071,2075 ---- tw != NULL; tw = (struct tcp_tw_bucket *)tw->next, num++) { ! if (tw->family != PF_INET6 || (current->s_context != 1 && tw->s_context != current->s_context)) continue; pos += LINE_LEN+1; diff -rc2P linux-2.4.17ctx-7/net/ipv6/udp.c linux-2.4.17ctx-8/net/ipv6/udp.c *** linux-2.4.17ctx-7/net/ipv6/udp.c Fri Sep 7 14:01:21 2001 --- linux-2.4.17ctx-8/net/ipv6/udp.c Thu Feb 21 14:42:39 2002 *************** *** 953,957 **** for (sk = udp_hash[i]; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET6) continue; pos += LINE_LEN+1; --- 953,957 ---- for (sk = udp_hash[i]; sk; sk = sk->next, num++) { ! if (sk->family != PF_INET6 || (current->s_context != 1 && sk->s_context != current->s_context)) continue; pos += LINE_LEN+1; diff -rc2P linux-2.4.17ctx-7/net/unix/af_unix.c linux-2.4.17ctx-8/net/unix/af_unix.c *** linux-2.4.17ctx-7/net/unix/af_unix.c Sat Dec 22 22:38:47 2001 --- linux-2.4.17ctx-8/net/unix/af_unix.c Thu Feb 21 14:42:39 2002 *************** *** 479,482 **** --- 479,484 ---- sk->write_space = unix_write_space; + sk->s_context = current->s_context; + sk->max_ack_backlog = sysctl_unix_max_dgram_qlen; sk->destruct = unix_sock_destructor; *************** *** 1741,1744 **** --- 1743,1749 ---- forall_unix_sockets (i,s) { + if (current->s_context != 1 && s->s_context != current->s_context) + continue; + unix_state_rlock(s);