diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 25 |
1 files changed, 22 insertions, 3 deletions
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/stat.h> | 29 | #include <linux/stat.h> |
30 | #include <linux/fcntl.h> | 30 | #include <linux/fcntl.h> |
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <linux/string.h> | ||
32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
33 | #include <linux/pagemap.h> | 34 | #include <linux/pagemap.h> |
34 | #include <linux/highmem.h> | 35 | #include <linux/highmem.h> |
@@ -1514,6 +1515,14 @@ static int format_corename(char *corename, const char *pattern, long signr) | |||
1514 | goto out; | 1515 | goto out; |
1515 | out_ptr += rc; | 1516 | out_ptr += rc; |
1516 | break; | 1517 | break; |
1518 | /* core limit size */ | ||
1519 | case 'c': | ||
1520 | rc = snprintf(out_ptr, out_end - out_ptr, | ||
1521 | "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur); | ||
1522 | if (rc > out_end - out_ptr) | ||
1523 | goto out; | ||
1524 | out_ptr += rc; | ||
1525 | break; | ||
1517 | default: | 1526 | default: |
1518 | break; | 1527 | break; |
1519 | } | 1528 | } |
@@ -1698,6 +1707,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1698 | int flag = 0; | 1707 | int flag = 0; |
1699 | int ispipe = 0; | 1708 | int ispipe = 0; |
1700 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; | 1709 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; |
1710 | char **helper_argv = NULL; | ||
1711 | int helper_argc = 0; | ||
1712 | char *delimit; | ||
1701 | 1713 | ||
1702 | audit_core_dumps(signr); | 1714 | audit_core_dumps(signr); |
1703 | 1715 | ||
@@ -1746,14 +1758,18 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1746 | * at which point file size limits and permissions will be imposed | 1758 | * at which point file size limits and permissions will be imposed |
1747 | * as it does with any other process | 1759 | * as it does with any other process |
1748 | */ | 1760 | */ |
1749 | if ((!ispipe) && | 1761 | if ((!ispipe) && (core_limit < binfmt->min_coredump)) |
1750 | (core_limit < binfmt->min_coredump)) | ||
1751 | goto fail_unlock; | 1762 | goto fail_unlock; |
1752 | 1763 | ||
1753 | if (ispipe) { | 1764 | if (ispipe) { |
1754 | core_limit = RLIM_INFINITY; | 1765 | core_limit = RLIM_INFINITY; |
1766 | helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); | ||
1767 | /* Terminate the string before the first option */ | ||
1768 | delimit = strchr(corename, ' '); | ||
1769 | if (delimit) | ||
1770 | *delimit = '\0'; | ||
1755 | /* SIGPIPE can happen, but it's just never processed */ | 1771 | /* SIGPIPE can happen, but it's just never processed */ |
1756 | if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) { | 1772 | if(call_usermodehelper_pipe(corename+1, helper_argv, NULL, &file)) { |
1757 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1773 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1758 | corename); | 1774 | corename); |
1759 | goto fail_unlock; | 1775 | goto fail_unlock; |
@@ -1788,6 +1804,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1788 | close_fail: | 1804 | close_fail: |
1789 | filp_close(file, NULL); | 1805 | filp_close(file, NULL); |
1790 | fail_unlock: | 1806 | fail_unlock: |
1807 | if (helper_argv) | ||
1808 | argv_free(helper_argv); | ||
1809 | |||
1791 | current->fsuid = fsuid; | 1810 | current->fsuid = fsuid; |
1792 | complete_all(&mm->core_done); | 1811 | complete_all(&mm->core_done); |
1793 | fail: | 1812 | fail: |