From: Herbert Pƶtzl <herbert@13thfloor.at>
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 <sam.vilain@catalyst.net.nz>
---
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
Vserver@list.linux-vserver.org
http://list.linux-vserver.org/mailman/listinfo/vserver
Received on Mon Feb 27 05:51:27 2006