On Fri, Jul 14, 2023 at 2:40 PM Christian Göttsche <cgzones@xxxxxxxxxxxxxx> wrote: > > Support the destruction of the hashtable entries via an optional > callback in hashtab_destroy(), to avoid iterating the hashtable twice in > common use cases, one time for the entry destruction via hashtab_map() > and a second time via hashtab_destroy() to free the hashtable itself. > > Also convert all the destroy callbacks to return void instead of the > needless value of 0. > > Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> > --- > checkpolicy/module_compiler.c | 6 +- > libsepol/cil/src/cil_binary.c | 9 +-- > libsepol/cil/src/cil_strpool.c | 6 +- > libsepol/cil/src/cil_symtab.c | 6 +- > libsepol/include/sepol/policydb/conditional.h | 2 +- > libsepol/include/sepol/policydb/hashtab.h | 8 ++- > libsepol/include/sepol/policydb/policydb.h | 2 +- > libsepol/src/conditional.c | 3 +- > libsepol/src/hashtab.c | 7 ++- > libsepol/src/policydb.c | 55 +++++++------------ > libsepol/src/symtab.c | 3 +- > libsepol/src/write.c | 6 +- > 12 files changed, 48 insertions(+), 65 deletions(-) > > diff --git a/checkpolicy/module_compiler.c b/checkpolicy/module_compiler.c > index 5fe1729a..554b625f 100644 > --- a/checkpolicy/module_compiler.c > +++ b/checkpolicy/module_compiler.c > @@ -761,20 +761,18 @@ int add_perm_to_class(uint32_t perm_value, uint32_t class_value) > return 0; > } > > -static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > if (key) > free(key); > free(datum); > - return 0; > } > > static void class_datum_destroy(class_datum_t * cladatum) > { > if (cladatum != NULL) { > - hashtab_map(cladatum->permissions.table, perm_destroy, NULL); > - hashtab_destroy(cladatum->permissions.table); > + hashtab_destroy(cladatum->permissions.table, perm_destroy, NULL); > free(cladatum); > } > } > diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c > index ea0cef32..8aa305c9 100644 > --- a/libsepol/cil/src/cil_binary.c > +++ b/libsepol/cil/src/cil_binary.c > @@ -1984,13 +1984,11 @@ exit: > return rc; > } > > -static int __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args) > +static void __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args) > { > free(k); > ebitmap_destroy(datum); > free(datum); > - > - return SEPOL_OK; > } > > static int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) > @@ -5230,9 +5228,8 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p > rc = SEPOL_OK; > > exit: > - hashtab_destroy(role_trans_table); > - hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL); > - hashtab_destroy(avrulex_ioctl_table); > + hashtab_destroy(role_trans_table, NULL, NULL); > + hashtab_destroy(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL); > free(type_value_to_cil); > free(class_value_to_cil); > if (perm_value_to_cil != NULL) { > diff --git a/libsepol/cil/src/cil_strpool.c b/libsepol/cil/src/cil_strpool.c > index e32ee4e9..18ecfe87 100644 > --- a/libsepol/cil/src/cil_strpool.c > +++ b/libsepol/cil/src/cil_strpool.c > @@ -87,12 +87,11 @@ char *cil_strpool_add(const char *str) > return strpool_ref->str; > } > > -static int cil_strpool_entry_destroy(hashtab_key_t k __attribute__ ((unused)), hashtab_datum_t d, void *args __attribute__ ((unused))) > +static void cil_strpool_entry_destroy(hashtab_key_t k __attribute__ ((unused)), hashtab_datum_t d, void *args __attribute__ ((unused))) > { > struct cil_strpool_entry *strpool_ref = (struct cil_strpool_entry*)d; > free(strpool_ref->str); > free(strpool_ref); > - return SEPOL_OK; > } > > void cil_strpool_init(void) > @@ -115,8 +114,7 @@ void cil_strpool_destroy(void) > pthread_mutex_lock(&cil_strpool_mutex); > cil_strpool_readers--; > if (cil_strpool_readers == 0) { > - hashtab_map(cil_strpool_tab, cil_strpool_entry_destroy, NULL); > - hashtab_destroy(cil_strpool_tab); > + hashtab_destroy(cil_strpool_tab, cil_strpool_entry_destroy, NULL); > cil_strpool_tab = NULL; > } > pthread_mutex_unlock(&cil_strpool_mutex); > diff --git a/libsepol/cil/src/cil_symtab.c b/libsepol/cil/src/cil_symtab.c > index 7e43a690..73cdd734 100644 > --- a/libsepol/cil/src/cil_symtab.c > +++ b/libsepol/cil/src/cil_symtab.c > @@ -133,18 +133,16 @@ int cil_symtab_map(symtab_t *symtab, > return hashtab_map(symtab->table, apply, args); > } > > -static int __cil_symtab_destroy_helper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, __attribute__((unused)) void *args) > +static void __cil_symtab_destroy_helper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, __attribute__((unused)) void *args) > { > struct cil_symtab_datum *datum = d; > datum->symtab = NULL; > - return SEPOL_OK; > } > > void cil_symtab_destroy(symtab_t *symtab) > { > if (symtab->table != NULL){ > - cil_symtab_map(symtab, __cil_symtab_destroy_helper, NULL); > - hashtab_destroy(symtab->table); > + hashtab_destroy(symtab->table, __cil_symtab_destroy_helper, NULL); > symtab->table = NULL; > } > } > diff --git a/libsepol/include/sepol/policydb/conditional.h b/libsepol/include/sepol/policydb/conditional.h > index 5318ea19..9b19946b 100644 > --- a/libsepol/include/sepol/policydb/conditional.h > +++ b/libsepol/include/sepol/policydb/conditional.h > @@ -127,7 +127,7 @@ extern void cond_policydb_destroy(policydb_t * p); > extern void cond_list_destroy(cond_list_t * list); > > extern int cond_init_bool_indexes(policydb_t * p); > -extern int cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p); > +extern void cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p); > > extern int cond_index_bool(hashtab_key_t key, hashtab_datum_t datum, > void *datap); > diff --git a/libsepol/include/sepol/policydb/hashtab.h b/libsepol/include/sepol/policydb/hashtab.h > index 354ebb43..7aa88f3b 100644 > --- a/libsepol/include/sepol/policydb/hashtab.h > +++ b/libsepol/include/sepol/policydb/hashtab.h > @@ -89,8 +89,14 @@ extern hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t k); > > /* > Destroys the specified hash table. > + Applies the specified destroy function to (key,datum,args) for > + all entries. > + > */ > -extern void hashtab_destroy(hashtab_t h); > +extern void hashtab_destroy(hashtab_t h, > + void (*destroy) (hashtab_key_t k, > + hashtab_datum_t d, > + void *args), void *args); > The args argument is never used. For hashtab_map() it is in other cases, but not in the case of destroying the items in the hashtab. Also, 1/3 of the calls to hashtab_destroy() do not even need to pass in a destroy function. I think that it would make more sense to create a new function (without the args argument) that could be used to destroy both the elements and the hashtab. If the destroy function is not needed, then the old hashtab_destroy() function could be used. If something more complex comes up in the future, there would still be the option of using the hashtab_map() and the hashtab_destroy() functions to deal with it. Thanks, Jim > /* > Applies the specified apply function to (key,datum,args) > diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h > index 48b7b8bb..8cf82da6 100644 > --- a/libsepol/include/sepol/policydb/policydb.h > +++ b/libsepol/include/sepol/policydb/policydb.h > @@ -634,7 +634,7 @@ extern int policydb_context_isvalid(const policydb_t * p, > const context_struct_t * c); > > extern void symtabs_destroy(symtab_t * symtab); > -extern int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p); > +extern void scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p); > > extern void class_perm_node_init(class_perm_node_t * x); > extern void type_set_init(type_set_t * x); > diff --git a/libsepol/src/conditional.c b/libsepol/src/conditional.c > index 7900e928..b51639d4 100644 > --- a/libsepol/src/conditional.c > +++ b/libsepol/src/conditional.c > @@ -528,13 +528,12 @@ int cond_init_bool_indexes(policydb_t * p) > return 0; > } > > -int cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p > +void cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > if (key) > free(key); > free(datum); > - return 0; > } > > int cond_index_bool(hashtab_key_t key, hashtab_datum_t datum, void *datap) > diff --git a/libsepol/src/hashtab.c b/libsepol/src/hashtab.c > index 922a8a4a..7f3dd00b 100644 > --- a/libsepol/src/hashtab.c > +++ b/libsepol/src/hashtab.c > @@ -193,7 +193,10 @@ hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t key) > return cur->datum; > } > > -void hashtab_destroy(hashtab_t h) > +void hashtab_destroy(hashtab_t h, > + void (*destroy) (hashtab_key_t k, > + hashtab_datum_t d, > + void *args), void *args) > { > unsigned int i; > hashtab_ptr_t cur, temp; > @@ -206,6 +209,8 @@ void hashtab_destroy(hashtab_t h) > while (cur != NULL) { > temp = cur; > cur = cur->next; > + if (destroy) > + destroy(temp->key, temp->datum, args); > free(temp); > } > h->htable[i] = NULL; > diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c > index 552eb77a..f443ea88 100644 > --- a/libsepol/src/policydb.c > +++ b/libsepol/src/policydb.c > @@ -895,10 +895,10 @@ int policydb_init(policydb_t * p) > > return 0; > err: > - hashtab_destroy(p->range_tr); > + hashtab_destroy(p->range_tr, NULL, NULL); > for (i = 0; i < SYM_NUM; i++) { > - hashtab_destroy(p->symtab[i].table); > - hashtab_destroy(p->scope[i].table); > + hashtab_destroy(p->symtab[i].table, NULL, NULL); > + hashtab_destroy(p->scope[i].table, NULL, NULL); > } > avrule_block_list_destroy(p->global); > return rc; > @@ -1264,16 +1264,15 @@ int policydb_index_others(sepol_handle_t * handle, > * symbol data in the policy database. > */ > > -static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > if (key) > free(key); > free(datum); > - return 0; > } > > -static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > common_datum_t *comdatum; > @@ -1281,13 +1280,11 @@ static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > if (key) > free(key); > comdatum = (common_datum_t *) datum; > - (void)hashtab_map(comdatum->permissions.table, perm_destroy, 0); > - hashtab_destroy(comdatum->permissions.table); > + hashtab_destroy(comdatum->permissions.table, perm_destroy, NULL); > free(datum); > - return 0; > } > > -static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > class_datum_t *cladatum; > @@ -1297,10 +1294,9 @@ static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > free(key); > cladatum = (class_datum_t *) datum; > if (cladatum == NULL) { > - return 0; > + return; > } > - (void)hashtab_map(cladatum->permissions.table, perm_destroy, 0); > - hashtab_destroy(cladatum->permissions.table); > + hashtab_destroy(cladatum->permissions.table, perm_destroy, NULL); > constraint = cladatum->constraints; > while (constraint) { > constraint_expr_destroy(constraint->expr); > @@ -1320,37 +1316,33 @@ static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > if (cladatum->comkey) > free(cladatum->comkey); > free(datum); > - return 0; > } > > -static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > free(key); > role_datum_destroy((role_datum_t *) datum); > free(datum); > - return 0; > } > > -static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > free(key); > type_datum_destroy((type_datum_t *) datum); > free(datum); > - return 0; > } > > -static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > free(key); > user_datum_destroy((user_datum_t *) datum); > free(datum); > - return 0; > } > > -static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > level_datum_t *levdatum; > @@ -1362,25 +1354,23 @@ static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > free(levdatum->level); > level_datum_destroy(levdatum); > free(levdatum); > - return 0; > } > > -static int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +static void cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > if (key) > free(key); > cat_datum_destroy((cat_datum_t *) datum); > free(datum); > - return 0; > } > > -static int (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, > +static void (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, > void *datap) = { > common_destroy, class_destroy, role_destroy, type_destroy, user_destroy, > cond_destroy_bool, sens_destroy, cat_destroy,}; > > -static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum, > +static void range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum, > void *p __attribute__ ((unused))) > { > struct mls_range *rt = (struct mls_range *)datum; > @@ -1388,7 +1378,6 @@ static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum, > ebitmap_destroy(&rt->level[0].cat); > ebitmap_destroy(&rt->level[1].cat); > free(datum); > - return 0; > } > > static void ocontext_selinux_free(ocontext_t **ocontexts) > @@ -1468,8 +1457,7 @@ void policydb_destroy(policydb_t * p) > free(p->decl_val_to_struct); > > for (i = 0; i < SYM_NUM; i++) { > - (void)hashtab_map(p->scope[i].table, scope_destroy, 0); > - hashtab_destroy(p->scope[i].table); > + hashtab_destroy(p->scope[i].table, scope_destroy, NULL); > } > avrule_block_list_destroy(p->global); > free(p->name); > @@ -1515,8 +1503,7 @@ void policydb_destroy(policydb_t * p) > if (lra) > free(lra); > > - hashtab_map(p->range_tr, range_tr_destroy, NULL); > - hashtab_destroy(p->range_tr); > + hashtab_destroy(p->range_tr, range_tr_destroy, NULL); > > if (p->type_attr_map) { > for (i = 0; i < p->p_types.nprim; i++) { > @@ -1539,12 +1526,11 @@ void symtabs_destroy(symtab_t * symtab) > { > int i; > for (i = 0; i < SYM_NUM; i++) { > - (void)hashtab_map(symtab[i].table, destroy_f[i], 0); > - hashtab_destroy(symtab[i].table); > + hashtab_destroy(symtab[i].table, destroy_f[i], NULL); > } > } > > -int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > +void scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > __attribute__ ((unused))) > { > scope_datum_t *cur = (scope_datum_t *) datum; > @@ -1553,7 +1539,6 @@ int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p > free(cur->decl_ids); > } > free(cur); > - return 0; > } > > /* > diff --git a/libsepol/src/symtab.c b/libsepol/src/symtab.c > index a6061851..3430bfc0 100644 > --- a/libsepol/src/symtab.c > +++ b/libsepol/src/symtab.c > @@ -51,7 +51,6 @@ void symtab_destroy(symtab_t * s) > if (!s) > return; > if (s->table) > - hashtab_destroy(s->table); > - return; > + hashtab_destroy(s->table, NULL, NULL); > } > /* FLASK */ > diff --git a/libsepol/src/write.c b/libsepol/src/write.c > index f0ed9e33..2eb08bb7 100644 > --- a/libsepol/src/write.c > +++ b/libsepol/src/write.c > @@ -539,7 +539,7 @@ static int filenametr_cmp(hashtab_t h __attribute__ ((unused)), > return strcmp(ft1->name, ft2->name); > } > > -static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum, > +static void filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum, > void *p __attribute__ ((unused))) > { > filenametr_key_t *ft = (filenametr_key_t *)key; > @@ -553,7 +553,6 @@ static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum, > free(fd); > fd = next; > } while (fd); > - return 0; > } > > typedef struct { > @@ -778,8 +777,7 @@ static int avtab_filename_trans_write(policydb_t *pol, avtab_t *a, > > out: > /* destroy temp filename transitions table */ > - hashtab_map(fnts_tab, filenametr_destroy, NULL); > - hashtab_destroy(fnts_tab); > + hashtab_destroy(fnts_tab, filenametr_destroy, NULL); > > return rc ? -1 : 0; > } > -- > 2.40.1 >