diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2020-11-20 13:34:04 +0000 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2020-11-20 13:34:13 +0000 |
commit | ef21dd3bcffd350f0bf27386f1eafe8095d8feec (patch) | |
tree | 8c3b7fb17d3ac94f9d1bfc6df3ccfa440d39c606 /libctf | |
parent | 8f235c90a287ee961153dd94f5ca28b033ebb668 (diff) | |
download | fsf-binutils-gdb-ef21dd3bcffd350f0bf27386f1eafe8095d8feec.zip fsf-binutils-gdb-ef21dd3bcffd350f0bf27386f1eafe8095d8feec.tar.gz fsf-binutils-gdb-ef21dd3bcffd350f0bf27386f1eafe8095d8feec.tar.bz2 |
libctf: do not crash when CTF symbol or variable linking fails
When linking fails, we delete all the generated outputs, but we fail to
remove them from the ctf_link_outputs hash we stuck them in before doing
symbol and variable section linking (which we had to do because that's
where ctf_create_per_cu, used by both, looks for them). This leaves
stale pointers to freed memory behind, and crashes soon follow.
Fix obvious.
libctf/ChangeLog
2020-11-20 Nick Alcock <nick.alcock@oracle.com>
* ctf-link.c (ctf_link_deduplicating): Clean up the ctf_link_outputs
hash on error.
Diffstat (limited to 'libctf')
-rw-r--r-- | libctf/ChangeLog | 5 | ||||
-rw-r--r-- | libctf/ctf-link.c | 16 |
2 files changed, 15 insertions, 6 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 0a8da12..7fdb355 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,5 +1,10 @@ 2020-11-20 Nick Alcock <nick.alcock@oracle.com> + * ctf-link.c (ctf_link_deduplicating): Clean up the ctf_link_outputs + hash on error. + +2020-11-20 Nick Alcock <nick.alcock@oracle.com> + * ctf-create.c (ctf_dtd_insert): Set ENOMEM on the dict if out of memory. (ctf_dvd_insert): Likewise. (ctf_add_function): Report ECTF_RDONLY if this dict is not writable. diff --git a/libctf/ctf-link.c b/libctf/ctf-link.c index 4b86ca9..cdf3db3 100644 --- a/libctf/ctf-link.c +++ b/libctf/ctf-link.c @@ -1616,18 +1616,14 @@ ctf_link_deduplicating (ctf_dict_t *fp) { ctf_err_warn (fp, 0, 0, _("deduplicating link variable emission failed for " "%s"), ctf_link_input_name (fp)); - for (i = 1; i < noutputs; i++) - ctf_dict_close (outputs[i]); - goto err; + goto err_clean_outputs; } if (ctf_link_deduplicating_syms (fp, inputs, ninputs, 0) < 0) { ctf_err_warn (fp, 0, 0, _("deduplicating link symbol emission failed for " "%s"), ctf_link_input_name (fp)); - for (i = 1; i < noutputs; i++) - ctf_dict_close (outputs[i]); - goto err; + goto err_clean_outputs; } /* Now close all the inputs, including per-CU intermediates. */ @@ -1647,6 +1643,14 @@ ctf_link_deduplicating (ctf_dict_t *fp) free (parents); free (outputs); return; + + err_clean_outputs: + for (i = 1; i < noutputs; i++) + { + ctf_dynhash_remove (fp->ctf_link_outputs, ctf_cuname (outputs[i])); + ctf_dict_close (outputs[i]); + } + goto err; } /* Merge types and variable sections in all files added to the link |