aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/fs/open.c b/fs/open.c
index f96eaab280a3..c0a426d5766c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -425,30 +425,33 @@ out:
425 */ 425 */
426asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) 426asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
427{ 427{
428 struct cred *cred = current->cred; 428 const struct cred *old_cred;
429 struct cred *override_cred;
429 struct path path; 430 struct path path;
430 struct inode *inode; 431 struct inode *inode;
431 int old_fsuid, old_fsgid;
432 kernel_cap_t uninitialized_var(old_cap); /* !SECURE_NO_SETUID_FIXUP */
433 int res; 432 int res;
434 433
435 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 434 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
436 return -EINVAL; 435 return -EINVAL;
437 436
438 old_fsuid = cred->fsuid; 437 override_cred = prepare_creds();
439 old_fsgid = cred->fsgid; 438 if (!override_cred)
439 return -ENOMEM;
440 440
441 cred->fsuid = cred->uid; 441 override_cred->fsuid = override_cred->uid;
442 cred->fsgid = cred->gid; 442 override_cred->fsgid = override_cred->gid;
443 443
444 if (!issecure(SECURE_NO_SETUID_FIXUP)) { 444 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
445 /* Clear the capabilities if we switch to a non-root user */ 445 /* Clear the capabilities if we switch to a non-root user */
446 if (current->cred->uid) 446 if (override_cred->uid)
447 old_cap = cap_set_effective(__cap_empty_set); 447 cap_clear(override_cred->cap_effective);
448 else 448 else
449 old_cap = cap_set_effective(cred->cap_permitted); 449 override_cred->cap_effective =
450 override_cred->cap_permitted;
450 } 451 }
451 452
453 old_cred = override_creds(override_cred);
454
452 res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); 455 res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
453 if (res) 456 if (res)
454 goto out; 457 goto out;
@@ -485,12 +488,8 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
485out_path_release: 488out_path_release:
486 path_put(&path); 489 path_put(&path);
487out: 490out:
488 cred->fsuid = old_fsuid; 491 revert_creds(old_cred);
489 cred->fsgid = old_fsgid; 492 put_cred(override_cred);
490
491 if (!issecure(SECURE_NO_SETUID_FIXUP))
492 cap_set_effective(old_cap);
493
494 return res; 493 return res;
495} 494}
496 495