aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/fs/open.c b/fs/open.c
index 4f01e06227c6..040cef72bc00 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -30,6 +30,9 @@
30#include <linux/audit.h> 30#include <linux/audit.h>
31#include <linux/falloc.h> 31#include <linux/falloc.h>
32#include <linux/fs_struct.h> 32#include <linux/fs_struct.h>
33#include <linux/ima.h>
34
35#include "internal.h"
33 36
34int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) 37int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
35{ 38{
@@ -587,6 +590,9 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
587 error = -EPERM; 590 error = -EPERM;
588 if (!capable(CAP_SYS_CHROOT)) 591 if (!capable(CAP_SYS_CHROOT))
589 goto dput_and_out; 592 goto dput_and_out;
593 error = security_path_chroot(&path);
594 if (error)
595 goto dput_and_out;
590 596
591 set_fs_root(current->fs, &path); 597 set_fs_root(current->fs, &path);
592 error = 0; 598 error = 0;
@@ -617,11 +623,15 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
617 if (err) 623 if (err)
618 goto out_putf; 624 goto out_putf;
619 mutex_lock(&inode->i_mutex); 625 mutex_lock(&inode->i_mutex);
626 err = security_path_chmod(dentry, file->f_vfsmnt, mode);
627 if (err)
628 goto out_unlock;
620 if (mode == (mode_t) -1) 629 if (mode == (mode_t) -1)
621 mode = inode->i_mode; 630 mode = inode->i_mode;
622 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 631 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
623 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 632 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
624 err = notify_change(dentry, &newattrs); 633 err = notify_change(dentry, &newattrs);
634out_unlock:
625 mutex_unlock(&inode->i_mutex); 635 mutex_unlock(&inode->i_mutex);
626 mnt_drop_write(file->f_path.mnt); 636 mnt_drop_write(file->f_path.mnt);
627out_putf: 637out_putf:
@@ -646,11 +656,15 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
646 if (error) 656 if (error)
647 goto dput_and_out; 657 goto dput_and_out;
648 mutex_lock(&inode->i_mutex); 658 mutex_lock(&inode->i_mutex);
659 error = security_path_chmod(path.dentry, path.mnt, mode);
660 if (error)
661 goto out_unlock;
649 if (mode == (mode_t) -1) 662 if (mode == (mode_t) -1)
650 mode = inode->i_mode; 663 mode = inode->i_mode;
651 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 664 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
652 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 665 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
653 error = notify_change(path.dentry, &newattrs); 666 error = notify_change(path.dentry, &newattrs);
667out_unlock:
654 mutex_unlock(&inode->i_mutex); 668 mutex_unlock(&inode->i_mutex);
655 mnt_drop_write(path.mnt); 669 mnt_drop_write(path.mnt);
656dput_and_out: 670dput_and_out:
@@ -664,9 +678,9 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)
664 return sys_fchmodat(AT_FDCWD, filename, mode); 678 return sys_fchmodat(AT_FDCWD, filename, mode);
665} 679}
666 680
667static int chown_common(struct dentry * dentry, uid_t user, gid_t group) 681static int chown_common(struct path *path, uid_t user, gid_t group)
668{ 682{
669 struct inode *inode = dentry->d_inode; 683 struct inode *inode = path->dentry->d_inode;
670 int error; 684 int error;
671 struct iattr newattrs; 685 struct iattr newattrs;
672 686
@@ -683,7 +697,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
683 newattrs.ia_valid |= 697 newattrs.ia_valid |=
684 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; 698 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
685 mutex_lock(&inode->i_mutex); 699 mutex_lock(&inode->i_mutex);
686 error = notify_change(dentry, &newattrs); 700 error = security_path_chown(path, user, group);
701 if (!error)
702 error = notify_change(path->dentry, &newattrs);
687 mutex_unlock(&inode->i_mutex); 703 mutex_unlock(&inode->i_mutex);
688 704
689 return error; 705 return error;
@@ -700,7 +716,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
700 error = mnt_want_write(path.mnt); 716 error = mnt_want_write(path.mnt);
701 if (error) 717 if (error)
702 goto out_release; 718 goto out_release;
703 error = chown_common(path.dentry, user, group); 719 error = chown_common(&path, user, group);
704 mnt_drop_write(path.mnt); 720 mnt_drop_write(path.mnt);
705out_release: 721out_release:
706 path_put(&path); 722 path_put(&path);
@@ -725,7 +741,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
725 error = mnt_want_write(path.mnt); 741 error = mnt_want_write(path.mnt);
726 if (error) 742 if (error)
727 goto out_release; 743 goto out_release;
728 error = chown_common(path.dentry, user, group); 744 error = chown_common(&path, user, group);
729 mnt_drop_write(path.mnt); 745 mnt_drop_write(path.mnt);
730out_release: 746out_release:
731 path_put(&path); 747 path_put(&path);
@@ -744,7 +760,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
744 error = mnt_want_write(path.mnt); 760 error = mnt_want_write(path.mnt);
745 if (error) 761 if (error)
746 goto out_release; 762 goto out_release;
747 error = chown_common(path.dentry, user, group); 763 error = chown_common(&path, user, group);
748 mnt_drop_write(path.mnt); 764 mnt_drop_write(path.mnt);
749out_release: 765out_release:
750 path_put(&path); 766 path_put(&path);
@@ -767,7 +783,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
767 goto out_fput; 783 goto out_fput;
768 dentry = file->f_path.dentry; 784 dentry = file->f_path.dentry;
769 audit_inode(NULL, dentry); 785 audit_inode(NULL, dentry);
770 error = chown_common(dentry, user, group); 786 error = chown_common(&file->f_path, user, group);
771 mnt_drop_write(file->f_path.mnt); 787 mnt_drop_write(file->f_path.mnt);
772out_fput: 788out_fput:
773 fput(file); 789 fput(file);
@@ -805,15 +821,14 @@ static inline int __get_file_write_access(struct inode *inode,
805} 821}
806 822
807static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, 823static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
808 int flags, struct file *f, 824 struct file *f,
809 int (*open)(struct inode *, struct file *), 825 int (*open)(struct inode *, struct file *),
810 const struct cred *cred) 826 const struct cred *cred)
811{ 827{
812 struct inode *inode; 828 struct inode *inode;
813 int error; 829 int error;
814 830
815 f->f_flags = flags; 831 f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
816 f->f_mode = (__force fmode_t)((flags+1) & O_ACCMODE) | FMODE_LSEEK |
817 FMODE_PREAD | FMODE_PWRITE; 832 FMODE_PREAD | FMODE_PWRITE;
818 inode = dentry->d_inode; 833 inode = dentry->d_inode;
819 if (f->f_mode & FMODE_WRITE) { 834 if (f->f_mode & FMODE_WRITE) {
@@ -842,6 +857,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
842 if (error) 857 if (error)
843 goto cleanup_all; 858 goto cleanup_all;
844 } 859 }
860 ima_counts_get(f);
845 861
846 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 862 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
847 863
@@ -913,7 +929,6 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry
913 if (IS_ERR(dentry)) 929 if (IS_ERR(dentry))
914 goto out_err; 930 goto out_err;
915 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), 931 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
916 nd->intent.open.flags - 1,
917 nd->intent.open.file, 932 nd->intent.open.file,
918 open, cred); 933 open, cred);
919out: 934out:
@@ -932,7 +947,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
932 * 947 *
933 * Note that this function destroys the original nameidata 948 * Note that this function destroys the original nameidata
934 */ 949 */
935struct file *nameidata_to_filp(struct nameidata *nd, int flags) 950struct file *nameidata_to_filp(struct nameidata *nd)
936{ 951{
937 const struct cred *cred = current_cred(); 952 const struct cred *cred = current_cred();
938 struct file *filp; 953 struct file *filp;
@@ -941,7 +956,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
941 filp = nd->intent.open.file; 956 filp = nd->intent.open.file;
942 /* Has the filesystem initialised the file for us? */ 957 /* Has the filesystem initialised the file for us? */
943 if (filp->f_path.dentry == NULL) 958 if (filp->f_path.dentry == NULL)
944 filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, 959 filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp,
945 NULL, cred); 960 NULL, cred);
946 else 961 else
947 path_put(&nd->path); 962 path_put(&nd->path);
@@ -980,7 +995,8 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
980 return ERR_PTR(error); 995 return ERR_PTR(error);
981 } 996 }
982 997
983 return __dentry_open(dentry, mnt, flags, f, NULL, cred); 998 f->f_flags = flags;
999 return __dentry_open(dentry, mnt, f, NULL, cred);
984} 1000}
985EXPORT_SYMBOL(dentry_open); 1001EXPORT_SYMBOL(dentry_open);
986 1002