diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 31 |
1 files changed, 21 insertions, 10 deletions
@@ -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); |
1840 | fail: | 1851 | fail: |
1841 | return retval; | 1852 | return retval; |