aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c66
1 files changed, 33 insertions, 33 deletions
diff --git a/fs/open.c b/fs/open.c
index 83cdb9dee0c1..d882fd2351d6 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -272,6 +272,8 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
272 goto put_write_and_out; 272 goto put_write_and_out;
273 273
274 error = locks_verify_truncate(inode, NULL, length); 274 error = locks_verify_truncate(inode, NULL, length);
275 if (!error)
276 error = security_path_truncate(&path, length, 0);
275 if (!error) { 277 if (!error) {
276 DQUOT_INIT(inode); 278 DQUOT_INIT(inode);
277 error = do_truncate(path.dentry, length, 0, NULL); 279 error = do_truncate(path.dentry, length, 0, NULL);
@@ -329,6 +331,9 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
329 331
330 error = locks_verify_truncate(inode, file, length); 332 error = locks_verify_truncate(inode, file, length);
331 if (!error) 333 if (!error)
334 error = security_path_truncate(&file->f_path, length,
335 ATTR_MTIME|ATTR_CTIME);
336 if (!error)
332 error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); 337 error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
333out_putf: 338out_putf:
334 fput(file); 339 fput(file);
@@ -407,7 +412,7 @@ asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len)
407 if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) 412 if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
408 goto out_fput; 413 goto out_fput;
409 414
410 if (inode->i_op && inode->i_op->fallocate) 415 if (inode->i_op->fallocate)
411 ret = inode->i_op->fallocate(inode, mode, offset, len); 416 ret = inode->i_op->fallocate(inode, mode, offset, len);
412 else 417 else
413 ret = -EOPNOTSUPP; 418 ret = -EOPNOTSUPP;
@@ -425,39 +430,33 @@ out:
425 */ 430 */
426asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) 431asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
427{ 432{
433 const struct cred *old_cred;
434 struct cred *override_cred;
428 struct path path; 435 struct path path;
429 struct inode *inode; 436 struct inode *inode;
430 int old_fsuid, old_fsgid;
431 kernel_cap_t uninitialized_var(old_cap); /* !SECURE_NO_SETUID_FIXUP */
432 int res; 437 int res;
433 438
434 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 439 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
435 return -EINVAL; 440 return -EINVAL;
436 441
437 old_fsuid = current->fsuid; 442 override_cred = prepare_creds();
438 old_fsgid = current->fsgid; 443 if (!override_cred)
444 return -ENOMEM;
439 445
440 current->fsuid = current->uid; 446 override_cred->fsuid = override_cred->uid;
441 current->fsgid = current->gid; 447 override_cred->fsgid = override_cred->gid;
442 448
443 if (!issecure(SECURE_NO_SETUID_FIXUP)) { 449 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
444 /* 450 /* Clear the capabilities if we switch to a non-root user */
445 * Clear the capabilities if we switch to a non-root user 451 if (override_cred->uid)
446 */ 452 cap_clear(override_cred->cap_effective);
447#ifndef CONFIG_SECURITY_FILE_CAPABILITIES
448 /*
449 * FIXME: There is a race here against sys_capset. The
450 * capabilities can change yet we will restore the old
451 * value below. We should hold task_capabilities_lock,
452 * but we cannot because user_path_at can sleep.
453 */
454#endif /* ndef CONFIG_SECURITY_FILE_CAPABILITIES */
455 if (current->uid)
456 old_cap = cap_set_effective(__cap_empty_set);
457 else 453 else
458 old_cap = cap_set_effective(current->cap_permitted); 454 override_cred->cap_effective =
455 override_cred->cap_permitted;
459 } 456 }
460 457
458 old_cred = override_creds(override_cred);
459
461 res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); 460 res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
462 if (res) 461 if (res)
463 goto out; 462 goto out;
@@ -494,12 +493,8 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
494out_path_release: 493out_path_release:
495 path_put(&path); 494 path_put(&path);
496out: 495out:
497 current->fsuid = old_fsuid; 496 revert_creds(old_cred);
498 current->fsgid = old_fsgid; 497 put_cred(override_cred);
499
500 if (!issecure(SECURE_NO_SETUID_FIXUP))
501 cap_set_effective(old_cap);
502
503 return res; 498 return res;
504} 499}
505 500
@@ -792,7 +787,8 @@ static inline int __get_file_write_access(struct inode *inode,
792 787
793static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, 788static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
794 int flags, struct file *f, 789 int flags, struct file *f,
795 int (*open)(struct inode *, struct file *)) 790 int (*open)(struct inode *, struct file *),
791 const struct cred *cred)
796{ 792{
797 struct inode *inode; 793 struct inode *inode;
798 int error; 794 int error;
@@ -816,7 +812,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
816 f->f_op = fops_get(inode->i_fop); 812 f->f_op = fops_get(inode->i_fop);
817 file_move(f, &inode->i_sb->s_files); 813 file_move(f, &inode->i_sb->s_files);
818 814
819 error = security_dentry_open(f); 815 error = security_dentry_open(f, cred);
820 if (error) 816 if (error)
821 goto cleanup_all; 817 goto cleanup_all;
822 818
@@ -891,6 +887,8 @@ cleanup_file:
891struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, 887struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
892 int (*open)(struct inode *, struct file *)) 888 int (*open)(struct inode *, struct file *))
893{ 889{
890 const struct cred *cred = current_cred();
891
894 if (IS_ERR(nd->intent.open.file)) 892 if (IS_ERR(nd->intent.open.file))
895 goto out; 893 goto out;
896 if (IS_ERR(dentry)) 894 if (IS_ERR(dentry))
@@ -898,7 +896,7 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry
898 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), 896 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
899 nd->intent.open.flags - 1, 897 nd->intent.open.flags - 1,
900 nd->intent.open.file, 898 nd->intent.open.file,
901 open); 899 open, cred);
902out: 900out:
903 return nd->intent.open.file; 901 return nd->intent.open.file;
904out_err: 902out_err:
@@ -917,6 +915,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
917 */ 915 */
918struct file *nameidata_to_filp(struct nameidata *nd, int flags) 916struct file *nameidata_to_filp(struct nameidata *nd, int flags)
919{ 917{
918 const struct cred *cred = current_cred();
920 struct file *filp; 919 struct file *filp;
921 920
922 /* Pick up the filp from the open intent */ 921 /* Pick up the filp from the open intent */
@@ -924,7 +923,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
924 /* Has the filesystem initialised the file for us? */ 923 /* Has the filesystem initialised the file for us? */
925 if (filp->f_path.dentry == NULL) 924 if (filp->f_path.dentry == NULL)
926 filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, 925 filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp,
927 NULL); 926 NULL, cred);
928 else 927 else
929 path_put(&nd->path); 928 path_put(&nd->path);
930 return filp; 929 return filp;
@@ -934,7 +933,8 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
934 * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an 933 * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
935 * error. 934 * error.
936 */ 935 */
937struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) 936struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
937 const struct cred *cred)
938{ 938{
939 int error; 939 int error;
940 struct file *f; 940 struct file *f;
@@ -959,7 +959,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
959 return ERR_PTR(error); 959 return ERR_PTR(error);
960 } 960 }
961 961
962 return __dentry_open(dentry, mnt, flags, f, NULL); 962 return __dentry_open(dentry, mnt, flags, f, NULL, cred);
963} 963}
964EXPORT_SYMBOL(dentry_open); 964EXPORT_SYMBOL(dentry_open);
965 965