From: Herbert Pƶtzl <[EMAIL PROTECTED]

Previously, permissions were only per-inode.  As permissions may now
be per-vfsmount, any previous checks for inodes being read-only via
the IS_RDONLY() macro and not via VFS functions like permission() must
now be extended to also check the mount permissions with
MNT_IS_RDONLY().

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

 arch/sparc64/solaris/fs.c |    4 ++--
 fs/ext2/ioctl.c           |    7 +++++--
 fs/ext3/ioctl.c           |   16 +++++++++++-----
 fs/hfsplus/ioctl.c        |    3 ++-
 fs/nfs/dir.c              |    3 ++-
 fs/nfsd/vfs.c             |    6 ++++--
 fs/reiserfs/ioctl.c       |    7 +++++--
 7 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 4885ca6..612477d 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -363,7 +363,7 @@ static int report_statvfs(struct vfsmoun
                int j = strlen (p);
                
                if (j > 15) j = 15;
-               if (IS_RDONLY(inode)) i = 1;
+               if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
                if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
                if (!sysv_valid_dev(inode->i_sb->s_dev))
                        return -EOVERFLOW;
@@ -399,7 +399,7 @@ static int report_statvfs64(struct vfsmo
                int j = strlen (p);
                
                if (j > 15) j = 15;
-               if (IS_RDONLY(inode)) i = 1;
+               if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
                if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
                if (!sysv_valid_dev(inode->i_sb->s_dev))
                        return -EOVERFLOW;
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index 3ca9afd..8f1c64a 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -11,6 +11,7 @@
 #include <linux/capability.h>
 #include <linux/time.h>
 #include <linux/sched.h>
+#include <linux/mount.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 
@@ -30,7 +31,8 @@ int ext2_ioctl (struct inode * inode, st
        case EXT2_IOC_SETFLAGS: {
                unsigned int oldflags;
 
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
 
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -69,7 +71,8 @@ int ext2_ioctl (struct inode * inode, st
        case EXT2_IOC_SETVERSION:
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
                        return -EPERM;
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
                if (get_user(inode->i_generation, (int __user *) arg))
                        return -EFAULT; 
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 556cd55..2b83f7e 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -8,6 +8,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/mount.h>
 #include <linux/jbd.h>
 #include <linux/capability.h>
 #include <linux/ext3_fs.h>
@@ -36,7 +37,8 @@ int ext3_ioctl (struct inode * inode, st
                unsigned int oldflags;
                unsigned int jflag;
 
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
 
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -112,7 +114,8 @@ flags_err:
 
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
                        return -EPERM;
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
                if (get_user(generation, (int __user *) arg))
                        return -EFAULT;
@@ -166,7 +169,8 @@ flags_err:
                if (!test_opt(inode->i_sb, RESERVATION) 
||!S_ISREG(inode->i_mode))
                        return -ENOTTY;
 
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
 
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -201,7 +205,8 @@ flags_err:
                if (!capable(CAP_SYS_RESOURCE))
                        return -EPERM;
 
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
 
                if (get_user(n_blocks_count, (__u32 __user *)arg))
@@ -222,7 +227,8 @@ flags_err:
                if (!capable(CAP_SYS_RESOURCE))
                        return -EPERM;
 
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
 
                if (copy_from_user(&input, (struct ext3_new_group_input __user 
*)arg,
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c
index 13cf848..73cc849 100644
--- a/fs/hfsplus/ioctl.c
+++ b/fs/hfsplus/ioctl.c
@@ -35,7 +35,8 @@ int hfsplus_ioctl(struct inode *inode, s
                        flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */
                return put_user(flags, (int __user *)arg);
        case HFSPLUS_IOC_EXT2_SETFLAGS: {
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
 
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index a1554be..e78b606 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -902,7 +902,8 @@ static int is_atomic_open(struct inode *
        if (nd->flags & LOOKUP_DIRECTORY)
                return 0;
        /* Are we trying to write to a read only partition? */
-       if (IS_RDONLY(dir) && (nd->intent.open.flags & 
(O_CREAT|O_TRUNC|FMODE_WRITE)))
+       if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
+               (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
                return 0;
        return 1;
 }
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 6fe2491..bbc74f4 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1772,7 +1772,8 @@ nfsd_permission(struct svc_export *exp, 
                inode->i_mode,
                IS_IMMUTABLE(inode)?    " immut" : "",
                IS_APPEND(inode)?       " append" : "",
-               IS_RDONLY(inode)?       " ro" : "");
+               (IS_RDONLY(inode)|| MNT_IS_RDONLY(exp->ex_mnt))
+               ?                       " ro" : "");
        dprintk("      owner %d/%d user %d/%d\n",
                inode->i_uid, inode->i_gid, current->fsuid, current->fsgid);
 #endif
@@ -1783,7 +1784,8 @@ nfsd_permission(struct svc_export *exp, 
         */
        if (!(acc & MAY_LOCAL_ACCESS))
                if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
-                       if (EX_RDONLY(exp) || IS_RDONLY(inode))
+                       if (EX_RDONLY(exp) || IS_RDONLY(inode)
+                               || MNT_IS_RDONLY(exp->ex_mnt))
                                return nfserr_rofs;
                        if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
                                return nfserr_perm;
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 745c881..cd5b6e8 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -4,6 +4,7 @@
 
 #include <linux/capability.h>
 #include <linux/fs.h>
+#include <linux/mount.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/time.h>
 #include <asm/uaccess.h>
@@ -47,7 +48,8 @@ int reiserfs_ioctl(struct inode *inode, 
                        if (!reiserfs_attrs(inode->i_sb))
                                return -ENOTTY;
 
-                       if (IS_RDONLY(inode))
+                       if (IS_RDONLY(inode) ||
+                               (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                                return -EROFS;
 
                        if ((current->fsuid != inode->i_uid)
@@ -82,7 +84,8 @@ int reiserfs_ioctl(struct inode *inode, 
        case REISERFS_IOC_SETVERSION:
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
                        return -EPERM;
-               if (IS_RDONLY(inode))
+               if (IS_RDONLY(inode) ||
+                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
                        return -EROFS;
                if (get_user(inode->i_generation, (int __user *)arg))
                        return -EFAULT;

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

Reply via email to