diff options
author | 2017-02-01 12:40:09 -1000 | |
---|---|---|
committer | 2017-02-01 12:40:09 -1000 | |
commit | 10a9643d90a1ba6058a66066803fac6cf43f6917 (patch) | |
tree | 1caff33529af2aa00161d3326b32e54234bf513f | |
parent | dumpelf: check for invalid program headers (diff) | |
download | pax-utils-10a9643d90a1ba6058a66066803fac6cf43f6917.tar.gz pax-utils-10a9643d90a1ba6058a66066803fac6cf43f6917.tar.bz2 pax-utils-10a9643d90a1ba6058a66066803fac6cf43f6917.zip |
dumpelf: check for invalid notes
Handle cases where the size fields would overflow the additions.
URL: https://bugs.gentoo.org/607898
Reported-by: Agostino Sarubbo <ago@gentoo.org>
-rw-r--r-- | dumpelf.c | 23 |
1 files changed, 16 insertions, 7 deletions
@@ -209,6 +209,7 @@ static void dump_notes(elfobj *elf, size_t B, const void *memory, const void *me * world, the two structs are exactly the same. So avoid ugly CPP. */ size_t i; + bool corrupt = false; const void *ndata = memory; const char *name; const unsigned char *desc; @@ -223,23 +224,31 @@ static void dump_notes(elfobj *elf, size_t B, const void *memory, const void *me } printf("\n\t/%c note section dump:\n", '*'); - for (i = 0; ndata < memory_end; ++i) { + for (i = 0; ndata < memory_end && !corrupt; ++i) { note = ndata; namesz = EGET(note->n_namesz); descsz = EGET(note->n_descsz); - name = namesz ? ndata + sizeof(*note) : ""; - desc = descsz ? ndata + sizeof(*note) + ALIGN_UP(namesz, 4) : ""; + if (namesz > elf->len || descsz > elf->len) + corrupt = true; + name = namesz ? ndata + sizeof(*note) : NULL; + desc = descsz ? ndata + sizeof(*note) + ALIGN_UP(namesz, 4) : NULL; ndata += sizeof(*note) + ALIGN_UP(namesz, 4) + ALIGN_UP(descsz, 4); - if (ndata > memory_end) { + if (ndata > memory_end) + corrupt = true; + if (corrupt) { + name = NULL; + desc = NULL; printf("\tNote is corrupt\n"); - break; } printf("\t * Elf%zu_Nhdr note%zu = {\n", B, i); - printf("\t * \t.n_namesz = %u, (bytes) [%s]\n", namesz, name); + printf("\t * \t.n_namesz = %u, (bytes)", namesz); + if (name) + printf(" [%s]", name); + printf("\n"); printf("\t * \t.n_descsz = %u, (bytes)", descsz); - if (descsz) { + if (desc) { printf(" [ "); for (i = 0; i < descsz; ++i) printf("%.2X ", desc[i]); |