diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 23 |
1 files changed, 18 insertions, 5 deletions
@@ -58,7 +58,7 @@ | |||
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | int core_uses_pid; | 60 | int core_uses_pid; |
61 | char core_pattern[65] = "core"; | 61 | char core_pattern[128] = "core"; |
62 | int suid_dumpable = 0; | 62 | int suid_dumpable = 0; |
63 | 63 | ||
64 | EXPORT_SYMBOL(suid_dumpable); | 64 | EXPORT_SYMBOL(suid_dumpable); |
@@ -1463,6 +1463,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1463 | int retval = 0; | 1463 | int retval = 0; |
1464 | int fsuid = current->fsuid; | 1464 | int fsuid = current->fsuid; |
1465 | int flag = 0; | 1465 | int flag = 0; |
1466 | int ispipe = 0; | ||
1466 | 1467 | ||
1467 | binfmt = current->binfmt; | 1468 | binfmt = current->binfmt; |
1468 | if (!binfmt || !binfmt->core_dump) | 1469 | if (!binfmt || !binfmt->core_dump) |
@@ -1504,22 +1505,34 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1504 | lock_kernel(); | 1505 | lock_kernel(); |
1505 | format_corename(corename, core_pattern, signr); | 1506 | format_corename(corename, core_pattern, signr); |
1506 | unlock_kernel(); | 1507 | unlock_kernel(); |
1507 | file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600); | 1508 | if (corename[0] == '|') { |
1509 | /* SIGPIPE can happen, but it's just never processed */ | ||
1510 | if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) { | ||
1511 | printk(KERN_INFO "Core dump to %s pipe failed\n", | ||
1512 | corename); | ||
1513 | goto fail_unlock; | ||
1514 | } | ||
1515 | ispipe = 1; | ||
1516 | } else | ||
1517 | file = filp_open(corename, | ||
1518 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); | ||
1508 | if (IS_ERR(file)) | 1519 | if (IS_ERR(file)) |
1509 | goto fail_unlock; | 1520 | goto fail_unlock; |
1510 | inode = file->f_dentry->d_inode; | 1521 | inode = file->f_dentry->d_inode; |
1511 | if (inode->i_nlink > 1) | 1522 | if (inode->i_nlink > 1) |
1512 | goto close_fail; /* multiple links - don't dump */ | 1523 | goto close_fail; /* multiple links - don't dump */ |
1513 | if (d_unhashed(file->f_dentry)) | 1524 | if (!ispipe && d_unhashed(file->f_dentry)) |
1514 | goto close_fail; | 1525 | goto close_fail; |
1515 | 1526 | ||
1516 | if (!S_ISREG(inode->i_mode)) | 1527 | /* AK: actually i see no reason to not allow this for named pipes etc., |
1528 | but keep the previous behaviour for now. */ | ||
1529 | if (!ispipe && !S_ISREG(inode->i_mode)) | ||
1517 | goto close_fail; | 1530 | goto close_fail; |
1518 | if (!file->f_op) | 1531 | if (!file->f_op) |
1519 | goto close_fail; | 1532 | goto close_fail; |
1520 | if (!file->f_op->write) | 1533 | if (!file->f_op->write) |
1521 | goto close_fail; | 1534 | goto close_fail; |
1522 | if (do_truncate(file->f_dentry, 0, 0, file) != 0) | 1535 | if (!ispipe && do_truncate(file->f_dentry, 0, 0, file) != 0) |
1523 | goto close_fail; | 1536 | goto close_fail; |
1524 | 1537 | ||
1525 | retval = binfmt->core_dump(signr, regs, file); | 1538 | retval = binfmt->core_dump(signr, regs, file); |