This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
[PATCH]: bfd: elf_core_file_p clobbers existing data
- To: gdb-patches at sourceware dot cygnus dot com, ian at zembu dot com
- Subject: [PATCH]: bfd: elf_core_file_p clobbers existing data
- From: msnyder at cygnus dot com
- Date: Fri, 7 Apr 2000 10:13:26 -0700 (PDT)
- Cc: bfd-local at cygnus dot com
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;
}