diff options
| -rw-r--r-- | Documentation/sysctl/kernel.txt | 3 | ||||
| -rw-r--r-- | fs/exec.c | 38 |
2 files changed, 40 insertions, 1 deletions
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 36f007514db3..5e7cb39ad195 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
| @@ -161,7 +161,8 @@ core_pattern is used to specify a core dumpfile pattern name. | |||
| 161 | %s signal number | 161 | %s signal number |
| 162 | %t UNIX time of dump | 162 | %t UNIX time of dump |
| 163 | %h hostname | 163 | %h hostname |
| 164 | %e executable filename | 164 | %e executable filename (may be shortened) |
| 165 | %E executable path | ||
| 165 | %<OTHER> both are dropped | 166 | %<OTHER> both are dropped |
| 166 | . If the first character of the pattern is a '|', the kernel will treat | 167 | . If the first character of the pattern is a '|', the kernel will treat |
| 167 | the rest of the pattern as a command to run. The core dump will be | 168 | the rest of the pattern as a command to run. The core dump will be |
| @@ -1623,6 +1623,41 @@ expand_fail: | |||
| 1623 | return ret; | 1623 | return ret; |
| 1624 | } | 1624 | } |
| 1625 | 1625 | ||
| 1626 | static int cn_print_exe_file(struct core_name *cn) | ||
| 1627 | { | ||
| 1628 | struct file *exe_file; | ||
| 1629 | char *pathbuf, *path, *p; | ||
| 1630 | int ret; | ||
| 1631 | |||
| 1632 | exe_file = get_mm_exe_file(current->mm); | ||
| 1633 | if (!exe_file) | ||
| 1634 | return cn_printf(cn, "(unknown)"); | ||
| 1635 | |||
| 1636 | pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY); | ||
| 1637 | if (!pathbuf) { | ||
| 1638 | ret = -ENOMEM; | ||
| 1639 | goto put_exe_file; | ||
| 1640 | } | ||
| 1641 | |||
| 1642 | path = d_path(&exe_file->f_path, pathbuf, PATH_MAX); | ||
| 1643 | if (IS_ERR(path)) { | ||
| 1644 | ret = PTR_ERR(path); | ||
| 1645 | goto free_buf; | ||
| 1646 | } | ||
| 1647 | |||
| 1648 | for (p = path; *p; p++) | ||
| 1649 | if (*p == '/') | ||
| 1650 | *p = '!'; | ||
| 1651 | |||
| 1652 | ret = cn_printf(cn, "%s", path); | ||
| 1653 | |||
| 1654 | free_buf: | ||
| 1655 | kfree(pathbuf); | ||
| 1656 | put_exe_file: | ||
| 1657 | fput(exe_file); | ||
| 1658 | return ret; | ||
| 1659 | } | ||
| 1660 | |||
| 1626 | /* format_corename will inspect the pattern parameter, and output a | 1661 | /* format_corename will inspect the pattern parameter, and output a |
| 1627 | * name into corename, which must have space for at least | 1662 | * name into corename, which must have space for at least |
| 1628 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. | 1663 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. |
| @@ -1694,6 +1729,9 @@ static int format_corename(struct core_name *cn, long signr) | |||
| 1694 | case 'e': | 1729 | case 'e': |
| 1695 | err = cn_printf(cn, "%s", current->comm); | 1730 | err = cn_printf(cn, "%s", current->comm); |
| 1696 | break; | 1731 | break; |
| 1732 | case 'E': | ||
| 1733 | err = cn_print_exe_file(cn); | ||
| 1734 | break; | ||
| 1697 | /* core limit size */ | 1735 | /* core limit size */ |
| 1698 | case 'c': | 1736 | case 'c': |
| 1699 | err = cn_printf(cn, "%lu", | 1737 | err = cn_printf(cn, "%lu", |
