summaryrefslogtreecommitdiff
path: root/libdwfl/find-debuginfo.c
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-05-22 16:01:02 +0200
committerMark Wielaard <mjw@redhat.com>2015-05-27 23:04:31 +0200
commitc4f133a956cdc0355eadedcfdc2198107d3e73b6 (patch)
treee8b4f5213db2e3cf68beb2dedb67920c9d8feb7e /libdwfl/find-debuginfo.c
parentc57829bb118bc30d874f7440b421abbebc74a733 (diff)
downloadelfutils-c4f133a956cdc0355eadedcfdc2198107d3e73b6.tar.gz
libdwfl: find_debuginfo_in_patch don't alloca/strdupa strings of unknown size.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libdwfl/find-debuginfo.c')
-rw-r--r--libdwfl/find-debuginfo.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c
index 3f5314ad..ac9a5e50 100644
--- a/libdwfl/find-debuginfo.c
+++ b/libdwfl/find-debuginfo.c
@@ -45,7 +45,7 @@ try_open (const struct stat64 *main_stat,
if (dir == NULL && subdir == NULL)
{
fname = strdup (debuglink);
- if (fname == NULL)
+ if (unlikely (fname == NULL))
return -1;
}
else if ((subdir == NULL ? asprintf (&fname, "%s/%s", dir, debuglink)
@@ -161,6 +161,7 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
bool cancheck = debuglink_crc != (GElf_Word) 0;
const char *file_basename = file_name == NULL ? NULL : basename (file_name);
+ char *localname = NULL;
if (debuglink_file == NULL)
{
/* For a alt debug multi file we need a name, for a separate debug
@@ -172,7 +173,9 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
}
size_t len = strlen (file_basename);
- char *localname = alloca (len + sizeof ".debug");
+ localname = malloc (len + sizeof ".debug");
+ if (unlikely (localname == NULL))
+ return -1;
memcpy (localname, file_basename, len);
memcpy (&localname[len], ".debug", sizeof ".debug");
debuglink_file = localname;
@@ -183,11 +186,17 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
indicated by the debug directory path setting. */
const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
- char *path = strdupa ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
- ?: DEFAULT_DEBUGINFO_PATH);
+ char *localpath = strdup ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
+ ?: DEFAULT_DEBUGINFO_PATH);
+ if (unlikely (localpath == NULL))
+ {
+ free (localname);
+ return -1;
+ }
/* A leading - or + in the whole path sets whether to check file CRCs. */
bool defcheck = true;
+ char *path = localpath;
if (path[0] == '-' || path[0] == '+')
{
defcheck = path[0] == '+';
@@ -205,7 +214,13 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
}
char *file_dirname = (file_basename == file_name ? NULL
- : strndupa (file_name, file_basename - 1 - file_name));
+ : strndup (file_name, file_basename - 1 - file_name));
+ if (file_basename != file_name && file_dirname == NULL)
+ {
+ free (localpath);
+ free (localname);
+ return -1;
+ }
char *p;
while ((p = strsep (&path, ":")) != NULL)
{
@@ -270,7 +285,7 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
if (fd < 0)
{
if (errno != ENOENT && errno != ENOTDIR)
- return -1;
+ goto fail_free;
else
continue;
}
@@ -278,8 +293,17 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
}
continue;
default:
- return -1;
+ {
+ fail_free:
+ free (localpath);
+ free (localname);
+ free (file_dirname);
+ return -1;
+ }
}
+ free (localpath);
+ free (localname);
+ free (file_dirname);
if (validate (mod, fd, check, debuglink_crc))
{
*debuginfo_file_name = fname;