diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 28 |
1 files changed, 20 insertions, 8 deletions
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/security.h> | 46 | #include <linux/security.h> |
47 | #include <linux/syscalls.h> | 47 | #include <linux/syscalls.h> |
48 | #include <linux/rmap.h> | 48 | #include <linux/rmap.h> |
49 | #include <linux/acct.h> | 49 | #include <linux/tsacct_kern.h> |
50 | #include <linux/cn_proc.h> | 50 | #include <linux/cn_proc.h> |
51 | #include <linux/audit.h> | 51 | #include <linux/audit.h> |
52 | 52 | ||
@@ -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); |
@@ -898,8 +898,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
898 | return 0; | 898 | return 0; |
899 | 899 | ||
900 | mmap_failed: | 900 | mmap_failed: |
901 | put_files_struct(current->files); | 901 | reset_files_struct(current, files); |
902 | current->files = files; | ||
903 | out: | 902 | out: |
904 | return retval; | 903 | return retval; |
905 | } | 904 | } |
@@ -1464,6 +1463,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1464 | int retval = 0; | 1463 | int retval = 0; |
1465 | int fsuid = current->fsuid; | 1464 | int fsuid = current->fsuid; |
1466 | int flag = 0; | 1465 | int flag = 0; |
1466 | int ispipe = 0; | ||
1467 | 1467 | ||
1468 | binfmt = current->binfmt; | 1468 | binfmt = current->binfmt; |
1469 | if (!binfmt || !binfmt->core_dump) | 1469 | if (!binfmt || !binfmt->core_dump) |
@@ -1505,22 +1505,34 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1505 | lock_kernel(); | 1505 | lock_kernel(); |
1506 | format_corename(corename, core_pattern, signr); | 1506 | format_corename(corename, core_pattern, signr); |
1507 | unlock_kernel(); | 1507 | unlock_kernel(); |
1508 | 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); | ||
1509 | if (IS_ERR(file)) | 1519 | if (IS_ERR(file)) |
1510 | goto fail_unlock; | 1520 | goto fail_unlock; |
1511 | inode = file->f_dentry->d_inode; | 1521 | inode = file->f_dentry->d_inode; |
1512 | if (inode->i_nlink > 1) | 1522 | if (inode->i_nlink > 1) |
1513 | goto close_fail; /* multiple links - don't dump */ | 1523 | goto close_fail; /* multiple links - don't dump */ |
1514 | if (d_unhashed(file->f_dentry)) | 1524 | if (!ispipe && d_unhashed(file->f_dentry)) |
1515 | goto close_fail; | 1525 | goto close_fail; |
1516 | 1526 | ||
1517 | 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)) | ||
1518 | goto close_fail; | 1530 | goto close_fail; |
1519 | if (!file->f_op) | 1531 | if (!file->f_op) |
1520 | goto close_fail; | 1532 | goto close_fail; |
1521 | if (!file->f_op->write) | 1533 | if (!file->f_op->write) |
1522 | goto close_fail; | 1534 | goto close_fail; |
1523 | if (do_truncate(file->f_dentry, 0, 0, file) != 0) | 1535 | if (!ispipe && do_truncate(file->f_dentry, 0, 0, file) != 0) |
1524 | goto close_fail; | 1536 | goto close_fail; |
1525 | 1537 | ||
1526 | retval = binfmt->core_dump(signr, regs, file); | 1538 | retval = binfmt->core_dump(signr, regs, file); |