author: Jann Horn <jann@thejh.net> 2016-01-20 15:00:08 -0800
committer: Linus Torvalds <torvalds@linux-foundation.org> 2016-01-20 17:09:18 -0800
commit: ac94b6e3ba858b8de1dfe3f77ad215af7b648545
parent: caaee6234d05a58c5b4d05e7bf766131b810a657
Commit Summary:
Diffstat:
1 file changed, 19 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, ...)
ret = cn_vprintf(cn, fmt, arg);
va_end(arg);
+ if (ret == 0) {
+ /*
+ * Ensure that this coredump name component can't cause the
+ * resulting corefile path to consist of a ".." or ".".
+ */
+ if ((cn->used - cur == 1 && cn->corename[cur] == '.') ||
+ (cn->used - cur == 2 && cn->corename[cur] == '.'
+ && cn->corename[cur+1] == '.'))
+ cn->corename[cur] = '!';
+
+ /*
+ * Empty names are fishy and could be used to create a "//" in a
+ * corefile name, causing the coredump to happen one directory
+ * level too high. Enforce that all components of the core
+ * pattern are at least one character long.
+ */
+ if (cn->used == cur)
+ ret = cn_printf(cn, "!");
+ }
+
for (; cur < cn->used; ++cur) {
if (cn->corename[cur] == '/')
cn->corename[cur] = '!';