PR24955, libbfd terminating program on out of memory
This patch fixes the worst of the cases where libbfd might terminate a program due to calling xstrdup or xmalloc. I've also fixed some error paths that didn't clean up properly. PR 24955 * libbfd-in.h (bfd_strdup): New inline function. * archive.c (_bfd_get_elt_at_filepos): Use bfd_strdup. Close bfd on error. * elfcode.h (_bfd_elf_bfd_from_remote_memory): Use bfd_strdup. * opncls.c (bfd_fopen): Use bfd_strdup. Close fd and stream on error. (bfd_openstreamr): Use bfd_strdup. (bfd_openr_iovec, bfd_openw, bfd_create): Likewise. * plugin.c (try_load_plugin): Use bfd_malloc. * libbfd.h: Regenerate.
This commit is contained in:
parent
809f915398
commit
89bdc77eab
@ -1,3 +1,17 @@
|
|||||||
|
2019-09-05 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR 24955
|
||||||
|
* libbfd-in.h (bfd_strdup): New inline function.
|
||||||
|
* archive.c (_bfd_get_elt_at_filepos): Use bfd_strdup. Close
|
||||||
|
bfd on error.
|
||||||
|
* elfcode.h (_bfd_elf_bfd_from_remote_memory): Use bfd_strdup.
|
||||||
|
* opncls.c (bfd_fopen): Use bfd_strdup. Close fd and stream
|
||||||
|
on error.
|
||||||
|
(bfd_openstreamr): Use bfd_strdup.
|
||||||
|
(bfd_openr_iovec, bfd_openw, bfd_create): Likewise.
|
||||||
|
* plugin.c (try_load_plugin): Use bfd_malloc.
|
||||||
|
* libbfd.h: Regenerate.
|
||||||
|
|
||||||
2019-09-02 Alan Modra <amodra@gmail.com>
|
2019-09-02 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR 11983
|
PR 11983
|
||||||
|
@ -728,7 +728,9 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
n_bfd->origin = n_bfd->proxy_origin;
|
n_bfd->origin = n_bfd->proxy_origin;
|
||||||
n_bfd->filename = xstrdup (filename);
|
n_bfd->filename = bfd_strdup (filename);
|
||||||
|
if (n_bfd->filename == NULL)
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_bfd->arelt_data = new_areldata;
|
n_bfd->arelt_data = new_areldata;
|
||||||
@ -745,8 +747,10 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
|
|||||||
|| _bfd_add_bfd_to_archive_cache (archive, filepos, n_bfd))
|
|| _bfd_add_bfd_to_archive_cache (archive, filepos, n_bfd))
|
||||||
return n_bfd;
|
return n_bfd;
|
||||||
|
|
||||||
|
out:
|
||||||
free (new_areldata);
|
free (new_areldata);
|
||||||
n_bfd->arelt_data = NULL;
|
n_bfd->arelt_data = NULL;
|
||||||
|
bfd_close (n_bfd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1652,6 +1652,7 @@ NAME(_bfd_elf,bfd_from_remote_memory)
|
|||||||
bfd_vma high_offset;
|
bfd_vma high_offset;
|
||||||
bfd_vma shdr_end;
|
bfd_vma shdr_end;
|
||||||
bfd_vma loadbase;
|
bfd_vma loadbase;
|
||||||
|
char *filename;
|
||||||
|
|
||||||
/* Read in the ELF header in external format. */
|
/* Read in the ELF header in external format. */
|
||||||
err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
|
err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
|
||||||
@ -1859,14 +1860,22 @@ NAME(_bfd_elf,bfd_from_remote_memory)
|
|||||||
free (contents);
|
free (contents);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
nbfd = _bfd_new_bfd ();
|
filename = bfd_strdup ("<in-memory>");
|
||||||
if (nbfd == NULL)
|
if (filename == NULL)
|
||||||
{
|
{
|
||||||
free (bim);
|
free (bim);
|
||||||
free (contents);
|
free (contents);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
nbfd->filename = xstrdup ("<in-memory>");
|
nbfd = _bfd_new_bfd ();
|
||||||
|
if (nbfd == NULL)
|
||||||
|
{
|
||||||
|
free (filename);
|
||||||
|
free (bim);
|
||||||
|
free (contents);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nbfd->filename = filename;
|
||||||
nbfd->xvec = templ->xvec;
|
nbfd->xvec = templ->xvec;
|
||||||
bim->size = high_offset;
|
bim->size = high_offset;
|
||||||
bim->buffer = contents;
|
bim->buffer = contents;
|
||||||
|
@ -123,6 +123,15 @@ extern void *bfd_realloc2
|
|||||||
extern void *bfd_zmalloc2
|
extern void *bfd_zmalloc2
|
||||||
(bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
|
(bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
bfd_strdup (const char *str)
|
||||||
|
{
|
||||||
|
size_t len = strlen (str) + 1;
|
||||||
|
char *buf = bfd_malloc (len);
|
||||||
|
if (buf != NULL)
|
||||||
|
memcpy (buf, str, len);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
/* These routines allocate and free things on the BFD's objalloc. */
|
/* These routines allocate and free things on the BFD's objalloc. */
|
||||||
|
|
||||||
extern void *bfd_alloc2
|
extern void *bfd_alloc2
|
||||||
|
@ -128,6 +128,15 @@ extern void *bfd_realloc2
|
|||||||
extern void *bfd_zmalloc2
|
extern void *bfd_zmalloc2
|
||||||
(bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
|
(bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
bfd_strdup (const char *str)
|
||||||
|
{
|
||||||
|
size_t len = strlen (str) + 1;
|
||||||
|
char *buf = bfd_malloc (len);
|
||||||
|
if (buf != NULL)
|
||||||
|
memcpy (buf, str, len);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
/* These routines allocate and free things on the BFD's objalloc. */
|
/* These routines allocate and free things on the BFD's objalloc. */
|
||||||
|
|
||||||
extern void *bfd_alloc2
|
extern void *bfd_alloc2
|
||||||
|
41
bfd/opncls.c
41
bfd/opncls.c
@ -223,6 +223,8 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
|
|||||||
if (nbfd->iostream == NULL)
|
if (nbfd->iostream == NULL)
|
||||||
{
|
{
|
||||||
bfd_set_error (bfd_error_system_call);
|
bfd_set_error (bfd_error_system_call);
|
||||||
|
if (fd != -1)
|
||||||
|
close (fd);
|
||||||
_bfd_delete_bfd (nbfd);
|
_bfd_delete_bfd (nbfd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -231,7 +233,13 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
|
|||||||
|
|
||||||
/* PR 11983: Do not cache the original filename, but
|
/* PR 11983: Do not cache the original filename, but
|
||||||
rather make a copy - the original might go away. */
|
rather make a copy - the original might go away. */
|
||||||
nbfd->filename = xstrdup (filename);
|
nbfd->filename = bfd_strdup (filename);
|
||||||
|
if (nbfd->filename == NULL)
|
||||||
|
{
|
||||||
|
fclose (nbfd->iostream);
|
||||||
|
_bfd_delete_bfd (nbfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Figure out whether the user is opening the file for reading,
|
/* Figure out whether the user is opening the file for reading,
|
||||||
writing, or both, by looking at the MODE argument. */
|
writing, or both, by looking at the MODE argument. */
|
||||||
@ -243,8 +251,9 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
|
|||||||
else
|
else
|
||||||
nbfd->direction = write_direction;
|
nbfd->direction = write_direction;
|
||||||
|
|
||||||
if (! bfd_cache_init (nbfd))
|
if (!bfd_cache_init (nbfd))
|
||||||
{
|
{
|
||||||
|
fclose (nbfd->iostream);
|
||||||
_bfd_delete_bfd (nbfd);
|
_bfd_delete_bfd (nbfd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -398,7 +407,12 @@ bfd_openstreamr (const char *filename, const char *target, void *streamarg)
|
|||||||
nbfd->iostream = stream;
|
nbfd->iostream = stream;
|
||||||
/* PR 11983: Do not cache the original filename, but
|
/* PR 11983: Do not cache the original filename, but
|
||||||
rather make a copy - the original might go away. */
|
rather make a copy - the original might go away. */
|
||||||
nbfd->filename = xstrdup (filename);
|
nbfd->filename = bfd_strdup (filename);
|
||||||
|
if (nbfd->filename == NULL)
|
||||||
|
{
|
||||||
|
_bfd_delete_bfd (nbfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
nbfd->direction = read_direction;
|
nbfd->direction = read_direction;
|
||||||
|
|
||||||
if (! bfd_cache_init (nbfd))
|
if (! bfd_cache_init (nbfd))
|
||||||
@ -594,7 +608,12 @@ bfd_openr_iovec (const char *filename, const char *target,
|
|||||||
|
|
||||||
/* PR 11983: Do not cache the original filename, but
|
/* PR 11983: Do not cache the original filename, but
|
||||||
rather make a copy - the original might go away. */
|
rather make a copy - the original might go away. */
|
||||||
nbfd->filename = xstrdup (filename);
|
nbfd->filename = bfd_strdup (filename);
|
||||||
|
if (nbfd->filename == NULL)
|
||||||
|
{
|
||||||
|
_bfd_delete_bfd (nbfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
nbfd->direction = read_direction;
|
nbfd->direction = read_direction;
|
||||||
|
|
||||||
/* `open_p (...)' would get expanded by an the open(2) syscall macro. */
|
/* `open_p (...)' would get expanded by an the open(2) syscall macro. */
|
||||||
@ -661,7 +680,12 @@ bfd_openw (const char *filename, const char *target)
|
|||||||
|
|
||||||
/* PR 11983: Do not cache the original filename, but
|
/* PR 11983: Do not cache the original filename, but
|
||||||
rather make a copy - the original might go away. */
|
rather make a copy - the original might go away. */
|
||||||
nbfd->filename = xstrdup (filename);
|
nbfd->filename = bfd_strdup (filename);
|
||||||
|
if (nbfd->filename == NULL)
|
||||||
|
{
|
||||||
|
_bfd_delete_bfd (nbfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
nbfd->direction = write_direction;
|
nbfd->direction = write_direction;
|
||||||
|
|
||||||
if (bfd_open_file (nbfd) == NULL)
|
if (bfd_open_file (nbfd) == NULL)
|
||||||
@ -801,7 +825,12 @@ bfd_create (const char *filename, bfd *templ)
|
|||||||
return NULL;
|
return NULL;
|
||||||
/* PR 11983: Do not cache the original filename, but
|
/* PR 11983: Do not cache the original filename, but
|
||||||
rather make a copy - the original might go away. */
|
rather make a copy - the original might go away. */
|
||||||
nbfd->filename = xstrdup (filename);
|
nbfd->filename = bfd_strdup (filename);
|
||||||
|
if (nbfd->filename == NULL)
|
||||||
|
{
|
||||||
|
_bfd_delete_bfd (nbfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (templ)
|
if (templ)
|
||||||
nbfd->xvec = templ->xvec;
|
nbfd->xvec = templ->xvec;
|
||||||
nbfd->direction = no_direction;
|
nbfd->direction = no_direction;
|
||||||
|
@ -262,7 +262,9 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin_list_iter = (struct plugin_list_entry *) xmalloc (sizeof *plugin_list_iter);
|
plugin_list_iter = bfd_malloc (sizeof *plugin_list_iter);
|
||||||
|
if (plugin_list_iter == NULL)
|
||||||
|
return 0;
|
||||||
plugin_list_iter->handle = plugin_handle;
|
plugin_list_iter->handle = plugin_handle;
|
||||||
plugin_list_iter->claim_file = NULL;
|
plugin_list_iter->claim_file = NULL;
|
||||||
plugin_list_iter->next = plugin_list;
|
plugin_list_iter->next = plugin_list;
|
||||||
|
Loading…
Reference in New Issue
Block a user