[patch 4/4] vfs: immutable inode checking cleanup
Move the immutable and append-only checks from chmod, chown and utimes into notify_change(). Checks for immutable and append-only files are always performed by the VFS and not by the filesystem (see permission() and may_...() in namei.c), so these belong in notify_change(), and not in inode_change_ok(). This should be completely equivalent. CC: Ulrich Drepper <drepper@redhat.com> CC: Michael Kerrisk <mtk.manpages@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
b1da47e29e
commit
beb29e058c
3 changed files with 7 additions and 26 deletions
|
@ -108,6 +108,11 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
|
|||
struct timespec now;
|
||||
unsigned int ia_valid = attr->ia_valid;
|
||||
|
||||
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
now = current_fs_time(inode->i_sb);
|
||||
|
||||
attr->ia_ctime = now;
|
||||
|
|
24
fs/open.c
24
fs/open.c
|
@ -588,9 +588,6 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
|
|||
err = mnt_want_write(file->f_path.mnt);
|
||||
if (err)
|
||||
goto out_putf;
|
||||
err = -EPERM;
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
goto out_drop_write;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
if (mode == (mode_t) -1)
|
||||
mode = inode->i_mode;
|
||||
|
@ -598,8 +595,6 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
|
|||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
err = notify_change(dentry, &newattrs);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
out_drop_write:
|
||||
mnt_drop_write(file->f_path.mnt);
|
||||
out_putf:
|
||||
fput(file);
|
||||
|
@ -623,11 +618,6 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename,
|
|||
error = mnt_want_write(nd.path.mnt);
|
||||
if (error)
|
||||
goto dput_and_out;
|
||||
|
||||
error = -EPERM;
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
goto out_drop_write;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
if (mode == (mode_t) -1)
|
||||
mode = inode->i_mode;
|
||||
|
@ -635,8 +625,6 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename,
|
|||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
error = notify_change(nd.path.dentry, &newattrs);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
out_drop_write:
|
||||
mnt_drop_write(nd.path.mnt);
|
||||
dput_and_out:
|
||||
path_put(&nd.path);
|
||||
|
@ -651,18 +639,10 @@ asmlinkage long sys_chmod(const char __user *filename, mode_t mode)
|
|||
|
||||
static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
|
||||
{
|
||||
struct inode * inode;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
struct iattr newattrs;
|
||||
|
||||
error = -ENOENT;
|
||||
if (!(inode = dentry->d_inode)) {
|
||||
printk(KERN_ERR "chown_common: NULL inode\n");
|
||||
goto out;
|
||||
}
|
||||
error = -EPERM;
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
goto out;
|
||||
newattrs.ia_valid = ATTR_CTIME;
|
||||
if (user != (uid_t) -1) {
|
||||
newattrs.ia_valid |= ATTR_UID;
|
||||
|
@ -678,7 +658,7 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
|
|||
mutex_lock(&inode->i_mutex);
|
||||
error = notify_change(dentry, &newattrs);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
out:
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,10 +64,6 @@ static int utimes_common(struct path *path, struct timespec *times)
|
|||
|
||||
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
|
||||
if (times) {
|
||||
error = -EPERM;
|
||||
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
|
||||
goto mnt_drop_write_and_out;
|
||||
|
||||
if (times[0].tv_nsec == UTIME_OMIT)
|
||||
newattrs.ia_valid &= ~ATTR_ATIME;
|
||||
else if (times[0].tv_nsec != UTIME_NOW) {
|
||||
|
|
Loading…
Reference in a new issue