aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/open.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/fs/open.c b/fs/open.c
index 4f01e06227c6..74e5cd9f718e 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -8,10 +8,8 @@
8#include <linux/mm.h> 8#include <linux/mm.h>
9#include <linux/file.h> 9#include <linux/file.h>
10#include <linux/fdtable.h> 10#include <linux/fdtable.h>
11#include <linux/quotaops.h>
12#include <linux/fsnotify.h> 11#include <linux/fsnotify.h>
13#include <linux/module.h> 12#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/tty.h> 13#include <linux/tty.h>
16#include <linux/namei.h> 14#include <linux/namei.h>
17#include <linux/backing-dev.h> 15#include <linux/backing-dev.h>
@@ -21,6 +19,7 @@
21#include <linux/mount.h> 19#include <linux/mount.h>
22#include <linux/vfs.h> 20#include <linux/vfs.h>
23#include <linux/fcntl.h> 21#include <linux/fcntl.h>
22#include <linux/slab.h>
24#include <asm/uaccess.h> 23#include <asm/uaccess.h>
25#include <linux/fs.h> 24#include <linux/fs.h>
26#include <linux/personality.h> 25#include <linux/personality.h>
@@ -30,6 +29,9 @@
30#include <linux/audit.h> 29#include <linux/audit.h>
31#include <linux/falloc.h> 30#include <linux/falloc.h>
32#include <linux/fs_struct.h> 31#include <linux/fs_struct.h>
32#include <linux/ima.h>
33
34#include "internal.h"
33 35
34int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) 36int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
35{ 37{
@@ -268,17 +270,15 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
268 * Make sure that there are no leases. get_write_access() protects 270 * Make sure that there are no leases. get_write_access() protects
269 * against the truncate racing with a lease-granting setlease(). 271 * against the truncate racing with a lease-granting setlease().
270 */ 272 */
271 error = break_lease(inode, FMODE_WRITE); 273 error = break_lease(inode, O_WRONLY);
272 if (error) 274 if (error)
273 goto put_write_and_out; 275 goto put_write_and_out;
274 276
275 error = locks_verify_truncate(inode, NULL, length); 277 error = locks_verify_truncate(inode, NULL, length);
276 if (!error) 278 if (!error)
277 error = security_path_truncate(&path, length, 0); 279 error = security_path_truncate(&path, length, 0);
278 if (!error) { 280 if (!error)
279 vfs_dq_init(inode);
280 error = do_truncate(path.dentry, length, 0, NULL); 281 error = do_truncate(path.dentry, length, 0, NULL);
281 }
282 282
283put_write_and_out: 283put_write_and_out:
284 put_write_access(inode); 284 put_write_access(inode);
@@ -587,6 +587,9 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
587 error = -EPERM; 587 error = -EPERM;
588 if (!capable(CAP_SYS_CHROOT)) 588 if (!capable(CAP_SYS_CHROOT))
589 goto dput_and_out; 589 goto dput_and_out;
590 error = security_path_chroot(&path);
591 if (error)
592 goto dput_and_out;
590 593
591 set_fs_root(current->fs, &path); 594 set_fs_root(current->fs, &path);
592 error = 0; 595 error = 0;
@@ -617,11 +620,15 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
617 if (err) 620 if (err)
618 goto out_putf; 621 goto out_putf;
619 mutex_lock(&inode->i_mutex); 622 mutex_lock(&inode->i_mutex);
623 err = security_path_chmod(dentry, file->f_vfsmnt, mode);
624 if (err)
625 goto out_unlock;
620 if (mode == (mode_t) -1) 626 if (mode == (mode_t) -1)
621 mode = inode->i_mode; 627 mode = inode->i_mode;
622 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 628 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
623 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 629 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
624 err = notify_change(dentry, &newattrs); 630 err = notify_change(dentry, &newattrs);
631out_unlock:
625 mutex_unlock(&inode->i_mutex); 632 mutex_unlock(&inode->i_mutex);
626 mnt_drop_write(file->f_path.mnt); 633 mnt_drop_write(file->f_path.mnt);
627out_putf: 634out_putf:
@@ -646,11 +653,15 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
646 if (error) 653 if (error)
647 goto dput_and_out; 654 goto dput_and_out;
648 mutex_lock(&inode->i_mutex); 655 mutex_lock(&inode->i_mutex);
656 error = security_path_chmod(path.dentry, path.mnt, mode);
657 if (error)
658 goto out_unlock;
649 if (mode == (mode_t) -1) 659 if (mode == (mode_t) -1)
650 mode = inode->i_mode; 660 mode = inode->i_mode;
651 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 661 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
652 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 662 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
653 error = notify_change(path.dentry, &newattrs); 663 error = notify_change(path.dentry, &newattrs);
664out_unlock:
654 mutex_unlock(&inode->i_mutex); 665 mutex_unlock(&inode->i_mutex);
655 mnt_drop_write(path.mnt); 666 mnt_drop_write(path.mnt);
656dput_and_out: 667dput_and_out:
@@ -664,9 +675,9 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)
664 return sys_fchmodat(AT_FDCWD, filename, mode); 675 return sys_fchmodat(AT_FDCWD, filename, mode);
665} 676}
666 677
667static 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)
668{ 679{
669 struct inode *inode = dentry->d_inode; 680 struct inode *inode = path->dentry->d_inode;
670 int error; 681 int error;
671 struct iattr newattrs; 682 struct iattr newattrs;
672 683
@@ -683,7 +694,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
683 newattrs.ia_valid |= 694 newattrs.ia_valid |=
684 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; 695 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
685 mutex_lock(&inode->i_mutex); 696 mutex_lock(&inode->i_mutex);
686 error = notify_change(dentry, &newattrs); 697 error = security_path_chown(path, user, group);
698 if (!error)
699 error = notify_change(path->dentry, &newattrs);
687 mutex_unlock(&inode->i_mutex); 700 mutex_unlock(&inode->i_mutex);
688 701
689 return error; 702 return error;
@@ -700,7 +713,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
700 error = mnt_want_write(path.mnt); 713 error = mnt_want_write(path.mnt);
701 if (error) 714 if (error)
702 goto out_release; 715 goto out_release;
703 error = chown_common(path.dentry, user, group); 716 error = chown_common(&path, user, group);
704 mnt_drop_write(path.mnt); 717 mnt_drop_write(path.mnt);
705out_release: 718out_release:
706 path_put(&path); 719 path_put(&path);
@@ -725,7 +738,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
725 error = mnt_want_write(path.mnt); 738 error = mnt_want_write(path.mnt);
726 if (error) 739 if (error)
727 goto out_release; 740 goto out_release;
728 error = chown_common(path.dentry, user, group); 741 error = chown_common(&path, user, group);
729 mnt_drop_write(path.mnt); 742 mnt_drop_write(path.mnt);
730out_release: 743out_release:
731 path_put(&path); 744 path_put(&path);
@@ -744,7 +757,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
744 error = mnt_want_write(path.mnt); 757 error = mnt_want_write(path.mnt);
745 if (error) 758 if (error)
746 goto out_release; 759 goto out_release;
747 error = chown_common(path.dentry, user, group); 760 error = chown_common(&path, user, group);
748 mnt_drop_write(path.mnt); 761 mnt_drop_write(path.mnt);
749out_release: 762out_release:
750 path_put(&path); 763 path_put(&path);
@@ -767,7 +780,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
767 goto out_fput; 780 goto out_fput;
768 dentry = file->f_path.dentry; 781 dentry = file->f_path.dentry;
769 audit_inode(NULL, dentry); 782 audit_inode(NULL, dentry);
770 error = chown_common(dentry, user, group); 783 error = chown_common(&file->f_path, user, group);
771 mnt_drop_write(file->f_path.mnt); 784 mnt_drop_write(file->f_path.mnt);
772out_fput: 785out_fput:
773 fput(file); 786 fput(file);
@@ -805,15 +818,14 @@ static inline int __get_file_write_access(struct inode *inode,
805} 818}
806 819
807static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, 820static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
808 int flags, struct file *f, 821 struct file *f,
809 int (*open)(struct inode *, struct file *), 822 int (*open)(struct inode *, struct file *),
810 const struct cred *cred) 823 const struct cred *cred)
811{ 824{
812 struct inode *inode; 825 struct inode *inode;
813 int error; 826 int error;
814 827
815 f->f_flags = flags; 828 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; 829 FMODE_PREAD | FMODE_PWRITE;
818 inode = dentry->d_inode; 830 inode = dentry->d_inode;
819 if (f->f_mode & FMODE_WRITE) { 831 if (f->f_mode & FMODE_WRITE) {
@@ -842,6 +854,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
842 if (error) 854 if (error)
843 goto cleanup_all; 855 goto cleanup_all;
844 } 856 }
857 ima_counts_get(f);
845 858
846 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 859 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
847 860
@@ -913,7 +926,6 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry
913 if (IS_ERR(dentry)) 926 if (IS_ERR(dentry))
914 goto out_err; 927 goto out_err;
915 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), 928 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
916 nd->intent.open.flags - 1,
917 nd->intent.open.file, 929 nd->intent.open.file,
918 open, cred); 930 open, cred);
919out: 931out:
@@ -932,7 +944,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
932 * 944 *
933 * Note that this function destroys the original nameidata 945 * Note that this function destroys the original nameidata
934 */ 946 */
935struct file *nameidata_to_filp(struct nameidata *nd, int flags) 947struct file *nameidata_to_filp(struct nameidata *nd)
936{ 948{
937 const struct cred *cred = current_cred(); 949 const struct cred *cred = current_cred();
938 struct file *filp; 950 struct file *filp;
@@ -941,7 +953,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
941 filp = nd->intent.open.file; 953 filp = nd->intent.open.file;
942 /* Has the filesystem initialised the file for us? */ 954 /* Has the filesystem initialised the file for us? */
943 if (filp->f_path.dentry == NULL) 955 if (filp->f_path.dentry == NULL)
944 filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, 956 filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp,
945 NULL, cred); 957 NULL, cred);
946 else 958 else
947 path_put(&nd->path); 959 path_put(&nd->path);
@@ -980,7 +992,8 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
980 return ERR_PTR(error); 992 return ERR_PTR(error);
981 } 993 }
982 994
983 return __dentry_open(dentry, mnt, flags, f, NULL, cred); 995 f->f_flags = flags;
996 return __dentry_open(dentry, mnt, f, NULL, cred);
984} 997}
985EXPORT_SYMBOL(dentry_open); 998EXPORT_SYMBOL(dentry_open);
986 999