aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2009-11-21 21:49:55 -0500
committerJames Morris <jmorris@namei.org>2009-11-23 16:49:26 -0500
commitfe542cf59bf0b31afe72b9e9749c0f6645419fa0 (patch)
treefcb1273863e96f4dd8206578f59ccaabceb46415 /fs/open.c
parent85c3b529f8ad4d65ba86b982ef050212ae7dd976 (diff)
LSM: Move security_path_chmod()/security_path_chown() to after mutex_lock().
We should call security_path_chmod()/security_path_chown() after mutex_lock() in order to avoid races. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Acked-by: John Johansen <john.johansen@canonical.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c36
1 files changed, 15 insertions, 21 deletions
diff --git a/fs/open.c b/fs/open.c
index 201041dfca57..b4b31d277f3a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -619,17 +619,17 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
619 err = mnt_want_write_file(file); 619 err = mnt_want_write_file(file);
620 if (err) 620 if (err)
621 goto out_putf; 621 goto out_putf;
622 mutex_lock(&inode->i_mutex);
622 err = security_path_chmod(dentry, file->f_vfsmnt, mode); 623 err = security_path_chmod(dentry, file->f_vfsmnt, mode);
623 if (err) 624 if (err)
624 goto out_drop_write; 625 goto out_unlock;
625 mutex_lock(&inode->i_mutex);
626 if (mode == (mode_t) -1) 626 if (mode == (mode_t) -1)
627 mode = inode->i_mode; 627 mode = inode->i_mode;
628 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 628 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
629 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 629 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
630 err = notify_change(dentry, &newattrs); 630 err = notify_change(dentry, &newattrs);
631out_unlock:
631 mutex_unlock(&inode->i_mutex); 632 mutex_unlock(&inode->i_mutex);
632out_drop_write:
633 mnt_drop_write(file->f_path.mnt); 633 mnt_drop_write(file->f_path.mnt);
634out_putf: 634out_putf:
635 fput(file); 635 fput(file);
@@ -652,17 +652,17 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
652 error = mnt_want_write(path.mnt); 652 error = mnt_want_write(path.mnt);
653 if (error) 653 if (error)
654 goto dput_and_out; 654 goto dput_and_out;
655 mutex_lock(&inode->i_mutex);
655 error = security_path_chmod(path.dentry, path.mnt, mode); 656 error = security_path_chmod(path.dentry, path.mnt, mode);
656 if (error) 657 if (error)
657 goto out_drop_write; 658 goto out_unlock;
658 mutex_lock(&inode->i_mutex);
659 if (mode == (mode_t) -1) 659 if (mode == (mode_t) -1)
660 mode = inode->i_mode; 660 mode = inode->i_mode;
661 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 661 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
662 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 662 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
663 error = notify_change(path.dentry, &newattrs); 663 error = notify_change(path.dentry, &newattrs);
664out_unlock:
664 mutex_unlock(&inode->i_mutex); 665 mutex_unlock(&inode->i_mutex);
665out_drop_write:
666 mnt_drop_write(path.mnt); 666 mnt_drop_write(path.mnt);
667dput_and_out: 667dput_and_out:
668 path_put(&path); 668 path_put(&path);
@@ -675,9 +675,9 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)
675 return sys_fchmodat(AT_FDCWD, filename, mode); 675 return sys_fchmodat(AT_FDCWD, filename, mode);
676} 676}
677 677
678static int chown_common(struct dentry * dentry, uid_t user, gid_t group) 678static int chown_common(struct path *path, uid_t user, gid_t group)
679{ 679{
680 struct inode *inode = dentry->d_inode; 680 struct inode *inode = path->dentry->d_inode;
681 int error; 681 int error;
682 struct iattr newattrs; 682 struct iattr newattrs;
683 683
@@ -694,7 +694,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
694 newattrs.ia_valid |= 694 newattrs.ia_valid |=
695 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; 695 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
696 mutex_lock(&inode->i_mutex); 696 mutex_lock(&inode->i_mutex);
697 error = notify_change(dentry, &newattrs); 697 error = security_path_chown(path, user, group);
698 if (!error)
699 error = notify_change(path->dentry, &newattrs);
698 mutex_unlock(&inode->i_mutex); 700 mutex_unlock(&inode->i_mutex);
699 701
700 return error; 702 return error;
@@ -711,9 +713,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
711 error = mnt_want_write(path.mnt); 713 error = mnt_want_write(path.mnt);
712 if (error) 714 if (error)
713 goto out_release; 715 goto out_release;
714 error = security_path_chown(&path, user, group); 716 error = chown_common(&path, user, group);
715 if (!error)
716 error = chown_common(path.dentry, user, group);
717 mnt_drop_write(path.mnt); 717 mnt_drop_write(path.mnt);
718out_release: 718out_release:
719 path_put(&path); 719 path_put(&path);
@@ -738,9 +738,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
738 error = mnt_want_write(path.mnt); 738 error = mnt_want_write(path.mnt);
739 if (error) 739 if (error)
740 goto out_release; 740 goto out_release;
741 error = security_path_chown(&path, user, group); 741 error = chown_common(&path, user, group);
742 if (!error)
743 error = chown_common(path.dentry, user, group);
744 mnt_drop_write(path.mnt); 742 mnt_drop_write(path.mnt);
745out_release: 743out_release:
746 path_put(&path); 744 path_put(&path);
@@ -759,9 +757,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
759 error = mnt_want_write(path.mnt); 757 error = mnt_want_write(path.mnt);
760 if (error) 758 if (error)
761 goto out_release; 759 goto out_release;
762 error = security_path_chown(&path, user, group); 760 error = chown_common(&path, user, group);
763 if (!error)
764 error = chown_common(path.dentry, user, group);
765 mnt_drop_write(path.mnt); 761 mnt_drop_write(path.mnt);
766out_release: 762out_release:
767 path_put(&path); 763 path_put(&path);
@@ -784,9 +780,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
784 goto out_fput; 780 goto out_fput;
785 dentry = file->f_path.dentry; 781 dentry = file->f_path.dentry;
786 audit_inode(NULL, dentry); 782 audit_inode(NULL, dentry);
787 error = security_path_chown(&file->f_path, user, group); 783 error = chown_common(&file->f_path, user, group);
788 if (!error)
789 error = chown_common(dentry, user, group);
790 mnt_drop_write(file->f_path.mnt); 784 mnt_drop_write(file->f_path.mnt);
791out_fput: 785out_fput:
792 fput(file); 786 fput(file);