diff options
| author | Miklos Szeredi <mszeredi@suse.cz> | 2008-07-01 09:01:29 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-26 20:53:28 -0400 |
| commit | beb29e058c35ab69e96e455a12ccf7505f6de425 (patch) | |
| tree | 0da9869b7e0422c34423a02216db1a758a55a95a | |
| parent | b1da47e29e467f1ec36dc78d009bfb109fd533c7 (diff) | |
[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>
| -rw-r--r-- | fs/attr.c | 5 | ||||
| -rw-r--r-- | fs/open.c | 24 | ||||
| -rw-r--r-- | fs/utimes.c | 4 |
3 files changed, 7 insertions, 26 deletions
| @@ -108,6 +108,11 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
| 108 | struct timespec now; | 108 | struct timespec now; |
| 109 | unsigned int ia_valid = attr->ia_valid; | 109 | unsigned int ia_valid = attr->ia_valid; |
| 110 | 110 | ||
| 111 | if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) { | ||
| 112 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | ||
| 113 | return -EPERM; | ||
| 114 | } | ||
| 115 | |||
| 111 | now = current_fs_time(inode->i_sb); | 116 | now = current_fs_time(inode->i_sb); |
| 112 | 117 | ||
| 113 | attr->ia_ctime = now; | 118 | attr->ia_ctime = now; |
| @@ -588,9 +588,6 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
| 588 | err = mnt_want_write(file->f_path.mnt); | 588 | err = mnt_want_write(file->f_path.mnt); |
| 589 | if (err) | 589 | if (err) |
| 590 | goto out_putf; | 590 | goto out_putf; |
| 591 | err = -EPERM; | ||
| 592 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | ||
| 593 | goto out_drop_write; | ||
| 594 | mutex_lock(&inode->i_mutex); | 591 | mutex_lock(&inode->i_mutex); |
| 595 | if (mode == (mode_t) -1) | 592 | if (mode == (mode_t) -1) |
| 596 | mode = inode->i_mode; | 593 | mode = inode->i_mode; |
| @@ -598,8 +595,6 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
| 598 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 595 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
| 599 | err = notify_change(dentry, &newattrs); | 596 | err = notify_change(dentry, &newattrs); |
| 600 | mutex_unlock(&inode->i_mutex); | 597 | mutex_unlock(&inode->i_mutex); |
| 601 | |||
| 602 | out_drop_write: | ||
| 603 | mnt_drop_write(file->f_path.mnt); | 598 | mnt_drop_write(file->f_path.mnt); |
| 604 | out_putf: | 599 | out_putf: |
| 605 | fput(file); | 600 | fput(file); |
| @@ -623,11 +618,6 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename, | |||
| 623 | error = mnt_want_write(nd.path.mnt); | 618 | error = mnt_want_write(nd.path.mnt); |
| 624 | if (error) | 619 | if (error) |
| 625 | goto dput_and_out; | 620 | goto dput_and_out; |
| 626 | |||
| 627 | error = -EPERM; | ||
| 628 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | ||
| 629 | goto out_drop_write; | ||
| 630 | |||
| 631 | mutex_lock(&inode->i_mutex); | 621 | mutex_lock(&inode->i_mutex); |
| 632 | if (mode == (mode_t) -1) | 622 | if (mode == (mode_t) -1) |
| 633 | mode = inode->i_mode; | 623 | mode = inode->i_mode; |
| @@ -635,8 +625,6 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename, | |||
| 635 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 625 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
| 636 | error = notify_change(nd.path.dentry, &newattrs); | 626 | error = notify_change(nd.path.dentry, &newattrs); |
| 637 | mutex_unlock(&inode->i_mutex); | 627 | mutex_unlock(&inode->i_mutex); |
| 638 | |||
| 639 | out_drop_write: | ||
| 640 | mnt_drop_write(nd.path.mnt); | 628 | mnt_drop_write(nd.path.mnt); |
| 641 | dput_and_out: | 629 | dput_and_out: |
| 642 | path_put(&nd.path); | 630 | path_put(&nd.path); |
| @@ -651,18 +639,10 @@ asmlinkage long sys_chmod(const char __user *filename, mode_t mode) | |||
| 651 | 639 | ||
| 652 | static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | 640 | static int chown_common(struct dentry * dentry, uid_t user, gid_t group) |
| 653 | { | 641 | { |
| 654 | struct inode * inode; | 642 | struct inode *inode = dentry->d_inode; |
| 655 | int error; | 643 | int error; |
| 656 | struct iattr newattrs; | 644 | struct iattr newattrs; |
| 657 | 645 | ||
| 658 | error = -ENOENT; | ||
| 659 | if (!(inode = dentry->d_inode)) { | ||
| 660 | printk(KERN_ERR "chown_common: NULL inode\n"); | ||
| 661 | goto out; | ||
| 662 | } | ||
| 663 | error = -EPERM; | ||
| 664 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | ||
| 665 | goto out; | ||
| 666 | newattrs.ia_valid = ATTR_CTIME; | 646 | newattrs.ia_valid = ATTR_CTIME; |
| 667 | if (user != (uid_t) -1) { | 647 | if (user != (uid_t) -1) { |
| 668 | newattrs.ia_valid |= ATTR_UID; | 648 | newattrs.ia_valid |= ATTR_UID; |
| @@ -678,7 +658,7 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | |||
| 678 | mutex_lock(&inode->i_mutex); | 658 | mutex_lock(&inode->i_mutex); |
| 679 | error = notify_change(dentry, &newattrs); | 659 | error = notify_change(dentry, &newattrs); |
| 680 | mutex_unlock(&inode->i_mutex); | 660 | mutex_unlock(&inode->i_mutex); |
| 681 | out: | 661 | |
| 682 | return error; | 662 | return error; |
| 683 | } | 663 | } |
| 684 | 664 | ||
diff --git a/fs/utimes.c b/fs/utimes.c index 8e09dbdfd7f5..dad679d3a158 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
| @@ -64,10 +64,6 @@ static int utimes_common(struct path *path, struct timespec *times) | |||
| 64 | 64 | ||
| 65 | newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; | 65 | newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; |
| 66 | if (times) { | 66 | if (times) { |
| 67 | error = -EPERM; | ||
| 68 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
| 69 | goto mnt_drop_write_and_out; | ||
| 70 | |||
| 71 | if (times[0].tv_nsec == UTIME_OMIT) | 67 | if (times[0].tv_nsec == UTIME_OMIT) |
| 72 | newattrs.ia_valid &= ~ATTR_ATIME; | 68 | newattrs.ia_valid &= ~ATTR_ATIME; |
| 73 | else if (times[0].tv_nsec != UTIME_NOW) { | 69 | else if (times[0].tv_nsec != UTIME_NOW) { |
