]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Merge branch 'master' into robustify
authorRoland McGrath <roland@redhat.com>
Fri, 8 Jan 2010 03:51:42 +0000 (19:51 -0800)
committerRoland McGrath <roland@redhat.com>
Fri, 8 Jan 2010 03:51:42 +0000 (19:51 -0800)
Conflicts:
libelf/elf32_getphdr.c
libelf/elf_begin.c

1  2 
libelf/ChangeLog
libelf/elf32_getphdr.c
libelf/elf32_newphdr.c
libelf/elf32_updatefile.c
libelf/elf_begin.c
libelf/libelfP.h

Simple merge
Simple merge
index 589322294f0619eed0774c407c46e6fd3051eb9e,03ff100a5641794fb0d3bfdd5d094f0a0c4f4bc6..9191d4418c1c9ac6a0b705acfd0ce3246a76524b
@@@ -122,14 -132,9 +132,15 @@@ elfw2(LIBELFBITS,newphdr) (elf, count
        result = NULL;
      }
    else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count
+          || count == PN_XNUM
           || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
      {
 +      if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))))
 +      {
 +        result = NULL;
 +        goto out;
 +      }
 +
        /* Allocate a new program header with the appropriate number of
         elements.  */
        result = (ElfW2(LIBELFBITS,Phdr) *)
Simple merge
index 4c1b1b8e87eb1f38fab95c75060142df918d494e,896d86b69d7e3b327ffb682464929dde616ec976..57b36afa5066a3a0205da326d4adcc4deca4b5d3
@@@ -287,18 -285,12 +287,21 @@@ file_read_elf (int fildes, void *map_ad
      /* Could not determine the number of sections.  */
      return NULL;
  
-   /* We can now allocate the memory.  */
 +  /* Check for too many sections.  */
 +  if (e_ident[EI_CLASS] == ELFCLASS32)
 +    {
 +      if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
 +      return NULL;
 +    }
 +  else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
 +    return NULL;
 +
+   /* We can now allocate the memory.  Even if there are no section headers,
+      we allocate space for a zeroth section in case we need it later.  */
+   const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
+                        ? 1 : 0);
    Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
-                          ELF_K_ELF, scncnt * sizeof (Elf_Scn));
+                          ELF_K_ELF, scnmax * sizeof (Elf_Scn));
    if (elf == NULL)
      /* Not enough memory.  */
      return NULL;
        {
          /* We can use the mmapped memory.  */
          elf->state.elf32.ehdr = ehdr;
 +
 +        if (unlikely (ehdr->e_shoff >= maxsize)
 +            || unlikely (maxsize - ehdr->e_shoff
 +                         < scncnt * sizeof (Elf32_Shdr)))
 +          {
 +          free_and_out:
 +            free (elf);
 +            __libelf_seterrno (ELF_E_INVALID_FILE);
 +            return NULL;
 +          }
          elf->state.elf32.shdr
            = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff);
 -        if (ehdr->e_phnum > 0)
 -          /* Assign a value only if there really is a program
 -             header.  Otherwise the value remains NULL.  */
 -          elf->state.elf32.phdr
 -            = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_phoff);
 +
-         if (ehdr->e_phnum > 0)
++        size_t phnum = ehdr->e_phnum;
++        if (phnum == PN_XNUM && scncnt > 0)
++          phnum = elf->state.elf32.shdr[0].sh_info;
++        if (phnum > 0)
 +          {
-           /* Assign a value only if there really is a program
-              header.  Otherwise the value remains NULL.  */
++            /* Assign a value only if there really is a program
++               header.  Otherwise the value remains NULL.  */
 +            if (unlikely (ehdr->e_phoff >= maxsize)
 +                || unlikely (maxsize - ehdr->e_phoff
-                              < ehdr->e_phnum * sizeof (Elf32_Phdr)))
++                             < phnum * sizeof (Elf32_Phdr)))
 +              goto free_and_out;
-           elf->state.elf32.phdr
-             = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_phoff);
++            elf->state.elf32.phdr
++              = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_phoff);
 +          }
  
          for (size_t cnt = 0; cnt < scncnt; ++cnt)
            {
        {
          /* We can use the mmapped memory.  */
          elf->state.elf64.ehdr = ehdr;
 +
 +        if (unlikely (ehdr->e_shoff >= maxsize)
 +            || unlikely (ehdr->e_shoff
 +                         + scncnt * sizeof (Elf32_Shdr) > maxsize))
 +          goto free_and_out;
          elf->state.elf64.shdr
            = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff);
 -        if (ehdr->e_phnum > 0)
 -          /* Assign a value only if there really is a program
 -             header.  Otherwise the value remains NULL.  */
 -          elf->state.elf64.phdr
 -            = (Elf64_Phdr *) ((char *) ehdr + ehdr->e_phoff);
 +
-         if (ehdr->e_phnum > 0)
++        size_t phnum = ehdr->e_phnum;
++        if (phnum == PN_XNUM && scncnt > 0)
++          phnum = elf->state.elf64.shdr[0].sh_info;
++        if (phnum > 0)
 +          {
-           /* Assign a value only if there really is a program
-              header.  Otherwise the value remains NULL.  */
++            /* Assign a value only if there really is a program
++               header.  Otherwise the value remains NULL.  */
 +            if (unlikely (ehdr->e_phoff >= maxsize)
 +                || unlikely (ehdr->e_phoff
-                              + ehdr->e_phnum
-                              * sizeof (Elf32_Phdr) > maxsize))
++                             + phnum * sizeof (Elf32_Phdr) > maxsize))
 +              goto free_and_out;
-           elf->state.elf64.phdr
-             = (Elf64_Phdr *) ((char *) ehdr + ehdr->e_phoff);
++            elf->state.elf64.phdr
++              = (Elf64_Phdr *) ((char *) ehdr + ehdr->e_phoff);
 +          }
  
          for (size_t cnt = 0; cnt < scncnt; ++cnt)
            {
Simple merge