Checks
Commit Message
My recent change to closing archives showed some problems with the way
we stash errors for archive elements. The most obvious thing found
by oss-fuzz, is that if output archive elements are closed during
bfd_close of an archive, then we can't access the element filename
when printing the element. So change bfd_set_input_error to stash the
entire error message instead of input bfd and input error.
* bfd.c (input_bfd, input_error): Delete.
(bfd_error, _bfd_error_buf): Move.
(_bfd_clear_error_data): Move. Make static. Clear bfd_error too.
(bfd_set_input_error): Print the error use bfd_asprintf here..
(bfd_errmsg): ..not here.
(bfd_init): Update.
* opncls.c (bfd_close_all_done): Don't call _bfd_clear_error_data.
* libbfd.h: Regenerate.
@@ -768,11 +768,6 @@ CODE_FRAGMENT
.
*/
-static TLS bfd_error_type bfd_error;
-static TLS bfd_error_type input_error;
-static TLS bfd *input_bfd;
-static TLS char *_bfd_error_buf;
-
const char *const bfd_errmsgs[] =
{
N_("no error"),
@@ -800,6 +795,19 @@ const char *const bfd_errmsgs[] =
N_("#<invalid error code>")
};
+static TLS bfd_error_type bfd_error;
+static TLS char *_bfd_error_buf;
+
+/* Free any data associated with the BFD error. */
+
+static void
+_bfd_clear_error_data (void)
+{
+ bfd_error = bfd_error_no_error;
+ free (_bfd_error_buf);
+ _bfd_error_buf = NULL;
+}
+
/*
FUNCTION
bfd_get_error
@@ -858,12 +866,12 @@ bfd_set_input_error (bfd *input, bfd_error_type error_tag)
{
/* This is an error that occurred during bfd_close when writing an
archive, but on one of the input files. */
- bfd_error = bfd_error_on_input;
_bfd_clear_error_data ();
- input_bfd = input;
- input_error = error_tag;
- if (input_error >= bfd_error_on_input)
+ if (error_tag >= bfd_error_on_input)
abort ();
+ if (bfd_asprintf (_(bfd_errmsgs[bfd_error_on_input]),
+ bfd_get_filename (input), bfd_errmsg (error_tag)))
+ bfd_error = bfd_error_on_input;
}
/*
@@ -885,16 +893,7 @@ bfd_errmsg (bfd_error_type error_tag)
extern int errno;
#endif
if (error_tag == bfd_error_on_input)
- {
- const char *msg = bfd_errmsg (input_error);
- char *ret = bfd_asprintf (_(bfd_errmsgs[error_tag]),
- bfd_get_filename (input_bfd), msg);
- if (ret)
- return ret;
-
- /* Ick, what to do on out of memory? */
- return msg;
- }
+ return _bfd_error_buf;
if (error_tag == bfd_error_system_call)
return xstrerror (errno);
@@ -931,24 +930,6 @@ bfd_perror (const char *message)
fflush (stderr);
}
-/*
-INTERNAL_FUNCTION
- _bfd_clear_error_data
-
-SYNOPSIS
- void _bfd_clear_error_data (void);
-
-DESCRIPTION
- Free any data associated with the BFD error.
-*/
-
-void
-_bfd_clear_error_data (void)
-{
- free (_bfd_error_buf);
- _bfd_error_buf = NULL;
-}
-
/*
INTERNAL_FUNCTION
bfd_asprintf
@@ -1961,10 +1942,7 @@ DESCRIPTION
unsigned int
bfd_init (void)
{
- bfd_error = bfd_error_no_error;
- input_bfd = NULL;
_bfd_clear_error_data ();
- input_error = bfd_error_no_error;
_bfd_error_internal = error_handler_fprintf;
_bfd_assert_handler = _bfd_default_assert_handler;
@@ -963,8 +963,6 @@ bool bfd_write_bigendian_4byte_int (bfd *, unsigned int) ATTRIBUTE_HIDDEN;
unsigned int bfd_log2 (bfd_vma x) ATTRIBUTE_HIDDEN;
/* Extracted from bfd.c. */
-void _bfd_clear_error_data (void) ATTRIBUTE_HIDDEN;
-
char *bfd_asprintf (const char *fmt, ...) ATTRIBUTE_HIDDEN;
/* Cached _bfd_check_format messages are put in this. */
@@ -943,7 +943,6 @@ bfd_close_all_done (bfd *abfd)
_maybe_make_executable (abfd);
_bfd_delete_bfd (abfd);
- _bfd_clear_error_data ();
return ret;
}