libctf: do not crash when CTF symbol or variable linking fails
authorNick Alcock <nick.alcock@oracle.com>
Fri, 20 Nov 2020 13:34:04 +0000 (13:34 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 20 Nov 2020 13:34:13 +0000 (13:34 +0000)
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.

libctf/ChangeLog
libctf/ctf-link.c

index 0a8da127616f5ab0d25266473f1de29f264670e7..7fdb3558f3daa8c69c082d47322bbdf11dfff99f 100644 (file)
@@ -1,3 +1,8 @@
+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.
index 4b86ca98095787316e42a4799131ffed1dde3215..cdf3db3a7c3f1d22ea80cae3135b72f394d501dc 100644 (file)
@@ -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