This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PR binutils/10785 crash on freeing bim buffer
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Fri, 16 Oct 2009 17:18:27 +1030
- Subject: PR binutils/10785 crash on freeing bim buffer
Fussing about memory leaks led to this bug. Since we now free bim and
bim->buffer in bfd_close we'd better bfd_malloc them rather than
bfd_alloc, and we certainly can't allocate one area then point bim and
bim->buffer into it as was done in peicode.h.
I think this one is important enough to go onto the branch even at
this late stage. Either that or revert the 2009-08-16 opncls.c patch.
I'm still running tests on this so won't commit to the branch.
PR binutils/10785
* coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Don't bfd_alloc
bim and bim->buffer. bfd_malloc instead.
* peicode.h (pe_ILF_build_a_bfd): Similarly.
(ILF_DATA_SIZE): Don't include bim.
* opncls.c (bfd_close): Test bim->buffer non-NULL before freeing.
Index: bfd/coff-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-alpha.c,v
retrieving revision 1.40
diff -u -p -r1.40 coff-alpha.c
--- bfd/coff-alpha.c 16 Apr 2009 23:06:58 -0000 1.40
+++ bfd/coff-alpha.c 16 Oct 2009 05:57:41 -0000
@@ -2120,6 +2120,7 @@ alpha_ecoff_get_elt_at_filepos (archive,
bfd_byte *buf, *p;
struct bfd_in_memory *bim;
+ buf = NULL;
nbfd = _bfd_get_elt_at_filepos (archive, filepos);
if (nbfd == NULL)
goto error_return;
@@ -2151,16 +2152,14 @@ alpha_ecoff_get_elt_at_filepos (archive,
goto error_return;
size = H_GET_64 (nbfd, ab);
- if (size == 0)
- buf = NULL;
- else
+ if (size != 0)
{
bfd_size_type left;
bfd_byte dict[4096];
unsigned int h;
bfd_byte b;
- buf = (bfd_byte *) bfd_alloc (nbfd, size);
+ buf = (bfd_byte *) bfd_malloc (size);
if (buf == NULL)
goto error_return;
p = buf;
@@ -2214,7 +2213,7 @@ alpha_ecoff_get_elt_at_filepos (archive,
/* Now the uncompressed file contents are in buf. */
bim = ((struct bfd_in_memory *)
- bfd_alloc (nbfd, (bfd_size_type) sizeof (struct bfd_in_memory)));
+ bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
if (bim == NULL)
goto error_return;
bim->size = size;
@@ -2230,6 +2229,8 @@ alpha_ecoff_get_elt_at_filepos (archive,
return nbfd;
error_return:
+ if (buf != NULL)
+ free (buf);
if (nbfd != NULL)
bfd_close (nbfd);
return NULL;
Index: bfd/opncls.c
===================================================================
RCS file: /cvs/src/src/bfd/opncls.c,v
retrieving revision 1.58
diff -u -p -r1.58 opncls.c
--- bfd/opncls.c 9 Sep 2009 21:38:58 -0000 1.58
+++ bfd/opncls.c 16 Oct 2009 05:58:22 -0000
@@ -709,7 +709,9 @@ bfd_close (bfd *abfd)
vector.
Until that's done, at least don't leak memory. */
struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
- free (bim->buffer);
+
+ if (bim->buffer != NULL)
+ free (bim->buffer);
free (bim);
ret = TRUE;
}
Index: bfd/peicode.h
===================================================================
RCS file: /cvs/src/src/bfd/peicode.h,v
retrieving revision 1.60
diff -u -p -r1.60 peicode.h
--- bfd/peicode.h 9 Sep 2009 21:38:58 -0000 1.60
+++ bfd/peicode.h 16 Oct 2009 05:58:22 -0000
@@ -422,7 +422,6 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd,
#define SIZEOF_ILF_SECTIONS (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
#define ILF_DATA_SIZE \
- sizeof (* vars.bim) \
+ SIZEOF_ILF_SYMS \
+ SIZEOF_ILF_SYM_TABLE \
+ SIZEOF_ILF_NATIVE_SYMS \
@@ -780,15 +779,16 @@ pe_ILF_build_a_bfd (bfd * abfd
We are going to construct the contents of the BFD in memory,
so allocate all the space that we will need right now. */
- ptr = (bfd_byte *) bfd_zalloc (abfd, (bfd_size_type) ILF_DATA_SIZE);
- if (ptr == NULL)
+ vars.bim
+ = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
+ if (vars.bim == NULL)
return FALSE;
- /* Create a bfd_in_memory structure. */
- vars.bim = (struct bfd_in_memory *) ptr;
+ ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
vars.bim->buffer = ptr;
vars.bim->size = ILF_DATA_SIZE;
- ptr += sizeof (* vars.bim);
+ if (ptr == NULL)
+ goto error_return;
/* Initialise the pointers to regions of the memory and the
other contents of the pe_ILF_vars structure as well. */
@@ -842,7 +842,7 @@ pe_ILF_build_a_bfd (bfd * abfd
id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
if (id4 == NULL || id5 == NULL)
- return FALSE;
+ goto error_return;
/* Fill in the contents of these sections. */
if (import_name_type == IMPORT_ORDINAL)
@@ -869,7 +869,7 @@ pe_ILF_build_a_bfd (bfd * abfd
/* Create .idata$6 - the Hint Name Table. */
id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
if (id6 == NULL)
- return FALSE;
+ goto error_return;
/* If necessary, trim the import symbol name. */
symbol = symbol_name;
@@ -936,7 +936,7 @@ pe_ILF_build_a_bfd (bfd * abfd
/* Create the .text section. */
text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
if (text == NULL)
- return FALSE;
+ goto error_return;
/* Copy in the jump code. */
memcpy (text->contents, jtab[i].data, jtab[i].size);
@@ -985,10 +985,10 @@ pe_ILF_build_a_bfd (bfd * abfd
if ( ! bfd_set_start_address (abfd, (bfd_vma) 0)
|| ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
- return FALSE;
+ goto error_return;
if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
- return FALSE;
+ goto error_return;
coff_data (abfd)->pe = 1;
#ifdef THUMBPEMAGIC
@@ -1050,6 +1050,12 @@ pe_ILF_build_a_bfd (bfd * abfd
abfd->flags |= HAS_SYMS;
return TRUE;
+
+ error_return:
+ if (vars.bim->buffer != NULL)
+ free (vars.bim->buffer);
+ free (vars.bim);
+ return FALSE;
}
/* We have detected a Image Library Format archive element.
--
Alan Modra
Australia Development Lab, IBM