Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

exec.c: fix coredump to pipe problem and obscure "security hole"

The patch checks for "|" in the pattern not the output and doesn't nail a
pid on to a piped name (as it is a program name not a file)

Also fixes a very very obscure security corner case. If you happen to have
decided on a core pattern that starts with the program name then the user
can run a program called "|myevilhack" as it stands. I doubt anyone does
this.

Signed-off-by: Alan Cox <alan@redhat.com>
Confirmed-by: Christopher S. Aker <caker@theshore.net>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Alan Cox and committed by
Linus Torvalds
c4bbafda c4b7e875

+11 -7
+11 -7
fs/exec.c
··· 1244 1244 * name into corename, which must have space for at least 1245 1245 * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. 1246 1246 */ 1247 - static void format_corename(char *corename, const char *pattern, long signr) 1247 + static int format_corename(char *corename, const char *pattern, long signr) 1248 1248 { 1249 1249 const char *pat_ptr = pattern; 1250 1250 char *out_ptr = corename; 1251 1251 char *const out_end = corename + CORENAME_MAX_SIZE; 1252 1252 int rc; 1253 1253 int pid_in_pattern = 0; 1254 + int ispipe = 0; 1255 + 1256 + if (*pattern == '|') 1257 + ispipe = 1; 1254 1258 1255 1259 /* Repeat as long as we have more pattern to process and more output 1256 1260 space */ ··· 1345 1341 * 1346 1342 * If core_pattern does not include a %p (as is the default) 1347 1343 * and core_uses_pid is set, then .%pid will be appended to 1348 - * the filename */ 1349 - if (!pid_in_pattern 1344 + * the filename. Do not do this for piped commands. */ 1345 + if (!ispipe && !pid_in_pattern 1350 1346 && (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) { 1351 1347 rc = snprintf(out_ptr, out_end - out_ptr, 1352 1348 ".%d", current->tgid); ··· 1354 1350 goto out; 1355 1351 out_ptr += rc; 1356 1352 } 1357 - out: 1353 + out: 1358 1354 *out_ptr = 0; 1355 + return ispipe; 1359 1356 } 1360 1357 1361 1358 static void zap_process(struct task_struct *start) ··· 1507 1502 * uses lock_kernel() 1508 1503 */ 1509 1504 lock_kernel(); 1510 - format_corename(corename, core_pattern, signr); 1505 + ispipe = format_corename(corename, core_pattern, signr); 1511 1506 unlock_kernel(); 1512 - if (corename[0] == '|') { 1507 + if (ispipe) { 1513 1508 /* SIGPIPE can happen, but it's just never processed */ 1514 1509 if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) { 1515 1510 printk(KERN_INFO "Core dump to %s pipe failed\n", 1516 1511 corename); 1517 1512 goto fail_unlock; 1518 1513 } 1519 - ispipe = 1; 1520 1514 } else 1521 1515 file = filp_open(corename, 1522 1516 O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,