diff options
author | Christopher Ferris <cferris@google.com> | 2015-09-22 18:21:51 -0700 |
---|---|---|
committer | The Android Automerger <android-build@google.com> | 2015-09-25 14:40:41 -0700 |
commit | 5e3bc6a32ca5a78a1a66b4dffe94dfdbf829cae5 (patch) | |
tree | 3276be4d119adc26ab76b291bec7a1a1dd47aef7 | |
parent | 3c0cd977cafe8dfdfb5ec4b3cf3f58b908c01424 (diff) | |
download | libunwind-marshmallow-dr-release.tar.gz |
Verify section table name size before strcmp.android-6.0.0_r26android-6.0.0_r25android-6.0.0_r24android-6.0.0_r23android-6.0.0_r13android-6.0.0_r12android-6.0.0_r11marshmallow-dr-releaselinaro-android-6.0
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.c | 24 |
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) |