aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coredump.c
diff options
context:
space:
mode:
authorJann Horn <jann@thejh.net>2016-01-20 18:00:08 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-20 20:09:18 -0500
commitac94b6e3ba858b8de1dfe3f77ad215af7b648545 (patch)
treedbff6b9854c3d300c21ce6e9b1627a035909bd30 /fs/coredump.c
parentcaaee6234d05a58c5b4d05e7bf766131b810a657 (diff)
fs/coredump: prevent "" / "." / ".." core path components
Let %h and %e print empty values as "!", "." as "!" and ".." as "!.". This prevents hostnames and comm values that are empty or consist of one or two dots from changing the directory level at which the corefile will be stored. Consider the case where someone decides to sort coredumps by hostname with a core pattern like "/cores/%h/core.%e.%p.%t" or so. In this case, hostnames "" and "." would cause the coredump to land directly in /cores, which is not what the intent behind the core pattern is, and ".." would cause the coredump to land in /. Yeah, there probably aren't many people who do that, but I still don't want this edgecase to be kind of broken. It seems very unlikely that this caused security issues anywhere, so I'm not requesting a stable backport. [akpm@linux-foundation.org: tweak code comment] Signed-off-by: Jann Horn <jann@thejh.net> Acked-by: Kees Cook <keescook@chromium.org> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/coredump.c')
-rw-r--r--fs/coredump.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/coredump.c b/fs/coredump.c
index b3c153ca435d..9ea87e9fdccf 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -118,6 +118,26 @@ int cn_esc_printf(struct core_name *cn, const char *fmt, ...)
118 ret = cn_vprintf(cn, fmt, arg); 118 ret = cn_vprintf(cn, fmt, arg);
119 va_end(arg); 119 va_end(arg);
120 120
121 if (ret == 0) {
122 /*
123 * Ensure that this coredump name component can't cause the
124 * resulting corefile path to consist of a ".." or ".".
125 */
126 if ((cn->used - cur == 1 && cn->corename[cur] == '.') ||
127 (cn->used - cur == 2 && cn->corename[cur] == '.'
128 && cn->corename[cur+1] == '.'))
129 cn->corename[cur] = '!';
130
131 /*
132 * Empty names are fishy and could be used to create a "//" in a
133 * corefile name, causing the coredump to happen one directory
134 * level too high. Enforce that all components of the core
135 * pattern are at least one character long.
136 */
137 if (cn->used == cur)
138 ret = cn_printf(cn, "!");
139 }
140
121 for (; cur < cn->used; ++cur) { 141 for (; cur < cn->used; ++cur) {
122 if (cn->corename[cur] == '/') 142 if (cn->corename[cur] == '/')
123 cn->corename[cur] = '!'; 143 cn->corename[cur] = '!';