]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libelf: Fix possible unbounded stack usage in updatefile.
authorMark Wielaard <mjw@redhat.com>
Sun, 17 May 2015 08:30:57 +0000 (10:30 +0200)
committerMark Wielaard <mjw@redhat.com>
Wed, 27 May 2015 21:04:31 +0000 (23:04 +0200)
Allocate shdr_data and scns with malloc, not alloca. Free after writing
section headers.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
libelf/ChangeLog
libelf/elf32_updatefile.c

index f1f8faca75baf07403e98325d022b59349d9e294..5f66135f14e4976a888311ef80bc5eafe54442b1 100644 (file)
@@ -1,3 +1,8 @@
+2015-05-17  Mark Wielaard  <mjw@redhat.com>
+
+       * elf32_updatefile.c (updatefile): Allocate shdr_data and scns
+       with malloc, not alloca. Free after writing section headers.
+
 2015-05-16  Mark Wielaard  <mjw@redhat.com>
 
        * elf32_updatefile.c (updatemmap): Allocate temporary shdr storage
index f625b308420f16cf66555a70efc86b1af97dc02e..e90ad47d458164ca6233b117e8f1755fb3863b83 100644 (file)
@@ -657,15 +657,27 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
       ElfW2(LIBELFBITS,Shdr) *shdr_data;
       if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL
          || (elf->flags & ELF_F_DIRTY))
-       shdr_data = (ElfW2(LIBELFBITS,Shdr) *)
-         alloca (shnum * sizeof (ElfW2(LIBELFBITS,Shdr)));
+       {
+         shdr_data = (ElfW2(LIBELFBITS,Shdr) *)
+           malloc (shnum * sizeof (ElfW2(LIBELFBITS,Shdr)));
+         if (unlikely (shdr_data == NULL))
+           {
+             __libelf_seterrno (ELF_E_NOMEM);
+             return -1;
+           }
+       }
       else
        shdr_data = elf->state.ELFW(elf,LIBELFBITS).shdr;
       int shdr_flags = elf->flags;
 
       /* Get all sections into the array and sort them.  */
       Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
-      Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *));
+      Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *));
+      if (unlikely (scns == NULL))
+       {
+         __libelf_seterrno (ELF_E_NOMEM);
+         return -1;
+       }
       sort_sections (scns, list);
 
       for (size_t cnt = 0; cnt < shnum; ++cnt)
@@ -814,6 +826,12 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
          __libelf_seterrno (ELF_E_WRITE_ERROR);
          return 1;
        }
+
+      if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL
+         || (elf->flags & ELF_F_DIRTY))
+       free (shdr_data);
+
+      free (scns);
     }
 
   /* That was the last part.  Clear the overall flag.  */