diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/Makefile linux-2.4.25-rc1-vs1.3.7/Makefile
--- linux-2.4.25-rc1-vs1.3.6/Makefile	2004-02-09 11:37:28.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/Makefile	2004-02-09 12:43:48.000000000 +0100
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 25
-EXTRAVERSION = -rc1-vs1.3.6
+EXTRAVERSION = -rc1-vs1.3.7
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/fs/namei.c linux-2.4.25-rc1-vs1.3.7/fs/namei.c
--- linux-2.4.25-rc1-vs1.3.6/fs/namei.c	2004-02-09 11:37:14.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/fs/namei.c	2004-02-09 12:43:49.000000000 +0100
@@ -151,16 +151,10 @@ char * getname(const char * filename)
  */
 int vfs_permission(struct inode * inode, int mask)
 {
-	umode_t			mode = inode->i_mode;
+	umode_t	mode = inode->i_mode;
 
-	/*
-		A dir with permission bit all 0s is a dead zone for
-		process running in a vserver. By doing
-			chmod 000 /vservers
-		you fix the "escape from chroot" bug.
-	*/
-	if ((mode & 0777) == 0 && S_ISDIR(mode)
-		&& !vx_check(0, VX_ADMIN))
+	if (IS_BARRIER(inode) && S_ISDIR(mode) &&
+		!vx_check(0, VX_ADMIN|VX_WATCH))
 		return -EACCES;
 	if (mask & MAY_WRITE) {
 		/*
diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/fs/open.c linux-2.4.25-rc1-vs1.3.7/fs/open.c
--- linux-2.4.25-rc1-vs1.3.6/fs/open.c	2004-02-06 00:45:54.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/fs/open.c	2004-02-09 12:43:48.000000000 +0100
@@ -489,6 +489,10 @@ asmlinkage long sys_fchmod(unsigned int 
 	dentry = file->f_dentry;
 	inode = dentry->d_inode;
 
+	err = -EPERM;
+        if (S_ISDIR(inode->i_mode) &&
+		IS_BARRIER(inode) && !vx_check(0, VX_ADMIN))
+		goto out_putf;	
 	err = -EROFS;
 	if (IS_RDONLY(inode))
 		goto out_putf;
@@ -519,6 +523,11 @@ asmlinkage long sys_chmod(const char * f
 		goto out;
 	inode = nd.dentry->d_inode;
 
+	error = -EPERM;
+        if (S_ISDIR(inode->i_mode) &&
+		IS_BARRIER(inode) && !vx_check(0, VX_ADMIN))
+		goto dput_and_out;	
+
 	error = -EROFS;
 	if (IS_RDONLY(inode))
 		goto dput_and_out;
diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/fs/proc/generic.c linux-2.4.25-rc1-vs1.3.7/fs/proc/generic.c
--- linux-2.4.25-rc1-vs1.3.6/fs/proc/generic.c	2004-02-09 11:37:14.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/fs/proc/generic.c	2004-02-09 12:43:49.000000000 +0100
@@ -17,6 +17,7 @@
 #define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/vinline.h>
+#include <linux/vserver/inode.h>
 #include <asm/bitops.h>
 
 static ssize_t proc_file_read(struct file * file, char * buf,
@@ -266,6 +267,12 @@ struct dentry *proc_lookup(struct inode 
 				continue;
 			if (de->namelen != dentry->d_name.len)
 				continue;
+			if (!vx_check(0, VX_ADMIN|VX_WATCH) &&
+				(de->vx_flags & IATTR_TRIGGER)) {
+				printk("··· trigger: »%*s«\n",
+					dentry->d_name.len, dentry->d_name.name);
+				de->vx_flags &= ~IATTR_TRIGGER;
+			}
 			if (!vx_weak_check(0, de->vx_flags))
 				continue;
 			if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/include/linux/vserver/inode.h linux-2.4.25-rc1-vs1.3.7/include/linux/vserver/inode.h
--- linux-2.4.25-rc1-vs1.3.6/include/linux/vserver/inode.h	2004-02-09 11:37:15.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/include/linux/vserver/inode.h	2004-02-09 12:44:05.000000000 +0100
@@ -24,6 +24,7 @@ struct  vcmd_ctx_iattr_v0 {
 #define IATTR_HIDE	0x00000004
 #define IATTR_FLAGS	0x00000007
 
+#define IATTR_TRIGGER	0x00000010
 #define IATTR_BARRIER	0x00010000
 #define	IATTR_IUNLINK	0x00020000
 
diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/include/net/route.h linux-2.4.25-rc1-vs1.3.7/include/net/route.h
--- linux-2.4.25-rc1-vs1.3.6/include/net/route.h	2004-02-09 11:37:15.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/include/net/route.h	2004-02-09 12:46:29.000000000 +0100
@@ -164,46 +164,72 @@ static inline char rt_tos2priority(u8 to
 	return ip_tos2prio[IPTOS_TOS(tos)>>1];
 }
 
-static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif)
+
+#define IPI_LOOPBACK	0x0100007f
+
+static inline int ip_find_src(struct ip_info *ipi,
+	struct rtable **rp, u32 *src, u32 dst, u32 tos, int oif)
 {
 	int err;
-	struct ip_info *ip_info = current->ip_info;
-	if (ip_info != NULL) {
-		__u32 ipv4root = ip_info->ipv4[0];
-		if (ipv4root != 0) {
-			int n = ip_info->nbipv4;
-			if (dst == 0x0100007f && !vx_check(0, VX_ADMIN))
-				dst = ipv4root;
-			if (src == 0) {
-				if (n > 1) {
-					u32 foundsrc;
-					int i;
-					err = ip_route_output(rp, dst, src, tos, oif);
-					if (err) return err;
-					foundsrc = (*rp)->rt_src;
-					ip_rt_put(*rp);
-					for (i=0; i<n; i++){
-						u32 mask = ip_info->mask[i];
-						u32 ipv4 = ip_info->ipv4[i];
-						u32 netipv4 = ipv4 & mask;
-						if ((foundsrc & mask) == netipv4) {
-							src = ipv4;
-							break;
-						}
-					}
-				}
-				if (src == 0)
-					src = dst == 0x0100007f
-						? 0x0100007f: ipv4root;
-			} else {
-				int i;
-				for (i=0; i<n; i++) {
-					if (ip_info->ipv4[i] == src) break;
+	int i, n = ipi->nbipv4;
+        u32 ipv4root = ipi->ipv4[0];
+	
+	if (ipv4root == 0)
+		return 0;
+		
+	if (*src == 0) {
+		if (n > 1) {
+			u32 foundsrc;
+
+			err = ip_route_output(rp, dst, *src, tos, oif);
+			if (err) {
+				*src = ipv4root;
+				err = ip_route_output(rp, dst, *src, tos, oif);
+			}
+			if (err)
+				return err;
+
+			foundsrc = (*rp)->rt_src;
+			ip_rt_put(*rp);
+
+			for (i=0; i<n; i++){
+				u32 mask = ipi->mask[i];
+				u32 ipv4 = ipi->ipv4[i];
+				u32 net4 = ipv4 & mask;
+
+				if (foundsrc == ipv4) {
+					*src = ipv4;
+					break;
 				}
-				if (i == n)
-					return -EPERM;
+				if (!*src && (foundsrc & mask) == net4)
+					*src = ipv4;
 			}
 		}
+		if (*src == 0)
+			*src = (dst == IPI_LOOPBACK)
+				? IPI_LOOPBACK : ipv4root;
+	} else {
+                for (i=0; i<n; i++) {
+                        if (ipi->ipv4[i] == *src)
+				break;
+                }
+                if (i == n)
+                        return -EPERM;
+        }
+	return 0;
+}
+
+
+static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif)
+{
+	int err;
+	struct ip_info *ip_info = current->ip_info;
+	if (ip_info != NULL) {
+		err = ip_find_src(ip_info, rp, &src, dst, tos, oif);
+		if (err)
+			return err;
+		if (dst == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
+			dst = ip_info->ipv4[0];
 	}
 	err = ip_route_output(rp, dst, src, tos, oif);
 	if (err || (dst && src))
diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/kernel/fork.c linux-2.4.25-rc1-vs1.3.7/kernel/fork.c
--- linux-2.4.25-rc1-vs1.3.6/kernel/fork.c	2004-02-09 11:37:15.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/kernel/fork.c	2004-02-09 12:43:49.000000000 +0100
@@ -666,9 +666,9 @@ int do_fork(unsigned long clone_flags, u
 		goto fork_out;
 
 	retval = -EAGAIN;
-	vxi = get_vx_info(current->vx_info);
-	get_ip_info(current->ip_info);
 	*p = *current;
+	vxi = get_vx_info(p->vx_info);
+	get_ip_info(p->ip_info);
 
 	if (vxi && (atomic_read(&vxi->limit.res[RLIMIT_NPROC])
 		>= vxi->limit.rlim[RLIMIT_NPROC]))
diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/kernel/vserver/context.c linux-2.4.25-rc1-vs1.3.7/kernel/vserver/context.c
--- linux-2.4.25-rc1-vs1.3.6/kernel/vserver/context.c	2004-02-09 11:37:15.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/kernel/vserver/context.c	2004-02-09 12:43:49.000000000 +0100
@@ -10,6 +10,7 @@
  *  V0.03  replaced context_info calls
  *  V0.04  redesign of struct (de)alloc
  *  V0.05  rlimit basic implementation
+ *  V0.06  task_xid and info commands
  *
  */
 
@@ -178,20 +179,22 @@ out_unlock:
 
 int vc_task_xid(uint32_t id, void *data)
 {
-	if (!vx_check(0, VX_ADMIN))
-		return -ENOSYS;
-	switch (id) {
-	case 0:
-		break;
-		
-	case -1:
-		break;
-		
-	default:
-		break;
-	
-	}
-	return 0;
+        xid_t xid;
+
+        if (id) {
+                struct task_struct *tsk;
+
+                if (!vx_check(0, VX_ADMIN|VX_WATCH))
+                        return -EPERM;
+
+                read_lock(&tasklist_lock);
+                tsk = find_task_by_pid(id);
+                xid = (tsk) ? tsk->xid : -ESRCH;
+                read_unlock(&tasklist_lock);
+        }
+        else
+                xid = current->xid;
+        return xid;
 }
 
 
diff -NurpP --minimal linux-2.4.25-rc1-vs1.3.6/net/ipv4/udp.c linux-2.4.25-rc1-vs1.3.7/net/ipv4/udp.c
--- linux-2.4.25-rc1-vs1.3.6/net/ipv4/udp.c	2004-02-09 11:37:15.000000000 +0100
+++ linux-2.4.25-rc1-vs1.3.7/net/ipv4/udp.c	2004-02-09 12:43:49.000000000 +0100
@@ -554,14 +554,11 @@ int udp_sendmsg(struct sock *sk, struct 
 		struct ip_info *ip_info = current->ip_info;
 
 		if (ip_info != NULL) {
-			__u32 ipv4root = ip_info->ipv4[0];
-			if (ipv4root) {
-				if (daddr == 0x0100007f &&
-					!vx_check(0, VX_ADMIN))
-					daddr = ipv4root;
-				if (ufh.saddr == 0)
-					ufh.saddr = ipv4root;
-			}
+			err = ip_find_src(ip_info, &rt, &ufh.saddr, daddr, tos, ipc.oif);
+			if (err)
+				goto out;
+			if (daddr == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
+				daddr = ip_info->ipv4[0];
 		}
 		err = ip_route_output(&rt, daddr, ufh.saddr, tos, ipc.oif);
 		if (err)
