summaryrefslogtreecommitdiff
path: root/libdwfl
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-05-22 14:18:11 +0200
committerMark Wielaard <mjw@redhat.com>2015-05-27 23:04:31 +0200
commitc57829bb118bc30d874f7440b421abbebc74a733 (patch)
treedbbfa00cb0964b7ee2fe01d6d7e01b91f875173a /libdwfl
parent9202fe132caea838cc7e2c7864e0ee702e62f155 (diff)
downloadelfutils-c57829bb118bc30d874f7440b421abbebc74a733.tar.gz
libdwfl: Reject very short or really large build-ids.
We cannot handle build-ids less than at least 3 or more than 64 bytes. Very big build-ids, or very large debug search paths might have blown up the stack. Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libdwfl')
-rw-r--r--libdwfl/ChangeLog6
-rw-r--r--libdwfl/dwfl_build_id_find_elf.c23
2 files changed, 25 insertions, 4 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 080825ed..f08200e6 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-22 Mark Wielaard <mjw@redhat.com>
+
+ * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Return
+ error when id_len too small or too large. strdup, not strdupa,
+ and free path when done.
+
2015-05-19 Mark Wielaard <mjw@redhat.com>
* elf-from-memory.c (elf_from_remote_memory): Don't allocate all
diff --git a/libdwfl/dwfl_build_id_find_elf.c b/libdwfl/dwfl_build_id_find_elf.c
index 062aad1f..215782a7 100644
--- a/libdwfl/dwfl_build_id_find_elf.c
+++ b/libdwfl/dwfl_build_id_find_elf.c
@@ -1,5 +1,5 @@
/* Find an ELF file for a module from its build ID.
- Copyright (C) 2007-2010, 2014 Red Hat, Inc.
+ Copyright (C) 2007-2010, 2014, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -37,9 +37,20 @@ internal_function
__libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name,
const size_t id_len, const uint8_t *id)
{
+ /* We don't handle very short or really large build-ids. We need at
+ at least 3 and allow for up to 64 (normally ids are 20 long). */
+#define MIN_BUILD_ID_BYTES 3
+#define MAX_BUILD_ID_BYTES 64
+ if (id_len < MIN_BUILD_ID_BYTES || id_len > MAX_BUILD_ID_BYTES)
+ {
+ __libdwfl_seterrno (DWFL_E_WRONG_ID_ELF);
+ return -1;
+ }
+
/* Search debuginfo_path directories' .build-id/ subdirectories. */
- char id_name[sizeof "/.build-id/" + 1 + id_len * 2 + sizeof ".debug" - 1];
+ char id_name[sizeof "/.build-id/" + 1 + MAX_BUILD_ID_BYTES * 2
+ + sizeof ".debug" - 1];
strcpy (id_name, "/.build-id/");
int n = snprintf (&id_name[sizeof "/.build-id/" - 1],
4, "%02" PRIx8 "/", (uint8_t) id[0]);
@@ -55,8 +66,10 @@ __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name,
".debug");
const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
- char *path = strdupa ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
- ?: DEFAULT_DEBUGINFO_PATH);
+ char *path = strdup ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
+ ?: DEFAULT_DEBUGINFO_PATH);
+ if (path == NULL)
+ return -1;
int fd = -1;
char *dir;
@@ -90,6 +103,8 @@ __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name,
free (name);
}
+ free (path);
+
/* If we simply found nothing, clear errno. If we had some other error
with the file, report that. Possibly this should treat other errors
like ENOENT too. But ignoring all errors could mask some that should