Commit 03414a49 authored by Ondrej Mosnacek's avatar Ondrej Mosnacek Committed by Paul Moore

selinux: do not allocate hashtabs dynamically

It is simpler to allocate them statically in the corresponding
structure, avoiding unnecessary kmalloc() calls and pointer
dereferencing.
Signed-off-by: default avatarOndrej Mosnacek <omosnace@redhat.com>
[PM: manual merging required in policydb.c]
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 46619b44
...@@ -29,34 +29,21 @@ static u32 hashtab_compute_size(u32 nel) ...@@ -29,34 +29,21 @@ static u32 hashtab_compute_size(u32 nel)
return nel == 0 ? 0 : roundup_pow_of_two(nel); return nel == 0 ? 0 : roundup_pow_of_two(nel);
} }
struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), int hashtab_init(struct hashtab *h,
int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), u32 (*hash_value)(struct hashtab *h, const void *key),
u32 nel_hint) int (*keycmp)(struct hashtab *h, const void *key1,
const void *key2),
u32 nel_hint)
{ {
struct hashtab *p; h->size = hashtab_compute_size(nel_hint);
u32 i, size = hashtab_compute_size(nel_hint); h->nel = 0;
h->hash_value = hash_value;
p = kzalloc(sizeof(*p), GFP_KERNEL); h->keycmp = keycmp;
if (!p) if (!h->size)
return p; return 0;
p->size = size;
p->nel = 0;
p->hash_value = hash_value;
p->keycmp = keycmp;
if (!size)
return p;
p->htable = kmalloc_array(size, sizeof(*p->htable), GFP_KERNEL);
if (!p->htable) {
kfree(p);
return NULL;
}
for (i = 0; i < size; i++)
p->htable[i] = NULL;
return p; h->htable = kcalloc(h->size, sizeof(*h->htable), GFP_KERNEL);
return h->htable ? 0 : -ENOMEM;
} }
int hashtab_insert(struct hashtab *h, void *key, void *datum) int hashtab_insert(struct hashtab *h, void *key, void *datum)
...@@ -66,7 +53,7 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum) ...@@ -66,7 +53,7 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum)
cond_resched(); cond_resched();
if (!h || !h->size || h->nel == HASHTAB_MAX_NODES) if (!h->size || h->nel == HASHTAB_MAX_NODES)
return -EINVAL; return -EINVAL;
hvalue = h->hash_value(h, key); hvalue = h->hash_value(h, key);
...@@ -102,7 +89,7 @@ void *hashtab_search(struct hashtab *h, const void *key) ...@@ -102,7 +89,7 @@ void *hashtab_search(struct hashtab *h, const void *key)
u32 hvalue; u32 hvalue;
struct hashtab_node *cur; struct hashtab_node *cur;
if (!h || !h->size) if (!h->size)
return NULL; return NULL;
hvalue = h->hash_value(h, key); hvalue = h->hash_value(h, key);
...@@ -121,9 +108,6 @@ void hashtab_destroy(struct hashtab *h) ...@@ -121,9 +108,6 @@ void hashtab_destroy(struct hashtab *h)
u32 i; u32 i;
struct hashtab_node *cur, *temp; struct hashtab_node *cur, *temp;
if (!h)
return;
for (i = 0; i < h->size; i++) { for (i = 0; i < h->size; i++) {
cur = h->htable[i]; cur = h->htable[i];
while (cur) { while (cur) {
...@@ -136,8 +120,6 @@ void hashtab_destroy(struct hashtab *h) ...@@ -136,8 +120,6 @@ void hashtab_destroy(struct hashtab *h)
kfree(h->htable); kfree(h->htable);
h->htable = NULL; h->htable = NULL;
kfree(h);
} }
int hashtab_map(struct hashtab *h, int hashtab_map(struct hashtab *h,
...@@ -148,9 +130,6 @@ int hashtab_map(struct hashtab *h, ...@@ -148,9 +130,6 @@ int hashtab_map(struct hashtab *h,
int ret; int ret;
struct hashtab_node *cur; struct hashtab_node *cur;
if (!h)
return 0;
for (i = 0; i < h->size; i++) { for (i = 0; i < h->size; i++) {
cur = h->htable[i]; cur = h->htable[i];
while (cur) { while (cur) {
......
...@@ -35,14 +35,15 @@ struct hashtab_info { ...@@ -35,14 +35,15 @@ struct hashtab_info {
}; };
/* /*
* Creates a new hash table with the specified characteristics. * Initializes a new hash table with the specified characteristics.
* *
* Returns NULL if insufficent space is available or * Returns -ENOMEM if insufficient space is available or 0 otherwise.
* the new hash table otherwise.
*/ */
struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), int hashtab_init(struct hashtab *h,
int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), u32 (*hash_value)(struct hashtab *h, const void *key),
u32 nel_hint); int (*keycmp)(struct hashtab *h, const void *key1,
const void *key2),
u32 nel_hint);
/* /*
* Inserts the specified (key, datum) pair into the specified hash table. * Inserts the specified (key, datum) pair into the specified hash table.
......
...@@ -165,7 +165,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l) ...@@ -165,7 +165,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
if (!l->sens || l->sens > p->p_levels.nprim) if (!l->sens || l->sens > p->p_levels.nprim)
return 0; return 0;
levdatum = hashtab_search(p->p_levels.table, levdatum = hashtab_search(&p->p_levels.table,
sym_name(p, SYM_LEVELS, l->sens - 1)); sym_name(p, SYM_LEVELS, l->sens - 1));
if (!levdatum) if (!levdatum)
return 0; return 0;
...@@ -293,7 +293,7 @@ int mls_context_to_sid(struct policydb *pol, ...@@ -293,7 +293,7 @@ int mls_context_to_sid(struct policydb *pol,
*(next_cat++) = '\0'; *(next_cat++) = '\0';
/* Parse sensitivity. */ /* Parse sensitivity. */
levdatum = hashtab_search(pol->p_levels.table, sensitivity); levdatum = hashtab_search(&pol->p_levels.table, sensitivity);
if (!levdatum) if (!levdatum)
return -EINVAL; return -EINVAL;
context->range.level[l].sens = levdatum->level->sens; context->range.level[l].sens = levdatum->level->sens;
...@@ -312,7 +312,7 @@ int mls_context_to_sid(struct policydb *pol, ...@@ -312,7 +312,7 @@ int mls_context_to_sid(struct policydb *pol,
*rngptr++ = '\0'; *rngptr++ = '\0';
} }
catdatum = hashtab_search(pol->p_cats.table, cur_cat); catdatum = hashtab_search(&pol->p_cats.table, cur_cat);
if (!catdatum) if (!catdatum)
return -EINVAL; return -EINVAL;
...@@ -325,7 +325,7 @@ int mls_context_to_sid(struct policydb *pol, ...@@ -325,7 +325,7 @@ int mls_context_to_sid(struct policydb *pol,
if (rngptr == NULL) if (rngptr == NULL)
continue; continue;
rngdatum = hashtab_search(pol->p_cats.table, rngptr); rngdatum = hashtab_search(&pol->p_cats.table, rngptr);
if (!rngdatum) if (!rngdatum)
return -EINVAL; return -EINVAL;
...@@ -458,7 +458,7 @@ int mls_convert_context(struct policydb *oldp, ...@@ -458,7 +458,7 @@ int mls_convert_context(struct policydb *oldp,
return 0; return 0;
for (l = 0; l < 2; l++) { for (l = 0; l < 2; l++) {
levdatum = hashtab_search(newp->p_levels.table, levdatum = hashtab_search(&newp->p_levels.table,
sym_name(oldp, SYM_LEVELS, sym_name(oldp, SYM_LEVELS,
oldc->range.level[l].sens - 1)); oldc->range.level[l].sens - 1));
...@@ -470,7 +470,7 @@ int mls_convert_context(struct policydb *oldp, ...@@ -470,7 +470,7 @@ int mls_convert_context(struct policydb *oldp,
node, i) { node, i) {
int rc; int rc;
catdatum = hashtab_search(newp->p_cats.table, catdatum = hashtab_search(&newp->p_cats.table,
sym_name(oldp, SYM_CATS, i)); sym_name(oldp, SYM_CATS, i));
if (!catdatum) if (!catdatum)
return -EINVAL; return -EINVAL;
...@@ -506,7 +506,7 @@ int mls_compute_sid(struct policydb *p, ...@@ -506,7 +506,7 @@ int mls_compute_sid(struct policydb *p,
rtr.source_type = scontext->type; rtr.source_type = scontext->type;
rtr.target_type = tcontext->type; rtr.target_type = tcontext->type;
rtr.target_class = tclass; rtr.target_class = tclass;
r = hashtab_search(p->range_tr, &rtr); r = hashtab_search(&p->range_tr, &rtr);
if (r) if (r)
return mls_range_set(newcontext, r); return mls_range_set(newcontext, r);
......
This diff is collapsed.
...@@ -263,13 +263,13 @@ struct policydb { ...@@ -263,13 +263,13 @@ struct policydb {
struct avtab te_avtab; struct avtab te_avtab;
/* role transitions */ /* role transitions */
struct hashtab *role_tr; struct hashtab role_tr;
/* file transitions with the last path component */ /* file transitions with the last path component */
/* quickly exclude lookups when parent ttype has no rules */ /* quickly exclude lookups when parent ttype has no rules */
struct ebitmap filename_trans_ttypes; struct ebitmap filename_trans_ttypes;
/* actual set of filename_trans rules */ /* actual set of filename_trans rules */
struct hashtab *filename_trans; struct hashtab filename_trans;
/* only used if policyvers < POLICYDB_VERSION_COMP_FTRANS */ /* only used if policyvers < POLICYDB_VERSION_COMP_FTRANS */
u32 compat_filename_trans_count; u32 compat_filename_trans_count;
...@@ -294,7 +294,7 @@ struct policydb { ...@@ -294,7 +294,7 @@ struct policydb {
struct genfs *genfs; struct genfs *genfs;
/* range transitions table (range_trans_key -> mls_range) */ /* range transitions table (range_trans_key -> mls_range) */
struct hashtab *range_tr; struct hashtab range_tr;
/* type -> attribute reverse mapping */ /* type -> attribute reverse mapping */
struct ebitmap *type_attr_map_array; struct ebitmap *type_attr_map_array;
......
...@@ -482,11 +482,11 @@ static void security_dump_masked_av(struct policydb *policydb, ...@@ -482,11 +482,11 @@ static void security_dump_masked_av(struct policydb *policydb,
/* init permission_names */ /* init permission_names */
if (common_dat && if (common_dat &&
hashtab_map(common_dat->permissions.table, hashtab_map(&common_dat->permissions.table,
dump_masked_av_helper, permission_names) < 0) dump_masked_av_helper, permission_names) < 0)
goto out; goto out;
if (hashtab_map(tclass_dat->permissions.table, if (hashtab_map(&tclass_dat->permissions.table,
dump_masked_av_helper, permission_names) < 0) dump_masked_av_helper, permission_names) < 0)
goto out; goto out;
...@@ -1441,7 +1441,7 @@ static int string_to_context_struct(struct policydb *pol, ...@@ -1441,7 +1441,7 @@ static int string_to_context_struct(struct policydb *pol,
*p++ = 0; *p++ = 0;
usrdatum = hashtab_search(pol->p_users.table, scontextp); usrdatum = hashtab_search(&pol->p_users.table, scontextp);
if (!usrdatum) if (!usrdatum)
goto out; goto out;
...@@ -1457,7 +1457,7 @@ static int string_to_context_struct(struct policydb *pol, ...@@ -1457,7 +1457,7 @@ static int string_to_context_struct(struct policydb *pol,
*p++ = 0; *p++ = 0;
role = hashtab_search(pol->p_roles.table, scontextp); role = hashtab_search(&pol->p_roles.table, scontextp);
if (!role) if (!role)
goto out; goto out;
ctx->role = role->value; ctx->role = role->value;
...@@ -1469,7 +1469,7 @@ static int string_to_context_struct(struct policydb *pol, ...@@ -1469,7 +1469,7 @@ static int string_to_context_struct(struct policydb *pol,
oldc = *p; oldc = *p;
*p++ = 0; *p++ = 0;
typdatum = hashtab_search(pol->p_types.table, scontextp); typdatum = hashtab_search(&pol->p_types.table, scontextp);
if (!typdatum || typdatum->attribute) if (!typdatum || typdatum->attribute)
goto out; goto out;
...@@ -1671,7 +1671,7 @@ static void filename_compute_type(struct policydb *policydb, ...@@ -1671,7 +1671,7 @@ static void filename_compute_type(struct policydb *policydb,
ft.tclass = tclass; ft.tclass = tclass;
ft.name = objname; ft.name = objname;
datum = hashtab_search(policydb->filename_trans, &ft); datum = hashtab_search(&policydb->filename_trans, &ft);
while (datum) { while (datum) {
if (ebitmap_get_bit(&datum->stypes, stype - 1)) { if (ebitmap_get_bit(&datum->stypes, stype - 1)) {
newcontext->type = datum->otype; newcontext->type = datum->otype;
...@@ -1834,7 +1834,7 @@ static int security_compute_sid(struct selinux_state *state, ...@@ -1834,7 +1834,7 @@ static int security_compute_sid(struct selinux_state *state,
.tclass = tclass, .tclass = tclass,
}; };
rtd = hashtab_search(policydb->role_tr, &rtk); rtd = hashtab_search(&policydb->role_tr, &rtk);
if (rtd) if (rtd)
newcontext.role = rtd->new_role; newcontext.role = rtd->new_role;
} }
...@@ -2024,7 +2024,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p) ...@@ -2024,7 +2024,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p)
/* Convert the user. */ /* Convert the user. */
rc = -EINVAL; rc = -EINVAL;
usrdatum = hashtab_search(args->newp->p_users.table, usrdatum = hashtab_search(&args->newp->p_users.table,
sym_name(args->oldp, sym_name(args->oldp,
SYM_USERS, oldc->user - 1)); SYM_USERS, oldc->user - 1));
if (!usrdatum) if (!usrdatum)
...@@ -2033,7 +2033,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p) ...@@ -2033,7 +2033,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p)
/* Convert the role. */ /* Convert the role. */
rc = -EINVAL; rc = -EINVAL;
role = hashtab_search(args->newp->p_roles.table, role = hashtab_search(&args->newp->p_roles.table,
sym_name(args->oldp, SYM_ROLES, oldc->role - 1)); sym_name(args->oldp, SYM_ROLES, oldc->role - 1));
if (!role) if (!role)
goto bad; goto bad;
...@@ -2041,7 +2041,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p) ...@@ -2041,7 +2041,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p)
/* Convert the type. */ /* Convert the type. */
rc = -EINVAL; rc = -EINVAL;
typdatum = hashtab_search(args->newp->p_types.table, typdatum = hashtab_search(&args->newp->p_types.table,
sym_name(args->oldp, sym_name(args->oldp,
SYM_TYPES, oldc->type - 1)); SYM_TYPES, oldc->type - 1));
if (!typdatum) if (!typdatum)
...@@ -2623,7 +2623,7 @@ int security_get_user_sids(struct selinux_state *state, ...@@ -2623,7 +2623,7 @@ int security_get_user_sids(struct selinux_state *state,
goto out_unlock; goto out_unlock;
rc = -EINVAL; rc = -EINVAL;
user = hashtab_search(policydb->p_users.table, username); user = hashtab_search(&policydb->p_users.table, username);
if (!user) if (!user)
goto out_unlock; goto out_unlock;
...@@ -2975,7 +2975,7 @@ static int security_preserve_bools(struct selinux_state *state, ...@@ -2975,7 +2975,7 @@ static int security_preserve_bools(struct selinux_state *state,
if (rc) if (rc)
goto out; goto out;
for (i = 0; i < nbools; i++) { for (i = 0; i < nbools; i++) {
booldatum = hashtab_search(policydb->p_bools.table, bnames[i]); booldatum = hashtab_search(&policydb->p_bools.table, bnames[i]);
if (booldatum) if (booldatum)
booldatum->state = bvalues[i]; booldatum->state = bvalues[i];
} }
...@@ -3189,8 +3189,8 @@ int security_get_classes(struct selinux_state *state, ...@@ -3189,8 +3189,8 @@ int security_get_classes(struct selinux_state *state,
if (!*classes) if (!*classes)
goto out; goto out;
rc = hashtab_map(policydb->p_classes.table, get_classes_callback, rc = hashtab_map(&policydb->p_classes.table, get_classes_callback,
*classes); *classes);
if (rc) { if (rc) {
int i; int i;
for (i = 0; i < *nclasses; i++) for (i = 0; i < *nclasses; i++)
...@@ -3226,7 +3226,7 @@ int security_get_permissions(struct selinux_state *state, ...@@ -3226,7 +3226,7 @@ int security_get_permissions(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock); read_lock(&state->ss->policy_rwlock);
rc = -EINVAL; rc = -EINVAL;
match = hashtab_search(policydb->p_classes.table, class); match = hashtab_search(&policydb->p_classes.table, class);
if (!match) { if (!match) {
pr_err("SELinux: %s: unrecognized class %s\n", pr_err("SELinux: %s: unrecognized class %s\n",
__func__, class); __func__, class);
...@@ -3240,14 +3240,14 @@ int security_get_permissions(struct selinux_state *state, ...@@ -3240,14 +3240,14 @@ int security_get_permissions(struct selinux_state *state,
goto out; goto out;
if (match->comdatum) { if (match->comdatum) {
rc = hashtab_map(match->comdatum->permissions.table, rc = hashtab_map(&match->comdatum->permissions.table,
get_permissions_callback, *perms); get_permissions_callback, *perms);
if (rc) if (rc)
goto err; goto err;
} }
rc = hashtab_map(match->permissions.table, get_permissions_callback, rc = hashtab_map(&match->permissions.table, get_permissions_callback,
*perms); *perms);
if (rc) if (rc)
goto err; goto err;
...@@ -3365,7 +3365,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ...@@ -3365,7 +3365,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
case AUDIT_SUBJ_USER: case AUDIT_SUBJ_USER:
case AUDIT_OBJ_USER: case AUDIT_OBJ_USER:
rc = -EINVAL; rc = -EINVAL;
userdatum = hashtab_search(policydb->p_users.table, rulestr); userdatum = hashtab_search(&policydb->p_users.table, rulestr);
if (!userdatum) if (!userdatum)
goto out; goto out;
tmprule->au_ctxt.user = userdatum->value; tmprule->au_ctxt.user = userdatum->value;
...@@ -3373,7 +3373,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ...@@ -3373,7 +3373,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
case AUDIT_SUBJ_ROLE: case AUDIT_SUBJ_ROLE:
case AUDIT_OBJ_ROLE: case AUDIT_OBJ_ROLE:
rc = -EINVAL; rc = -EINVAL;
roledatum = hashtab_search(policydb->p_roles.table, rulestr); roledatum = hashtab_search(&policydb->p_roles.table, rulestr);
if (!roledatum) if (!roledatum)
goto out; goto out;
tmprule->au_ctxt.role = roledatum->value; tmprule->au_ctxt.role = roledatum->value;
...@@ -3381,7 +3381,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ...@@ -3381,7 +3381,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
case AUDIT_SUBJ_TYPE: case AUDIT_SUBJ_TYPE:
case AUDIT_OBJ_TYPE: case AUDIT_OBJ_TYPE:
rc = -EINVAL; rc = -EINVAL;
typedatum = hashtab_search(policydb->p_types.table, rulestr); typedatum = hashtab_search(&policydb->p_types.table, rulestr);
if (!typedatum) if (!typedatum)
goto out; goto out;
tmprule->au_ctxt.type = typedatum->value; tmprule->au_ctxt.type = typedatum->value;
......
...@@ -35,10 +35,7 @@ static int symcmp(struct hashtab *h, const void *key1, const void *key2) ...@@ -35,10 +35,7 @@ static int symcmp(struct hashtab *h, const void *key1, const void *key2)
int symtab_init(struct symtab *s, unsigned int size) int symtab_init(struct symtab *s, unsigned int size)
{ {
s->table = hashtab_create(symhash, symcmp, size);
if (!s->table)
return -ENOMEM;
s->nprim = 0; s->nprim = 0;
return 0; return hashtab_init(&s->table, symhash, symcmp, size);
} }
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "hashtab.h" #include "hashtab.h"
struct symtab { struct symtab {
struct hashtab *table; /* hash table (keyed on a string) */ struct hashtab table; /* hash table (keyed on a string) */
u32 nprim; /* number of primary names in table */ u32 nprim; /* number of primary names in table */
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment