From fe4c2d55634c700ba527ac4183e05c66e9f93c62 Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Mon, 21 Oct 2019 11:27:43 +0100 Subject: [PATCH] libctf: create: non-root-visible types should not appear in name tables We were accidentally interning newly-added and newly-opened non-root-visible types into name tables, and removing names from name tables when such types were removed. This is very wrong: the whole point of non-root-visible types is they do not go in name tables and cannot be looked up by name. This bug made non-root-visible types basically identical to root-visible types, right back to the earliest days of libctf in the Solaris era. libctf/ * ctf-open.c (init_types): Only intern root-visible types. * ctf-create.c (ctf_dtd_insert): Likewise. (ctf_dtd_delete): Only remove root-visible types. (ctf_rollback): Likewise. (ctf_add_generic): Adjust. (ctf_add_struct_sized): Adjust comment. (ctf_add_union_sized): Likewise. (ctf_add_enum): Likewise. * ctf-impl.h (ctf_dtd_insert): Adjust prototype. --- libctf/ChangeLog | 12 ++++++++++++ libctf/ctf-create.c | 19 ++++++++++--------- libctf/ctf-impl.h | 2 +- libctf/ctf-open.c | 37 ++++++++++++++++++++++++++++++------- 4 files changed, 53 insertions(+), 17 deletions(-) diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 5f7bdf34c28..056cb7b929d 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,15 @@ +2020-06-26 Nick Alcock + + * ctf-open.c (init_types): Only intern root-visible types. + * ctf-create.c (ctf_dtd_insert): Likewise. + (ctf_dtd_delete): Only remove root-visible types. + (ctf_rollback): Likewise. + (ctf_add_generic): Adjust. + (ctf_add_struct_sized): Adjust comment. + (ctf_add_union_sized): Likewise. + (ctf_add_enum): Likewise. + * ctf-impl.h (ctf_dtd_insert): Adjust prototype. + 2020-03-11 John Baldwin * swap.h (bswap_identity_64): Make static. diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index ed9bfc5c318..e8e80287cb3 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -597,13 +597,13 @@ ctf_name_table (ctf_file_t *fp, int kind) } int -ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd, int kind) +ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd, int flag, int kind) { const char *name; if (ctf_dynhash_insert (fp->ctf_dthash, (void *) dtd->dtd_type, dtd) < 0) return -1; - if (dtd->dtd_data.ctt_name + if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL) { if (ctf_dynhash_insert (ctf_name_table (fp, kind)->ctn_writable, @@ -646,7 +646,8 @@ ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd) } if (dtd->dtd_data.ctt_name - && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL) + && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL + && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info)) { ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable, name); @@ -762,7 +763,8 @@ ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id) kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info); if (dtd->dtd_data.ctt_name - && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL) + && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL + && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info)) { ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable, name); @@ -831,7 +833,7 @@ ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name, int kind, return (ctf_set_errno (fp, EAGAIN)); } - if (ctf_dtd_insert (fp, dtd, kind) < 0) + if (ctf_dtd_insert (fp, dtd, flag, kind) < 0) { free (dtd); return CTF_ERR; /* errno is set for us. */ @@ -1094,8 +1096,7 @@ ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name, ctf_dtdef_t *dtd; ctf_id_t type = 0; - /* Promote forwards to structs. */ - + /* Promote root-visible forwards to structs. */ if (name != NULL) type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name); @@ -1132,7 +1133,7 @@ ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name, ctf_dtdef_t *dtd; ctf_id_t type = 0; - /* Promote forwards to unions. */ + /* Promote root-visible forwards to unions. */ if (name != NULL) type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name); @@ -1168,7 +1169,7 @@ ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name) ctf_dtdef_t *dtd; ctf_id_t type = 0; - /* Promote forwards to enums. */ + /* Promote root-visible forwards to enums. */ if (name != NULL) type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name); diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index 267801d12db..56ef9a33ba2 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -399,7 +399,7 @@ extern void ctf_list_prepend (ctf_list_t *, void *); extern void ctf_list_delete (ctf_list_t *, void *); extern int ctf_list_empty_p (ctf_list_t *lp); -extern int ctf_dtd_insert (ctf_file_t *, ctf_dtdef_t *, int); +extern int ctf_dtd_insert (ctf_file_t *, ctf_dtdef_t *, int flag, int kind); extern void ctf_dtd_delete (ctf_file_t *, ctf_dtdef_t *); extern ctf_dtdef_t *ctf_dtd_lookup (const ctf_file_t *, ctf_id_t); extern ctf_dtdef_t *ctf_dynamic_type (const ctf_file_t *, ctf_id_t); diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index 64081464425..4daa1e45351 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -765,7 +765,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) for (id = 1, tp = tbuf; tp < tend; xp++, id++) { unsigned short kind = LCTF_INFO_KIND (fp, tp->ctt_info); - unsigned short flag = LCTF_INFO_ISROOT (fp, tp->ctt_info); + unsigned short isroot = LCTF_INFO_ISROOT (fp, tp->ctt_info); unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info); ssize_t size, increment, vbytes; @@ -787,7 +787,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) if (((ctf_hash_lookup_type (fp->ctf_names.ctn_readonly, fp, name)) == 0) - || (flag & CTF_ADD_ROOT)) + || isroot) { err = ctf_hash_define_type (fp->ctf_names.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), @@ -804,6 +804,9 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_FUNCTION: + if (!isroot) + break; + err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); @@ -812,6 +815,12 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_STRUCT: + if (size >= CTF_LSTRUCT_THRESH) + nlstructs++; + + if (!isroot) + break; + err = ctf_hash_define_type (fp->ctf_structs.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); @@ -819,23 +828,27 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) if (err != 0) return err; - if (size >= CTF_LSTRUCT_THRESH) - nlstructs++; break; case CTF_K_UNION: + if (size >= CTF_LSTRUCT_THRESH) + nlunions++; + + if (!isroot) + break; + err = ctf_hash_define_type (fp->ctf_unions.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); if (err != 0) return err; - - if (size >= CTF_LSTRUCT_THRESH) - nlunions++; break; case CTF_K_ENUM: + if (!isroot) + break; + err = ctf_hash_define_type (fp->ctf_enums.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); @@ -845,6 +858,9 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_TYPEDEF: + if (!isroot) + break; + err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); @@ -855,6 +871,10 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) case CTF_K_FORWARD: { ctf_names_t *np = ctf_name_table (fp, tp->ctt_type); + + if (!isroot) + break; + /* Only insert forward tags into the given hash if the type or tag name is not already present. */ if (ctf_hash_lookup_type (np->ctn_readonly, fp, name) == 0) @@ -881,6 +901,9 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: + if (!isroot) + break; + err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); -- 2.30.2