diff options
author | Jiri Slaby <jslaby@suse.cz> | 2011-07-26 19:08:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 19:49:43 -0400 |
commit | 2c563731fee0f625924f72e854957bc77601e8b3 (patch) | |
tree | 76091ee6de5c2ca1eea2919b4dc5322e9472cf52 /fs/exec.c | |
parent | 3141c8b165644774eb0e83d8330fbe47e45b37bf (diff) |
coredump: escape / in hostname and comm
Change every occurence of / in comm and hostname to !. If the process
changes its name to contain /, the core is not dumped (if the directory
tree doesn't exist like that). The same with hostname being something
like myhost/3. Fix this behaviour by using the escape loop used in %E.
(We extract it to a separate function.)
Now both with comm == myprocess/1 and hostname == myhost/1, the core is
dumped like (kernel.core_pattern='core.%p.%e.%h):
core.2349.myprocess!1.myhost!1
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 31 |
1 files changed, 23 insertions, 8 deletions
@@ -1649,15 +1649,26 @@ expand_fail: | |||
1649 | return ret; | 1649 | return ret; |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | static void cn_escape(char *str) | ||
1653 | { | ||
1654 | for (; *str; str++) | ||
1655 | if (*str == '/') | ||
1656 | *str = '!'; | ||
1657 | } | ||
1658 | |||
1652 | static int cn_print_exe_file(struct core_name *cn) | 1659 | static int cn_print_exe_file(struct core_name *cn) |
1653 | { | 1660 | { |
1654 | struct file *exe_file; | 1661 | struct file *exe_file; |
1655 | char *pathbuf, *path, *p; | 1662 | char *pathbuf, *path; |
1656 | int ret; | 1663 | int ret; |
1657 | 1664 | ||
1658 | exe_file = get_mm_exe_file(current->mm); | 1665 | exe_file = get_mm_exe_file(current->mm); |
1659 | if (!exe_file) | 1666 | if (!exe_file) { |
1660 | return cn_printf(cn, "%s (path unknown)", current->comm); | 1667 | char *commstart = cn->corename + cn->used; |
1668 | ret = cn_printf(cn, "%s (path unknown)", current->comm); | ||
1669 | cn_escape(commstart); | ||
1670 | return ret; | ||
1671 | } | ||
1661 | 1672 | ||
1662 | pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY); | 1673 | pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY); |
1663 | if (!pathbuf) { | 1674 | if (!pathbuf) { |
@@ -1671,9 +1682,7 @@ static int cn_print_exe_file(struct core_name *cn) | |||
1671 | goto free_buf; | 1682 | goto free_buf; |
1672 | } | 1683 | } |
1673 | 1684 | ||
1674 | for (p = path; *p; p++) | 1685 | cn_escape(path); |
1675 | if (*p == '/') | ||
1676 | *p = '!'; | ||
1677 | 1686 | ||
1678 | ret = cn_printf(cn, "%s", path); | 1687 | ret = cn_printf(cn, "%s", path); |
1679 | 1688 | ||
@@ -1745,16 +1754,22 @@ static int format_corename(struct core_name *cn, long signr) | |||
1745 | break; | 1754 | break; |
1746 | } | 1755 | } |
1747 | /* hostname */ | 1756 | /* hostname */ |
1748 | case 'h': | 1757 | case 'h': { |
1758 | char *namestart = cn->corename + cn->used; | ||
1749 | down_read(&uts_sem); | 1759 | down_read(&uts_sem); |
1750 | err = cn_printf(cn, "%s", | 1760 | err = cn_printf(cn, "%s", |
1751 | utsname()->nodename); | 1761 | utsname()->nodename); |
1752 | up_read(&uts_sem); | 1762 | up_read(&uts_sem); |
1763 | cn_escape(namestart); | ||
1753 | break; | 1764 | break; |
1765 | } | ||
1754 | /* executable */ | 1766 | /* executable */ |
1755 | case 'e': | 1767 | case 'e': { |
1768 | char *commstart = cn->corename + cn->used; | ||
1756 | err = cn_printf(cn, "%s", current->comm); | 1769 | err = cn_printf(cn, "%s", current->comm); |
1770 | cn_escape(commstart); | ||
1757 | break; | 1771 | break; |
1772 | } | ||
1758 | case 'E': | 1773 | case 'E': |
1759 | err = cn_print_exe_file(cn); | 1774 | err = cn_print_exe_file(cn); |
1760 | break; | 1775 | break; |