commit:     10a9643d90a1ba6058a66066803fac6cf43f6917
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Wed Feb  1 22:40:09 2017 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Wed Feb  1 22:40:09 2017 +0000
URL:        https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=10a9643d

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 <AT> gentoo.org>

 dumpelf.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/dumpelf.c b/dumpelf.c
index a9c6e05..60c78a3 100644
--- a/dumpelf.c
+++ b/dumpelf.c
@@ -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]);

Reply via email to