This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / fs / namei.c
index 656430d..34da5b4 100644 (file)
@@ -165,10 +165,6 @@ int vfs_permission(struct inode * inode, int mask)
 {
        umode_t                 mode = inode->i_mode;
 
-       /* Prevent vservers from escaping chroot() barriers */
-       if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN))
-               return -EACCES;
-
        if (mask & MAY_WRITE) {
                /*
                 * Nobody gets write access to a read-only fs.
@@ -214,6 +210,20 @@ int vfs_permission(struct inode * inode, int mask)
        return -EACCES;
 }
 
+static inline int xid_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+       if (inode->i_xid == 0)
+               return 0;
+       if (vx_check(inode->i_xid, VX_ADMIN|VX_WATCH|VX_IDENT))
+               return 0;
+/*
+       printk("VSW: xid=%d denied access to %p[#%d,%lu] »%*s«.\n",
+               vx_current_xid(), inode, inode->i_xid, inode->i_ino,
+               nd->dentry->d_name.len, nd->dentry->d_name.name);
+*/
+       return -EACCES;
+}
+
 int permission(struct inode * inode,int mask, struct nameidata *nd)
 {
        int retval;
@@ -227,6 +237,8 @@ int permission(struct inode * inode,int mask, struct nameidata *nd)
                (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
                return -EROFS;
 
+       if ((retval = xid_permission(inode, mask, nd)))
+               return retval;
        if (inode->i_op && inode->i_op->permission)
                retval = inode->i_op->permission(inode, submask, nd);
        else
@@ -2013,13 +2025,8 @@ asmlinkage long sys_link(const char __user * oldname, const char __user * newnam
        error = path_lookup(to, LOOKUP_PARENT, &nd);
        if (error)
                goto out;
-       /*
-        * We allow hard-links to be created to a bind-mount as long
-        * as the bind-mount is not read-only.  Checking for cross-dev
-        * links is subsumed by the superblock check in vfs_link().
-        */
-       error = -EROFS;
-       if (MNT_IS_RDONLY(old_nd.mnt))
+       error = -EXDEV;
+       if (old_nd.mnt != nd.mnt)
                goto out_release;
        new_dentry = lookup_create(&nd, 0);
        error = PTR_ERR(new_dentry);