Commit 49e917de authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'selinux-pr-20200803' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux updates from Paul Moore:
 "Beyond the usual smattering of bug fixes, we've got three small
  improvements worth highlighting:

   - improved SELinux policy symbol table performance due to a reworking
     of the insert and search functions

   - allow reading of SELinux labels before the policy is loaded,
     allowing for some more "exotic" initramfs approaches

   - improved checking an error reporting about process
     class/permissions during SELinux policy load"

* tag 'selinux-pr-20200803' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: complete the inlining of hashtab functions
  selinux: prepare for inlining of hashtab functions
  selinux: specialize symtab insert and search functions
  selinux: Fix spelling mistakes in the comments
  selinux: fixed a checkpatch warning with the sizeof macro
  selinux: log error messages on required process class / permissions
  scripts/selinux/mdp: fix initial SID handling
  selinux: allow reading labels before policy is loaded
parents 9ecc6ea4 54b27f92
...@@ -67,8 +67,14 @@ int main(int argc, char *argv[]) ...@@ -67,8 +67,14 @@ int main(int argc, char *argv[])
initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
/* print out the sids */ /* print out the sids */
for (i = 1; i < initial_sid_to_string_len; i++) for (i = 1; i < initial_sid_to_string_len; i++) {
fprintf(fout, "sid %s\n", initial_sid_to_string[i]); const char *name = initial_sid_to_string[i];
if (name)
fprintf(fout, "sid %s\n", name);
else
fprintf(fout, "sid unused%d\n", i);
}
fprintf(fout, "\n"); fprintf(fout, "\n");
/* print out the class permissions */ /* print out the class permissions */
...@@ -126,9 +132,16 @@ int main(int argc, char *argv[]) ...@@ -126,9 +132,16 @@ int main(int argc, char *argv[])
#define OBJUSERROLETYPE "user_u:object_r:base_t" #define OBJUSERROLETYPE "user_u:object_r:base_t"
/* default sids */ /* default sids */
for (i = 1; i < initial_sid_to_string_len; i++) for (i = 1; i < initial_sid_to_string_len; i++) {
fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n", const char *name = initial_sid_to_string[i];
initial_sid_to_string[i], mls ? ":" SYSTEMLOW : "");
if (name)
fprintf(fout, "sid %s ", name);
else
fprintf(fout, "sid unused%d\n", i);
fprintf(fout, SUBJUSERROLETYPE "%s\n",
mls ? ":" SYSTEMLOW : "");
}
fprintf(fout, "\n"); fprintf(fout, "\n");
#define FS_USE(behavior, fstype) \ #define FS_USE(behavior, fstype) \
......
...@@ -3332,7 +3332,12 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void ...@@ -3332,7 +3332,12 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
char *context = NULL; char *context = NULL;
struct inode_security_struct *isec; struct inode_security_struct *isec;
if (strcmp(name, XATTR_SELINUX_SUFFIX)) /*
* If we're not initialized yet, then we can't validate contexts, so
* just let vfs_getxattr fall back to using the on-disk xattr.
*/
if (!selinux_initialized(&selinux_state) ||
strcmp(name, XATTR_SELINUX_SUFFIX))
return -EOPNOTSUPP; return -EOPNOTSUPP;
/* /*
......
...@@ -124,7 +124,7 @@ static void sel_netif_destroy(struct sel_netif *netif) ...@@ -124,7 +124,7 @@ static void sel_netif_destroy(struct sel_netif *netif)
* @sid: interface SID * @sid: interface SID
* *
* Description: * Description:
* This function determines the SID of a network interface by quering the * This function determines the SID of a network interface by querying the
* security policy. The result is added to the network interface table to * security policy. The result is added to the network interface table to
* speedup future queries. Returns zero on success, negative values on * speedup future queries. Returns zero on success, negative values on
* failure. * failure.
......
...@@ -181,7 +181,7 @@ static void sel_netnode_insert(struct sel_netnode *node) ...@@ -181,7 +181,7 @@ static void sel_netnode_insert(struct sel_netnode *node)
* @sid: node SID * @sid: node SID
* *
* Description: * Description:
* This function determines the SID of a network address by quering the * This function determines the SID of a network address by querying the
* security policy. The result is added to the network address table to * security policy. The result is added to the network address table to
* speedup future queries. Returns zero on success, negative values on * speedup future queries. Returns zero on success, negative values on
* failure. * failure.
......
...@@ -130,7 +130,7 @@ static void sel_netport_insert(struct sel_netport *port) ...@@ -130,7 +130,7 @@ static void sel_netport_insert(struct sel_netport *port)
* @sid: port SID * @sid: port SID
* *
* Description: * Description:
* This function determines the SID of a network port by quering the security * This function determines the SID of a network port by querying the security
* policy. The result is added to the network port table to speedup future * policy. The result is added to the network port table to speedup future
* queries. Returns zero on success, negative values on failure. * queries. Returns zero on success, negative values on failure.
* *
......
...@@ -203,7 +203,7 @@ static int bool_isvalid(struct cond_bool_datum *b) ...@@ -203,7 +203,7 @@ static int bool_isvalid(struct cond_bool_datum *b)
return 1; return 1;
} }
int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp) int cond_read_bool(struct policydb *p, struct symtab *s, void *fp)
{ {
char *key = NULL; char *key = NULL;
struct cond_bool_datum *booldatum; struct cond_bool_datum *booldatum;
...@@ -215,7 +215,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp) ...@@ -215,7 +215,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
if (!booldatum) if (!booldatum)
return -ENOMEM; return -ENOMEM;
rc = next_entry(buf, fp, sizeof buf); rc = next_entry(buf, fp, sizeof(buf));
if (rc) if (rc)
goto err; goto err;
...@@ -238,7 +238,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp) ...@@ -238,7 +238,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
if (rc) if (rc)
goto err; goto err;
key[len] = '\0'; key[len] = '\0';
rc = hashtab_insert(h, key, booldatum); rc = symtab_insert(s, key, booldatum);
if (rc) if (rc)
goto err; goto err;
...@@ -416,7 +416,7 @@ int cond_read_list(struct policydb *p, void *fp) ...@@ -416,7 +416,7 @@ int cond_read_list(struct policydb *p, void *fp)
u32 i, len; u32 i, len;
int rc; int rc;
rc = next_entry(buf, fp, sizeof buf); rc = next_entry(buf, fp, sizeof(buf));
if (rc) if (rc)
return rc; return rc;
......
...@@ -69,7 +69,7 @@ int cond_destroy_bool(void *key, void *datum, void *p); ...@@ -69,7 +69,7 @@ int cond_destroy_bool(void *key, void *datum, void *p);
int cond_index_bool(void *key, void *datum, void *datap); int cond_index_bool(void *key, void *datum, void *datap);
int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp); int cond_read_bool(struct policydb *p, struct symtab *s, void *fp);
int cond_read_list(struct policydb *p, void *fp); int cond_read_list(struct policydb *p, void *fp);
int cond_write_bool(void *key, void *datum, void *ptr); int cond_write_bool(void *key, void *datum, void *ptr);
int cond_write_list(struct policydb *p, void *fp); int cond_write_list(struct policydb *p, void *fp);
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/sched.h>
#include "hashtab.h" #include "hashtab.h"
static struct kmem_cache *hashtab_node_cachep; static struct kmem_cache *hashtab_node_cachep;
...@@ -29,16 +28,10 @@ static u32 hashtab_compute_size(u32 nel) ...@@ -29,16 +28,10 @@ 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);
} }
int hashtab_init(struct hashtab *h, int hashtab_init(struct hashtab *h, u32 nel_hint)
u32 (*hash_value)(struct hashtab *h, const void *key),
int (*keycmp)(struct hashtab *h, const void *key1,
const void *key2),
u32 nel_hint)
{ {
h->size = hashtab_compute_size(nel_hint); h->size = hashtab_compute_size(nel_hint);
h->nel = 0; h->nel = 0;
h->hash_value = hash_value;
h->keycmp = keycmp;
if (!h->size) if (!h->size)
return 0; return 0;
...@@ -46,63 +39,23 @@ int hashtab_init(struct hashtab *h, ...@@ -46,63 +39,23 @@ int hashtab_init(struct hashtab *h,
return h->htable ? 0 : -ENOMEM; return h->htable ? 0 : -ENOMEM;
} }
int hashtab_insert(struct hashtab *h, void *key, void *datum) int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
void *key, void *datum)
{ {
u32 hvalue; struct hashtab_node *newnode;
struct hashtab_node *prev, *cur, *newnode;
cond_resched();
if (!h->size || h->nel == HASHTAB_MAX_NODES)
return -EINVAL;
hvalue = h->hash_value(h, key);
prev = NULL;
cur = h->htable[hvalue];
while (cur && h->keycmp(h, key, cur->key) > 0) {
prev = cur;
cur = cur->next;
}
if (cur && (h->keycmp(h, key, cur->key) == 0))
return -EEXIST;
newnode = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL); newnode = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL);
if (!newnode) if (!newnode)
return -ENOMEM; return -ENOMEM;
newnode->key = key; newnode->key = key;
newnode->datum = datum; newnode->datum = datum;
if (prev) { newnode->next = *dst;
newnode->next = prev->next; *dst = newnode;
prev->next = newnode;
} else {
newnode->next = h->htable[hvalue];
h->htable[hvalue] = newnode;
}
h->nel++; h->nel++;
return 0; return 0;
} }
void *hashtab_search(struct hashtab *h, const void *key)
{
u32 hvalue;
struct hashtab_node *cur;
if (!h->size)
return NULL;
hvalue = h->hash_value(h, key);
cur = h->htable[hvalue];
while (cur && h->keycmp(h, key, cur->key) > 0)
cur = cur->next;
if (!cur || (h->keycmp(h, key, cur->key) != 0))
return NULL;
return cur->datum;
}
void hashtab_destroy(struct hashtab *h) void hashtab_destroy(struct hashtab *h)
{ {
u32 i; u32 i;
......
...@@ -11,7 +11,17 @@ ...@@ -11,7 +11,17 @@
#ifndef _SS_HASHTAB_H_ #ifndef _SS_HASHTAB_H_
#define _SS_HASHTAB_H_ #define _SS_HASHTAB_H_
#define HASHTAB_MAX_NODES 0xffffffff #include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
#define HASHTAB_MAX_NODES U32_MAX
struct hashtab_key_params {
u32 (*hash)(const void *key); /* hash function */
int (*cmp)(const void *key1, const void *key2);
/* key comparison function */
};
struct hashtab_node { struct hashtab_node {
void *key; void *key;
...@@ -23,10 +33,6 @@ struct hashtab { ...@@ -23,10 +33,6 @@ struct hashtab {
struct hashtab_node **htable; /* hash table */ struct hashtab_node **htable; /* hash table */
u32 size; /* number of slots in hash table */ u32 size; /* number of slots in hash table */
u32 nel; /* number of elements in hash table */ u32 nel; /* number of elements in hash table */
u32 (*hash_value)(struct hashtab *h, const void *key);
/* hash function */
int (*keycmp)(struct hashtab *h, const void *key1, const void *key2);
/* key comparison function */
}; };
struct hashtab_info { struct hashtab_info {
...@@ -39,11 +45,10 @@ struct hashtab_info { ...@@ -39,11 +45,10 @@ struct hashtab_info {
* *
* Returns -ENOMEM if insufficient space is available or 0 otherwise. * Returns -ENOMEM if insufficient space is available or 0 otherwise.
*/ */
int hashtab_init(struct hashtab *h, int hashtab_init(struct hashtab *h, u32 nel_hint);
u32 (*hash_value)(struct hashtab *h, const void *key),
int (*keycmp)(struct hashtab *h, const void *key1, int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
const void *key2), void *key, void *datum);
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.
...@@ -53,7 +58,34 @@ int hashtab_init(struct hashtab *h, ...@@ -53,7 +58,34 @@ int hashtab_init(struct hashtab *h,
* -EINVAL for general errors or * -EINVAL for general errors or
0 otherwise. 0 otherwise.
*/ */
int hashtab_insert(struct hashtab *h, void *k, void *d); static inline int hashtab_insert(struct hashtab *h, void *key, void *datum,
struct hashtab_key_params key_params)
{
u32 hvalue;
struct hashtab_node *prev, *cur;
cond_resched();
if (!h->size || h->nel == HASHTAB_MAX_NODES)
return -EINVAL;
hvalue = key_params.hash(key) & (h->size - 1);
prev = NULL;
cur = h->htable[hvalue];
while (cur) {
int cmp = key_params.cmp(key, cur->key);
if (cmp == 0)
return -EEXIST;
if (cmp < 0)
break;
prev = cur;
cur = cur->next;
}
return __hashtab_insert(h, prev ? &prev->next : &h->htable[hvalue],
key, datum);
}
/* /*
* Searches for the entry with the specified key in the hash table. * Searches for the entry with the specified key in the hash table.
...@@ -61,7 +93,28 @@ int hashtab_insert(struct hashtab *h, void *k, void *d); ...@@ -61,7 +93,28 @@ int hashtab_insert(struct hashtab *h, void *k, void *d);
* Returns NULL if no entry has the specified key or * Returns NULL if no entry has the specified key or
* the datum of the entry otherwise. * the datum of the entry otherwise.
*/ */
void *hashtab_search(struct hashtab *h, const void *k); static inline void *hashtab_search(struct hashtab *h, const void *key,
struct hashtab_key_params key_params)
{
u32 hvalue;
struct hashtab_node *cur;
if (!h->size)
return NULL;
hvalue = key_params.hash(key) & (h->size - 1);
cur = h->htable[hvalue];
while (cur) {
int cmp = key_params.cmp(key, cur->key);
if (cmp == 0)
return cur->datum;
if (cmp < 0)
break;
cur = cur->next;
}
return NULL;
}
/* /*
* Destroys the specified hash table. * Destroys the specified hash table.
......
...@@ -165,8 +165,8 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l) ...@@ -165,8 +165,8 @@ 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 = symtab_search(&p->p_levels,
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 = symtab_search(&pol->p_levels, 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 = symtab_search(&pol->p_cats, 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 = symtab_search(&pol->p_cats, rngptr);
if (!rngdatum) if (!rngdatum)
return -EINVAL; return -EINVAL;
...@@ -458,9 +458,10 @@ int mls_convert_context(struct policydb *oldp, ...@@ -458,9 +458,10 @@ 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, char *name = sym_name(oldp, SYM_LEVELS,
sym_name(oldp, SYM_LEVELS, oldc->range.level[l].sens - 1);
oldc->range.level[l].sens - 1));
levdatum = symtab_search(&newp->p_levels, name);
if (!levdatum) if (!levdatum)
return -EINVAL; return -EINVAL;
...@@ -470,8 +471,8 @@ int mls_convert_context(struct policydb *oldp, ...@@ -470,8 +471,8 @@ int mls_convert_context(struct policydb *oldp,
node, i) { node, i) {
int rc; int rc;
catdatum = hashtab_search(&newp->p_cats.table, catdatum = symtab_search(&newp->p_cats,
sym_name(oldp, SYM_CATS, i)); sym_name(oldp, SYM_CATS, i));
if (!catdatum) if (!catdatum)
return -EINVAL; return -EINVAL;
rc = ebitmap_set_bit(&newc->range.level[l].cat, rc = ebitmap_set_bit(&newc->range.level[l].cat,
...@@ -506,7 +507,7 @@ int mls_compute_sid(struct policydb *p, ...@@ -506,7 +507,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 = policydb_rangetr_search(p, &rtr);
if (r) if (r)
return mls_range_set(newcontext, r); return mls_range_set(newcontext, r);
......
This diff is collapsed.
...@@ -324,6 +324,15 @@ extern int policydb_role_isvalid(struct policydb *p, unsigned int role); ...@@ -324,6 +324,15 @@ extern int policydb_role_isvalid(struct policydb *p, unsigned int role);
extern int policydb_read(struct policydb *p, void *fp); extern int policydb_read(struct policydb *p, void *fp);
extern int policydb_write(struct policydb *p, void *fp); extern int policydb_write(struct policydb *p, void *fp);
extern struct filename_trans_datum *policydb_filenametr_search(
struct policydb *p, struct filename_trans_key *key);
extern struct mls_range *policydb_rangetr_search(
struct policydb *p, struct range_trans *key);
extern struct role_trans_datum *policydb_roletr_search(
struct policydb *p, struct role_trans_key *key);
#define POLICYDB_CONFIG_MLS 1 #define POLICYDB_CONFIG_MLS 1
/* the config flags related to unknown classes/perms are bits 2 and 3 */ /* the config flags related to unknown classes/perms are bits 2 and 3 */
......
...@@ -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 = symtab_search(&pol->p_users, 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 = symtab_search(&pol->p_roles, 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 = symtab_search(&pol->p_types, 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 = policydb_filenametr_search(policydb, &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 = policydb_roletr_search(policydb, &rtk);
if (rtd) if (rtd)
newcontext.role = rtd->new_role; newcontext.role = rtd->new_role;
} }
...@@ -2024,26 +2024,26 @@ static int convert_context(struct context *oldc, struct context *newc, void *p) ...@@ -2024,26 +2024,26 @@ 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 = symtab_search(&args->newp->p_users,
sym_name(args->oldp, sym_name(args->oldp,
SYM_USERS, oldc->user - 1)); SYM_USERS, oldc->user - 1));
if (!usrdatum) if (!usrdatum)
goto bad; goto bad;
newc->user = usrdatum->value; newc->user = usrdatum->value;
/* Convert the role. */ /* Convert the role. */
rc = -EINVAL; rc = -EINVAL;
role = hashtab_search(&args->newp->p_roles.table, role = symtab_search(&args->newp->p_roles,
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;
newc->role = role->value; newc->role = role->value;
/* Convert the type. */ /* Convert the type. */
rc = -EINVAL; rc = -EINVAL;
typdatum = hashtab_search(&args->newp->p_types.table, typdatum = symtab_search(&args->newp->p_types,
sym_name(args->oldp, sym_name(args->oldp,
SYM_TYPES, oldc->type - 1)); SYM_TYPES, oldc->type - 1));
if (!typdatum) if (!typdatum)
goto bad; goto bad;
newc->type = typdatum->value; newc->type = typdatum->value;
...@@ -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 = symtab_search(&policydb->p_users, username);
if (!user) if (!user)
goto out_unlock; goto out_unlock;
...@@ -2979,7 +2979,7 @@ static int security_preserve_bools(struct selinux_state *state, ...@@ -2979,7 +2979,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 = symtab_search(&policydb->p_bools, bnames[i]);
if (booldatum) if (booldatum)
booldatum->state = bvalues[i]; booldatum->state = bvalues[i];
} }
...@@ -3230,7 +3230,7 @@ int security_get_permissions(struct selinux_state *state, ...@@ -3230,7 +3230,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 = symtab_search(&policydb->p_classes, 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);
...@@ -3369,7 +3369,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ...@@ -3369,7 +3369,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 = symtab_search(&policydb->p_users, rulestr);
if (!userdatum) if (!userdatum)
goto out; goto out;
tmprule->au_ctxt.user = userdatum->value; tmprule->au_ctxt.user = userdatum->value;
...@@ -3377,7 +3377,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ...@@ -3377,7 +3377,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 = symtab_search(&policydb->p_roles, rulestr);
if (!roledatum) if (!roledatum)
goto out; goto out;
tmprule->au_ctxt.role = roledatum->value; tmprule->au_ctxt.role = roledatum->value;
...@@ -3385,7 +3385,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ...@@ -3385,7 +3385,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 = symtab_search(&policydb->p_types, rulestr);
if (!typedatum) if (!typedatum)
goto out; goto out;
tmprule->au_ctxt.type = typedatum->value; tmprule->au_ctxt.type = typedatum->value;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include "symtab.h" #include "symtab.h"
static unsigned int symhash(struct hashtab *h, const void *key) static unsigned int symhash(const void *key)
{ {
const char *p, *keyp; const char *p, *keyp;
unsigned int size; unsigned int size;
...@@ -20,10 +20,10 @@ static unsigned int symhash(struct hashtab *h, const void *key) ...@@ -20,10 +20,10 @@ static unsigned int symhash(struct hashtab *h, const void *key)
size = strlen(keyp); size = strlen(keyp);
for (p = keyp; (p - keyp) < size; p++) for (p = keyp; (p - keyp) < size; p++)
val = (val << 4 | (val >> (8*sizeof(unsigned int)-4))) ^ (*p); val = (val << 4 | (val >> (8*sizeof(unsigned int)-4))) ^ (*p);
return val & (h->size - 1); return val;
} }
static int symcmp(struct hashtab *h, const void *key1, const void *key2) static int symcmp(const void *key1, const void *key2)
{ {
const char *keyp1, *keyp2; const char *keyp1, *keyp2;
...@@ -32,10 +32,23 @@ static int symcmp(struct hashtab *h, const void *key1, const void *key2) ...@@ -32,10 +32,23 @@ static int symcmp(struct hashtab *h, const void *key1, const void *key2)
return strcmp(keyp1, keyp2); return strcmp(keyp1, keyp2);
} }
static const struct hashtab_key_params symtab_key_params = {
.hash = symhash,
.cmp = symcmp,
};
int symtab_init(struct symtab *s, unsigned int size) int symtab_init(struct symtab *s, unsigned int size)
{ {
s->nprim = 0; s->nprim = 0;
return hashtab_init(&s->table, symhash, symcmp, size); return hashtab_init(&s->table, size);
} }
int symtab_insert(struct symtab *s, char *name, void *datum)
{
return hashtab_insert(&s->table, name, datum, symtab_key_params);
}
void *symtab_search(struct symtab *s, const char *name)
{
return hashtab_search(&s->table, name, symtab_key_params);
}
...@@ -19,6 +19,9 @@ struct symtab { ...@@ -19,6 +19,9 @@ struct symtab {
int symtab_init(struct symtab *s, unsigned int size); int symtab_init(struct symtab *s, unsigned int size);
int symtab_insert(struct symtab *s, char *name, void *datum);
void *symtab_search(struct symtab *s, const char *name);
#endif /* _SS_SYMTAB_H_ */ #endif /* _SS_SYMTAB_H_ */
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