Skip to content

Commit

Permalink
[patch 4/4] vfs: immutable inode checking cleanup
Browse files Browse the repository at this point in the history
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 <[email protected]>
CC: Michael Kerrisk <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Miklos Szeredi authored and Al Viro committed Jul 27, 2008
1 parent b1da47e commit beb29e0
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 26 deletions.
5 changes: 5 additions & 0 deletions fs/attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
24 changes: 2 additions & 22 deletions fs/open.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,18 +588,13 @@ 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;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
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);
Expand All @@ -623,20 +618,13 @@ 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;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
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);
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down
4 changes: 0 additions & 4 deletions fs/utimes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit beb29e0

Please sign in to comment.