]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
types: add some more error checking
authorNick Alcock <nick.alcock@oracle.com>
Thu, 27 Feb 2025 19:27:00 +0000 (19:27 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Sun, 16 Mar 2025 15:25:28 +0000 (15:25 +0000)
A few places with inadequate error checking have fallen out of the
ctf_id_t work:

 - ctf_add_slice doesn't make sure that the type it is slicing
   actually exists
 - ctf_add_member_offset doesn't check that the type of the member
   exists (though it will often fail if it doesn't, it doesn't
   explicitly check, so if you're unlucky it can sometimes succeed,
   giving you a corrupted dict)
 - ctf_type_encoding doesn't check whether its slied type exists:
   it should verify it so it can return a decent error, rather than
   a thoroughly misleading one
 - ctf_type_compat has the same problem with respect to both of its
   arguments. It would definitely be nicer if we could call
   ctf_type_compat and just get a boolean answer, but it's not
   clear to me whether a type can be said to be compatible *or*
   incompatible with a nonexistent one, and we should probably alert
   the users to a likely bug regardless.  C error checking, sigh...

libctf/ctf-create.c
libctf/ctf-types.c

index 33c13b52fd63fc79a9766dd18a5093e0c70ea4e0..3262c4e679066d296c22818e1d57c6dc315406f6 100644 (file)
@@ -690,7 +690,8 @@ ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
      point to the unimplemented type, for now, because the compiler can emit
      such slices, though they're not very much use.  */
 
-  resolved_ref = ctf_type_resolve_unsliced (fp, ref);
+  if ((resolved_ref = ctf_type_resolve_unsliced (fp, ref)) == CTF_ERR)
+    return CTF_ERR;            /* errno is set for us.  */
   kind = ctf_type_kind_unsliced (fp, resolved_ref);
 
   if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
@@ -1229,6 +1230,7 @@ ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
                       ctf_id_t type, unsigned long bit_offset)
 {
   ctf_dict_t *ofp = fp;
+  ctf_dict_t *tmp = fp;
   ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
 
   ssize_t msize, malign, ssize;
@@ -1260,6 +1262,9 @@ ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
   if (dtd == NULL)
     return (ctf_set_errno (ofp, ECTF_BADID));
 
+  if ((ctf_lookup_by_id (&tmp, type)) == NULL)
+    return -1;                 /* errno is set for us.  */
+
   if (name != NULL && name[0] == '\0')
     name = NULL;
 
index b4567c0fba2768c16c25c6c0dc4b92f9a7d85f90..6a3dff3e4ca5813658720aaf327ec899d5b1b640 100644 (file)
@@ -1348,7 +1348,9 @@ ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
        ctf_id_t underlying;
 
        slice = (ctf_slice_t *) vlen;
-       underlying = ctf_type_resolve (ofp, slice->cts_type);
+       if ((underlying = ctf_type_resolve (ofp, slice->cts_type)) == CTF_ERR)
+         return -1;
+
        if (ctf_type_encoding (ofp, underlying, &underlying_en) < 0)
          return -1;                            /* errno is set for us.  */
 
@@ -1408,7 +1410,7 @@ ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
   const ctf_type_t *ltp, *rtp;
   ctf_encoding_t le, re;
   ctf_arinfo_t la, ra;
-  uint32_t lkind, rkind;
+  int lkind, rkind;
   int same_names = 0;
 
   if (lfp->ctf_flags & LCTF_NO_STR)
@@ -1427,11 +1429,17 @@ ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
     return 1;
 
   ltype = ctf_type_resolve (lfp, ltype);
-  lkind = ctf_type_kind (lfp, ltype);
-
   rtype = ctf_type_resolve (rfp, rtype);
+
+  if (ltype == CTF_ERR || rtype == CTF_ERR)
+    return -1;                                 /* errno is set for us.  */
+
+  lkind = ctf_type_kind (lfp, ltype);
   rkind = ctf_type_kind (rfp, rtype);
 
+  if (lkind < 0 || rkind < 0)
+    return -1;                                 /* errno is set for us.  */
+
   ltp = ctf_lookup_by_id (&lfp, ltype);
   rtp = ctf_lookup_by_id (&rfp, rtype);