aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/fs/exec.c b/fs/exec.c
index a5330e1a2216..9bd3559ddece 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1007,13 +1007,12 @@ int flush_old_exec(struct linux_binprm * bprm)
1007 */ 1007 */
1008 current->mm->task_size = TASK_SIZE; 1008 current->mm->task_size = TASK_SIZE;
1009 1009
1010 if (bprm->e_uid != current_euid() || bprm->e_gid != current_egid()) { 1010 if (bprm->e_uid != current_euid() ||
1011 suid_keys(current); 1011 bprm->e_gid != current_egid()) {
1012 set_dumpable(current->mm, suid_dumpable); 1012 set_dumpable(current->mm, suid_dumpable);
1013 current->pdeath_signal = 0; 1013 current->pdeath_signal = 0;
1014 } else if (file_permission(bprm->file, MAY_READ) || 1014 } else if (file_permission(bprm->file, MAY_READ) ||
1015 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { 1015 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
1016 suid_keys(current);
1017 set_dumpable(current->mm, suid_dumpable); 1016 set_dumpable(current->mm, suid_dumpable);
1018 } 1017 }
1019 1018
@@ -1096,10 +1095,8 @@ void compute_creds(struct linux_binprm *bprm)
1096{ 1095{
1097 int unsafe; 1096 int unsafe;
1098 1097
1099 if (bprm->e_uid != current_uid()) { 1098 if (bprm->e_uid != current_uid())
1100 suid_keys(current);
1101 current->pdeath_signal = 0; 1099 current->pdeath_signal = 0;
1102 }
1103 exec_keys(current); 1100 exec_keys(current);
1104 1101
1105 task_lock(current); 1102 task_lock(current);
@@ -1709,8 +1706,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1709 struct linux_binfmt * binfmt; 1706 struct linux_binfmt * binfmt;
1710 struct inode * inode; 1707 struct inode * inode;
1711 struct file * file; 1708 struct file * file;
1709 const struct cred *old_cred;
1710 struct cred *cred;
1712 int retval = 0; 1711 int retval = 0;
1713 int fsuid = current_fsuid();
1714 int flag = 0; 1712 int flag = 0;
1715 int ispipe = 0; 1713 int ispipe = 0;
1716 unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; 1714 unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
@@ -1723,12 +1721,20 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1723 binfmt = current->binfmt; 1721 binfmt = current->binfmt;
1724 if (!binfmt || !binfmt->core_dump) 1722 if (!binfmt || !binfmt->core_dump)
1725 goto fail; 1723 goto fail;
1724
1725 cred = prepare_creds();
1726 if (!cred) {
1727 retval = -ENOMEM;
1728 goto fail;
1729 }
1730
1726 down_write(&mm->mmap_sem); 1731 down_write(&mm->mmap_sem);
1727 /* 1732 /*
1728 * If another thread got here first, or we are not dumpable, bail out. 1733 * If another thread got here first, or we are not dumpable, bail out.
1729 */ 1734 */
1730 if (mm->core_state || !get_dumpable(mm)) { 1735 if (mm->core_state || !get_dumpable(mm)) {
1731 up_write(&mm->mmap_sem); 1736 up_write(&mm->mmap_sem);
1737 put_cred(cred);
1732 goto fail; 1738 goto fail;
1733 } 1739 }
1734 1740
@@ -1739,12 +1745,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1739 */ 1745 */
1740 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ 1746 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
1741 flag = O_EXCL; /* Stop rewrite attacks */ 1747 flag = O_EXCL; /* Stop rewrite attacks */
1742 current->cred->fsuid = 0; /* Dump root private */ 1748 cred->fsuid = 0; /* Dump root private */
1743 } 1749 }
1744 1750
1745 retval = coredump_wait(exit_code, &core_state); 1751 retval = coredump_wait(exit_code, &core_state);
1746 if (retval < 0) 1752 if (retval < 0) {
1753 put_cred(cred);
1747 goto fail; 1754 goto fail;
1755 }
1756
1757 old_cred = override_creds(cred);
1748 1758
1749 /* 1759 /*
1750 * Clear any false indication of pending signals that might 1760 * Clear any false indication of pending signals that might
@@ -1835,7 +1845,8 @@ fail_unlock:
1835 if (helper_argv) 1845 if (helper_argv)
1836 argv_free(helper_argv); 1846 argv_free(helper_argv);
1837 1847
1838 current->cred->fsuid = fsuid; 1848 revert_creds(old_cred);
1849 put_cred(cred);
1839 coredump_finish(mm); 1850 coredump_finish(mm);
1840fail: 1851fail:
1841 return retval; 1852 return retval;