This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH]: bfd: elf_core_file_p clobbers existing data



This is a re-submission of the patch that I withdrew yesterday.
The function 'elf_core_file_p' allocates a data structure without
checking to see if it has already been allocated.  Since the function
is called repeatedly, it may clobber data that it has saved from
a previous call.  This patch (modeled after the behavior of 
'elf_object_p') saves the previous data, and restores it (while
incidentally freeing the new allocation) if the current call is
unsuccessful.

2000-04-06  Michael Snyder  <msnyder@seadog.cygnus.com>

        * elfcore.h (elf_core_file_p): preserve value of tdata at entry,
        and restore it on failure.  Release newly allocated tdata on
        failure.

Index: elfcore.h
===================================================================
RCS file: /cvs/src/src/bfd/elfcore.h,v
retrieving revision 1.2
diff -c -r1.2 elfcore.h
*** elfcore.h	2000/04/07 03:59:23	1.2
--- elfcore.h	2000/04/07 17:11:52
***************
*** 83,91 ****
  {
    Elf_External_Ehdr x_ehdr;	/* Elf file header, external form */
    Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */
!   Elf_Internal_Phdr *i_phdrp;	/* Elf program header, internal form */
    unsigned int phindex;
    struct elf_backend_data *ebd;
  
    /* Read in the ELF header in external format.  */
    if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
--- 83,93 ----
  {
    Elf_External_Ehdr x_ehdr;	/* Elf file header, external form */
    Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */
!   Elf_Internal_Phdr *i_phdrp = NULL;	/* Elf program header, internal form */
    unsigned int phindex;
    struct elf_backend_data *ebd;
+   struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
+   struct elf_obj_tdata *new_tdata = NULL;
  
    /* Read in the ELF header in external format.  */
    if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
***************
*** 98,106 ****
    /* Check the magic number. */
    if (elf_file_p (&x_ehdr) == false)
      {
!     wrong:
!       bfd_set_error (bfd_error_wrong_format);
!       return NULL;
      }
  
    /* FIXME: Check EI_VERSION here ! */
--- 100,106 ----
    /* Check the magic number. */
    if (elf_file_p (&x_ehdr) == false)
      {
!       goto wrong;
      }
  
    /* FIXME: Check EI_VERSION here ! */
***************
*** 125,136 ****
      }
  
    /* Give abfd an elf_obj_tdata. */
!   elf_tdata (abfd) =
      (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
!   if (elf_tdata (abfd) == NULL)
      return NULL;
! 
!   /* FIXME: from here on down, "goto wrong" will leak memory.  */
  
    /* Swap in the rest of the header, now that we have the byte order. */
    i_ehdrp = elf_elfheader (abfd);
--- 125,135 ----
      }
  
    /* Give abfd an elf_obj_tdata. */
!   new_tdata = 
      (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
!   if (new_tdata == NULL)
      return NULL;
!   elf_tdata (abfd) = new_tdata;  
  
    /* Swap in the rest of the header, now that we have the byte order. */
    i_ehdrp = elf_elfheader (abfd);
***************
*** 189,195 ****
    i_phdrp = (Elf_Internal_Phdr *)
      bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
    if (!i_phdrp)
!     return NULL;
  
    elf_tdata (abfd)->phdr = i_phdrp;
  
--- 188,194 ----
    i_phdrp = (Elf_Internal_Phdr *)
      bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
    if (!i_phdrp)
!     goto fail;
  
    elf_tdata (abfd)->phdr = i_phdrp;
  
***************
*** 199,205 ****
        Elf_External_Phdr x_phdr;
        if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd)
  	  != sizeof (x_phdr))
! 	return NULL;
  
        elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
      }
--- 198,204 ----
        Elf_External_Phdr x_phdr;
        if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd)
  	  != sizeof (x_phdr))
! 	goto fail;
  
        elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
      }
***************
*** 208,214 ****
    for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
      {
        if (!_bfd_elfcore_section_from_phdr (abfd, i_phdrp + phindex, phindex))
! 	return NULL;
      }
  
    /* Set the machine architecture. */
--- 207,213 ----
    for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
      {
        if (!_bfd_elfcore_section_from_phdr (abfd, i_phdrp + phindex, phindex))
! 	goto fail;
      }
  
    /* Set the machine architecture. */
***************
*** 216,222 ****
      {
        /* It's OK if this fails for the generic target.  */
        if (ebd->elf_machine_code != EM_NONE)
! 	return NULL;
      }
  
    /* Save the entry point from the ELF header. */
--- 215,221 ----
      {
        /* It's OK if this fails for the generic target.  */
        if (ebd->elf_machine_code != EM_NONE)
! 	goto fail;
      }
  
    /* Save the entry point from the ELF header. */
***************
*** 231,234 ****
--- 230,243 ----
      }
  
    return abfd->xvec;
+ 
+ wrong:
+   bfd_set_error (bfd_error_wrong_format);
+ fail:
+   if (i_phdrp != NULL)
+     bfd_release (abfd, i_phdrp);
+   if (new_tdata != NULL)
+     bfd_release (abfd, new_tdata);
+   elf_tdata (abfd) = preserved_tdata;
+   return NULL;
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]