aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/fs/exec.c b/fs/exec.c
index e95aeeddd25c..3684353ebd5f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -2002,17 +2002,17 @@ static void coredump_finish(struct mm_struct *mm)
2002void set_dumpable(struct mm_struct *mm, int value) 2002void set_dumpable(struct mm_struct *mm, int value)
2003{ 2003{
2004 switch (value) { 2004 switch (value) {
2005 case 0: 2005 case SUID_DUMPABLE_DISABLED:
2006 clear_bit(MMF_DUMPABLE, &mm->flags); 2006 clear_bit(MMF_DUMPABLE, &mm->flags);
2007 smp_wmb(); 2007 smp_wmb();
2008 clear_bit(MMF_DUMP_SECURELY, &mm->flags); 2008 clear_bit(MMF_DUMP_SECURELY, &mm->flags);
2009 break; 2009 break;
2010 case 1: 2010 case SUID_DUMPABLE_ENABLED:
2011 set_bit(MMF_DUMPABLE, &mm->flags); 2011 set_bit(MMF_DUMPABLE, &mm->flags);
2012 smp_wmb(); 2012 smp_wmb();
2013 clear_bit(MMF_DUMP_SECURELY, &mm->flags); 2013 clear_bit(MMF_DUMP_SECURELY, &mm->flags);
2014 break; 2014 break;
2015 case 2: 2015 case SUID_DUMPABLE_SAFE:
2016 set_bit(MMF_DUMP_SECURELY, &mm->flags); 2016 set_bit(MMF_DUMP_SECURELY, &mm->flags);
2017 smp_wmb(); 2017 smp_wmb();
2018 set_bit(MMF_DUMPABLE, &mm->flags); 2018 set_bit(MMF_DUMPABLE, &mm->flags);
@@ -2025,7 +2025,7 @@ static int __get_dumpable(unsigned long mm_flags)
2025 int ret; 2025 int ret;
2026 2026
2027 ret = mm_flags & MMF_DUMPABLE_MASK; 2027 ret = mm_flags & MMF_DUMPABLE_MASK;
2028 return (ret >= 2) ? 2 : ret; 2028 return (ret > SUID_DUMPABLE_ENABLED) ? SUID_DUMPABLE_SAFE : ret;
2029} 2029}
2030 2030
2031int get_dumpable(struct mm_struct *mm) 2031int get_dumpable(struct mm_struct *mm)
@@ -2111,6 +2111,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
2111 int retval = 0; 2111 int retval = 0;
2112 int flag = 0; 2112 int flag = 0;
2113 int ispipe; 2113 int ispipe;
2114 bool need_nonrelative = false;
2114 static atomic_t core_dump_count = ATOMIC_INIT(0); 2115 static atomic_t core_dump_count = ATOMIC_INIT(0);
2115 struct coredump_params cprm = { 2116 struct coredump_params cprm = {
2116 .signr = signr, 2117 .signr = signr,
@@ -2136,14 +2137,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
2136 if (!cred) 2137 if (!cred)
2137 goto fail; 2138 goto fail;
2138 /* 2139 /*
2139 * We cannot trust fsuid as being the "true" uid of the 2140 * We cannot trust fsuid as being the "true" uid of the process
2140 * process nor do we know its entire history. We only know it 2141 * nor do we know its entire history. We only know it was tainted
2141 * was tainted so we dump it as root in mode 2. 2142 * so we dump it as root in mode 2, and only into a controlled
2143 * environment (pipe handler or fully qualified path).
2142 */ 2144 */
2143 if (__get_dumpable(cprm.mm_flags) == 2) { 2145 if (__get_dumpable(cprm.mm_flags) == SUID_DUMPABLE_SAFE) {
2144 /* Setuid core dump mode */ 2146 /* Setuid core dump mode */
2145 flag = O_EXCL; /* Stop rewrite attacks */ 2147 flag = O_EXCL; /* Stop rewrite attacks */
2146 cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */ 2148 cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */
2149 need_nonrelative = true;
2147 } 2150 }
2148 2151
2149 retval = coredump_wait(exit_code, &core_state); 2152 retval = coredump_wait(exit_code, &core_state);
@@ -2171,15 +2174,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
2171 } 2174 }
2172 2175
2173 if (cprm.limit == 1) { 2176 if (cprm.limit == 1) {
2174 /* 2177 /* See umh_pipe_setup() which sets RLIMIT_CORE = 1.
2178 *
2175 * Normally core limits are irrelevant to pipes, since 2179 * Normally core limits are irrelevant to pipes, since
2176 * we're not writing to the file system, but we use 2180 * we're not writing to the file system, but we use
2177 * cprm.limit of 1 here as a speacial value. Any 2181 * cprm.limit of 1 here as a speacial value, this is a
2178 * non-1 limit gets set to RLIM_INFINITY below, but 2182 * consistent way to catch recursive crashes.
2179 * a limit of 0 skips the dump. This is a consistent 2183 * We can still crash if the core_pattern binary sets
2180 * way to catch recursive crashes. We can still crash 2184 * RLIM_CORE = !1, but it runs as root, and can do
2181 * if the core_pattern binary sets RLIM_CORE = !1 2185 * lots of stupid things.
2182 * but it runs as root, and can do lots of stupid things 2186 *
2183 * Note that we use task_tgid_vnr here to grab the pid 2187 * Note that we use task_tgid_vnr here to grab the pid
2184 * of the process group leader. That way we get the 2188 * of the process group leader. That way we get the
2185 * right pid if a thread in a multi-threaded 2189 * right pid if a thread in a multi-threaded
@@ -2223,6 +2227,14 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
2223 if (cprm.limit < binfmt->min_coredump) 2227 if (cprm.limit < binfmt->min_coredump)
2224 goto fail_unlock; 2228 goto fail_unlock;
2225 2229
2230 if (need_nonrelative && cn.corename[0] != '/') {
2231 printk(KERN_WARNING "Pid %d(%s) can only dump core "\
2232 "to fully qualified path!\n",
2233 task_tgid_vnr(current), current->comm);
2234 printk(KERN_WARNING "Skipping core dump\n");
2235 goto fail_unlock;
2236 }
2237
2226 cprm.file = filp_open(cn.corename, 2238 cprm.file = filp_open(cn.corename,
2227 O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 2239 O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
2228 0600); 2240 0600);