diff options
Diffstat (limited to 'libebl')
| -rw-r--r-- | libebl/ChangeLog | 20 | ||||
| -rw-r--r-- | libebl/eblcorenote.c | 39 | ||||
| -rw-r--r-- | libebl/eblobjnote.c | 44 | ||||
| -rw-r--r-- | libebl/libebl.h | 3 |
4 files changed, 72 insertions, 34 deletions
diff --git a/libebl/ChangeLog b/libebl/ChangeLog index a2f89562..acc68919 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,23 @@ +2019-01-29 Mark Wielaard <[email protected]> + + * eblobjnote.c (ebl_object_note): Check pr_datasz padding doesn't + overflow descsz. + +2019-01-16 Mark Wielaard <[email protected]> + + * libebl.h (ebl_core_note): Add desc as argument. + * eblcorenote.c (ebl_core_note): Take desc as an argument, check + it contains a zero terminated string if it is an NT_PLATFORM note. + +2019-01-16 Mark Wielaard <[email protected]> + + * eblobjnte.c (ebl_object_note): Check pr_datasz isn't too large. + +2018-12-02 Mark Wielaard <[email protected]> + + * eblobjnte.c (ebl_object_note): For GNU_PROPERTY_STACK_SIZE use + an Elf32_Addr or Elf64_Addr to read and print the size. + 2018-11-15 Mark Wielaard <[email protected]> * eblobjnotetypename.c (ebl_object_note_type_name): Don't update diff --git a/libebl/eblcorenote.c b/libebl/eblcorenote.c index 783f9815..7fab3974 100644 --- a/libebl/eblcorenote.c +++ b/libebl/eblcorenote.c @@ -36,11 +36,13 @@ #include <inttypes.h> #include <stdio.h> #include <stddef.h> +#include <string.h> #include <libeblP.h> int ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const char *name, + const char *desc, GElf_Word *regs_offset, size_t *nregloc, const Ebl_Register_Location **reglocs, size_t *nitems, const Ebl_Core_Item **items) @@ -51,28 +53,25 @@ ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const char *name, { /* The machine specific function did not know this type. */ - *regs_offset = 0; - *nregloc = 0; - *reglocs = NULL; - switch (nhdr->n_type) + /* NT_PLATFORM is kind of special since it needs a zero terminated + string (other notes often have a fixed size string). */ + static const Ebl_Core_Item platform[] = { -#define ITEMS(type, table) \ - case type: \ - *items = table; \ - *nitems = sizeof table / sizeof table[0]; \ - result = 1; \ - break + { + .name = "Platform", + .type = ELF_T_BYTE, .count = 0, .format = 's' + } + }; - static const Ebl_Core_Item platform[] = - { - { - .name = "Platform", - .type = ELF_T_BYTE, .count = 0, .format = 's' - } - }; - ITEMS (NT_PLATFORM, platform); - -#undef ITEMS + if (nhdr->n_type == NT_PLATFORM + && memchr (desc, '\0', nhdr->n_descsz) != NULL) + { + *regs_offset = 0; + *nregloc = 0; + *reglocs = NULL; + *items = platform; + *nitems = 1; + result = 1; } } diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c index 58ac86d7..f7ac915c 100644 --- a/libebl/eblobjnote.c +++ b/libebl/eblobjnote.c @@ -350,6 +350,13 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, desc += 8; descsz -= 8; + if (prop.pr_datasz > descsz) + { + printf ("BAD property datasz: %" PRId32 "\n", + prop.pr_datasz); + return; + } + int elfclass = gelf_getclass (ebl->elf); char *elfident = elf_getident (ebl->elf, NULL); GElf_Ehdr ehdr; @@ -360,15 +367,22 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, if (prop.pr_type == GNU_PROPERTY_STACK_SIZE) { printf ("STACK_SIZE "); - if (prop.pr_datasz == 4 || prop.pr_datasz == 8) + union + { + Elf64_Addr a64; + Elf32_Addr a32; + } addr; + if ((elfclass == ELFCLASS32 && prop.pr_datasz == 4) + || (elfclass == ELFCLASS64 && prop.pr_datasz == 8)) { - GElf_Addr addr; in.d_type = ELF_T_ADDR; out.d_type = ELF_T_ADDR; in.d_size = prop.pr_datasz; - out.d_size = sizeof (addr); + out.d_size = prop.pr_datasz; in.d_buf = (void *) desc; - out.d_buf = (void *) &addr; + out.d_buf = (elfclass == ELFCLASS32 + ? (void *) &addr.a32 + : (void *) &addr.a64); if (gelf_xlatetom (ebl->elf, &out, &in, elfident[EI_DATA]) == NULL) @@ -376,7 +390,10 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, printf ("%s\n", elf_errmsg (-1)); return; } - printf ("%#" PRIx64 "\n", addr); + if (elfclass == ELFCLASS32) + printf ("%#" PRIx32 "\n", addr.a32); + else + printf ("%#" PRIx64 "\n", addr.a64); } else printf (" (garbage datasz: %" PRIx32 ")\n", @@ -479,16 +496,17 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, printf ("%02" PRIx8 "\n", (uint8_t) desc[i]); } } + if (elfclass == ELFCLASS32) - { - desc += NOTE_ALIGN4 (prop.pr_datasz); - descsz -= NOTE_ALIGN4 (prop.pr_datasz); - } + prop.pr_datasz = NOTE_ALIGN4 (prop.pr_datasz); else - { - desc += NOTE_ALIGN8 (prop.pr_datasz); - descsz -= NOTE_ALIGN8 (prop.pr_datasz); - } + prop.pr_datasz = NOTE_ALIGN8 (prop.pr_datasz); + + desc += prop.pr_datasz; + if (descsz > prop.pr_datasz) + descsz -= prop.pr_datasz; + else + descsz = 0; } } break; diff --git a/libebl/libebl.h b/libebl/libebl.h index ca9b9fec..24922eb8 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -319,7 +319,8 @@ typedef struct /* Describe the format of a core file note with the given header and NAME. NAME is not guaranteed terminated, it's NHDR->n_namesz raw bytes. */ -extern int ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const char *name, +extern int ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, + const char *name, const char *desc, GElf_Word *regs_offset, size_t *nregloc, const Ebl_Register_Location **reglocs, size_t *nitems, const Ebl_Core_Item **items) |
