From: Herbert Pƶtzl <[EMAIL PROTECTED]>

Previously, the vfs functions did not enforce per-vfsmount flags such
as read-only.  Wherever we use the macro IS_RDONLY, we also need to
use MNT_IS_RDONLY on the corresponding vfsmount structure.

Acked-by: Sam Vilain <[EMAIL PROTECTED]>
---

 fs/namei.c |    8 ++++++--
 fs/open.c  |   13 +++++++------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 89cccf5..6af1461 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -235,7 +235,7 @@ int permission(struct inode *inode, int 
                /*
                 * Nobody gets write access to a read-only fs.
                 */
-               if (IS_RDONLY(inode) &&
+               if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
                    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
                        return -EROFS;
 
@@ -1508,7 +1508,8 @@ int may_open(struct nameidata *nd, int a
                        return -EACCES;
 
                flag &= ~O_TRUNC;
-       } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
+       } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
+               && (flag & FMODE_WRITE))
                return -EROFS;
        /*
         * An append-only file must be opened in append mode for writing.
@@ -2475,6 +2476,9 @@ static int do_rename(int olddfd, const c
        error = -EINVAL;
        if (old_dentry == trap)
                goto exit4;
+       error = -EROFS;
+       if (MNT_IS_RDONLY(newnd.mnt))
+               goto exit4;
        new_dentry = lookup_hash(&newnd);
        error = PTR_ERR(new_dentry);
        if (IS_ERR(new_dentry))
diff --git a/fs/open.c b/fs/open.c
index 8632721..3e7aea4 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -248,7 +248,7 @@ static long do_sys_truncate(const char _
                goto dput_and_out;
 
        error = -EROFS;
-       if (IS_RDONLY(inode))
+       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
                goto dput_and_out;
 
        error = -EPERM;
@@ -372,7 +372,7 @@ asmlinkage long sys_utime(char __user * 
        inode = nd.dentry->d_inode;
 
        error = -EROFS;
-       if (IS_RDONLY(inode))
+       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
                goto dput_and_out;
 
        /* Don't worry, the checks are done in inode_change_ok() */
@@ -429,7 +429,7 @@ long do_utimes(int dfd, char __user *fil
        inode = nd.dentry->d_inode;
 
        error = -EROFS;
-       if (IS_RDONLY(inode))
+       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
                goto dput_and_out;
 
        /* Don't worry, the checks are done in inode_change_ok() */
@@ -516,7 +516,8 @@ asmlinkage long sys_faccessat(int dfd, c
        if (!res) {
                res = vfs_permission(&nd, mode);
                /* SuS v2 requires we report a read only fs too */
-               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
+               if(!res && (mode & S_IWOTH)
+                  && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
                   && !special_file(nd.dentry->d_inode->i_mode))
                        res = -EROFS;
                path_release(&nd);
@@ -627,7 +628,7 @@ asmlinkage long sys_fchmod(unsigned int 
        inode = dentry->d_inode;
 
        err = -EROFS;
-       if (IS_RDONLY(inode))
+       if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
                goto out_putf;
        err = -EPERM;
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
@@ -660,7 +661,7 @@ asmlinkage long sys_fchmodat(int dfd, co
        inode = nd.dentry->d_inode;
 
        error = -EROFS;
-       if (IS_RDONLY(inode))
+       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
                goto dput_and_out;
 
        error = -EPERM;

_______________________________________________
Vserver mailing list
[email protected]
http://list.linux-vserver.org/mailman/listinfo/vserver

Reply via email to