From: Nick Alcock Date: Thu, 27 Feb 2025 19:27:00 +0000 (+0000) Subject: types: add some more error checking X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=456d5bedcccae4ace2b28f4871ebba4cebed8efc;p=thirdparty%2Fbinutils-gdb.git types: add some more error checking 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... --- diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index 33c13b52fd6..3262c4e6790 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -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; diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index b4567c0fba2..6a3dff3e4ca 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -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);