aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2015-09-22 18:21:51 -0700
committerThe Android Automerger <android-build@google.com>2015-09-25 14:40:41 -0700
commit5e3bc6a32ca5a78a1a66b4dffe94dfdbf829cae5 (patch)
tree3276be4d119adc26ab76b291bec7a1a1dd47aef7
parent3c0cd977cafe8dfdfb5ec4b3cf3f58b908c01424 (diff)
downloadlibunwind-marshmallow-dr-release.tar.gz
If an elf file has a malformed section names, skip processing of the name. Also, verify the return value of the allocations. Bug: 24279745 Change-Id: Ic51bd9df7142bc599dc51bfdcab87ff20fe8a389
-rw-r--r--src/dwarf/Gfind_proc_info-lsb.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c
index 7464f483..f74b734f 100644
--- a/src/dwarf/Gfind_proc_info-lsb.c
+++ b/src/dwarf/Gfind_proc_info-lsb.c
@@ -120,39 +120,45 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
fseek (f, ehdr.e_shoff, SEEK_SET);
sec_hdrs = calloc (ehdr.e_shnum, sizeof (Elf_W (Shdr)));
- if (fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f) != ehdr.e_shnum)
+ if (sec_hdrs == NULL || fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f) != ehdr.e_shnum)
goto file_error;
Debug (4, "loading string table of size %ld\n",
(long) sec_hdrs[shstrndx].sh_size);
- stringtab = malloc (sec_hdrs[shstrndx].sh_size);
+ size_t sec_size = sec_hdrs[shstrndx].sh_size;
+ stringtab = malloc (sec_size);
fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET);
- if (fread (stringtab, 1, sec_hdrs[shstrndx].sh_size, f) != sec_hdrs[shstrndx].sh_size)
+ if (stringtab == NULL || fread (stringtab, 1, sec_size, f) != sec_size)
goto file_error;
for (i = 1; i < ehdr.e_shnum && *buf == NULL; i++)
{
- char *secname = &stringtab[sec_hdrs[i].sh_name];
+ size_t sec_position = sec_hdrs[i].sh_name;
+ if (sec_position >= sec_size)
+ continue;
+ char *secname = &stringtab[sec_position];
- if (strcmp (secname, ".debug_frame") == 0)
+ if (sec_position + sizeof(".debug_frame") <= sec_size
+ && strcmp (secname, ".debug_frame") == 0)
{
*bufsize = sec_hdrs[i].sh_size;
*buf = malloc (*bufsize);
fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
- if (fread (*buf, 1, *bufsize, f) != *bufsize)
+ if (*buf == NULL || fread (*buf, 1, *bufsize, f) != *bufsize)
goto file_error;
Debug (4, "read %zd bytes of .debug_frame from offset %ld\n",
*bufsize, (long) sec_hdrs[i].sh_offset);
}
- else if (strcmp (secname, ".gnu_debuglink") == 0)
+ else if (sec_position + sizeof(".gnu_debuglink") <= sec_size
+ && strcmp (secname, ".gnu_debuglink") == 0)
{
linksize = sec_hdrs[i].sh_size;
linkbuf = malloc (linksize);
fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
- if (fread (linkbuf, 1, linksize, f) != linksize)
+ if (linkbuf == NULL || fread (linkbuf, 1, linksize, f) != linksize)
goto file_error;
Debug (4, "read %zd bytes of .gnu_debuglink from offset %ld\n",
@@ -182,6 +188,8 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
basedir = malloc (strlen (file) + 1);
newname = malloc (strlen (linkbuf) + strlen (debugdir)
+ strlen (file) + 9);
+ if (basedir == NULL || newname == NULL)
+ goto file_error;
p = strrchr (file, '/');
if (p != NULL)