diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2008-04-28 02:16:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 08:58:47 -0700 |
commit | e97e8de388723f9491514fa0434ddf1fd713a188 (patch) | |
tree | 582513162e3e9406a02d6de8a09af76da3839400 | |
parent | 1278fdd34b12214b5c2e91e64848a5e54e57ed96 (diff) | |
download | op-kernel-dev-e97e8de388723f9491514fa0434ddf1fd713a188.zip op-kernel-dev-e97e8de388723f9491514fa0434ddf1fd713a188.tar.gz |
fat: fat_setattr() fix
Fix fat_setattr() on the case of showexec option. If user specified
showexec option, inode->i_mode may not have S_IXUGO. This just use
inode->i_mode to fix it.
And with this patch, we don't allow chmod() on memory inode, it's just
bad behaviour. IOW, we allow changing S_IWUGO only which can be stored
to disk.
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/fat/file.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/fs/fat/file.c b/fs/fat/file.c index b61a98f..e73f13a 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -257,7 +257,8 @@ int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) } EXPORT_SYMBOL_GPL(fat_getattr); -static int fat_check_mode(const struct msdos_sb_info *sbi, mode_t mode) +static int fat_check_mode(const struct msdos_sb_info *sbi, struct inode *inode, + mode_t mode) { mode_t mask, req = mode & ~S_IFMT; @@ -271,7 +272,7 @@ static int fat_check_mode(const struct msdos_sb_info *sbi, mode_t mode) * w bits, either all (subject to umask) or none must be present. */ req &= ~mask; - if ((req & (S_IRUGO | S_IXUGO)) != ((S_IRUGO | S_IXUGO) & ~mask)) + if ((req & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) return -EPERM; if ((req & S_IWUGO) && ((req & S_IWUGO) != (S_IWUGO & ~mask))) return -EPERM; @@ -310,7 +311,9 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) if (((attr->ia_valid & ATTR_UID) && (attr->ia_uid != sbi->options.fs_uid)) || ((attr->ia_valid & ATTR_GID) && - (attr->ia_gid != sbi->options.fs_gid))) + (attr->ia_gid != sbi->options.fs_gid)) || + ((attr->ia_valid & ATTR_MODE) && + fat_check_mode(sbi, inode, attr->ia_mode) < 0)) error = -EPERM; if (error) { @@ -319,12 +322,6 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) goto out; } - if (attr->ia_valid & ATTR_MODE) { - error = fat_check_mode(sbi, attr->ia_mode); - if (error != 0 && !sbi->options.quiet) - goto out; - } - error = inode_setattr(inode, attr); if (error) goto out; |