summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-10-18 15:09:08 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-10-18 15:09:08 +0000
commit685a436a499e8b080a83986ccb0a274656d9960b (patch)
treecad22a2be1a4e28f619d26f670210b49f9f8945c
parenta40d95c48fa7e7974feb294abca8af34e299d109 (diff)
addr2line.c: boundary checks
* addr2line.c (parse_debug_line_cu): boundary checks for compressed debug sections. [ruby-dev:49840] [Bug #12850] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56446 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--addr2line.c27
2 files changed, 23 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 07c94f2e38..0d505cfbbe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Oct 19 00:09:06 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * addr2line.c (parse_debug_line_cu): boundary checks for
+ compressed debug sections. [ruby-dev:49840] [Bug #12850]
+
Tue Oct 18 16:36:40 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* configure.in (DLDFLAGS): append --compress-debug-sections=zlib
diff --git a/addr2line.c b/addr2line.c
index a20e5000c4..3cfb199d8b 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -225,7 +225,7 @@ fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
}
}
-static void
+static int
parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
obj_info_t *obj, line_info_t *lines, int offset)
{
@@ -287,9 +287,13 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
include_directories = p;
+ /* temporary measure for compress-debug-sections */
+ if (p >= cu_end) return -1;
+
/* skip include directories */
while (*p) {
- while (*p) p++;
+ p = memchr(p, '\0', cu_end - p);
+ if (!p) return -1;
p++;
}
p++;
@@ -397,21 +401,24 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
}
}
*debug_line = p;
+ return 0;
}
-static void
+static int
parse_debug_line(int num_traces, void **traces,
char *debug_line, unsigned long size,
obj_info_t *obj, line_info_t *lines, int offset)
{
char *debug_line_end = debug_line + size;
while (debug_line < debug_line_end) {
- parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset);
+ if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset))
+ return -1;
}
if (debug_line != debug_line_end) {
kprintf("Unexpected size of .debug_line in %s\n",
binary_filename);
}
+ return 0;
}
/* read file and fill lines */
@@ -620,10 +627,11 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
goto finish;
}
- parse_debug_line(num_traces, traces,
- file + debug_line_shdr->sh_offset,
- debug_line_shdr->sh_size,
- obj, lines, offset);
+ if (parse_debug_line(num_traces, traces,
+ file + debug_line_shdr->sh_offset,
+ debug_line_shdr->sh_size,
+ obj, lines, offset))
+ goto fail;
finish:
return dladdr_fbase;
fail:
@@ -719,7 +727,8 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces)
obj->path = path;
lines[i].path = path;
strcpy(binary_filename, path);
- fill_lines(num_traces, traces, 1, &obj, lines, i);
+ if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1)
+ break;
}
next_line:
continue;