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 <asm/io.h>
#include <asm/processor.h>
+ #include <asm/unistd.h>
/* 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
[email protected])
+ *
+ * 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);