selinux: move context hashing under sidtab
Now that context hash computation no longer depends on policydb, we can simplify things by moving the context hashing completely under sidtab. The hash is still cached in sidtab entries, but not for the in-flight context structures. Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:

committed by
Paul Moore

parent
5007728980
commit
225621c934
@@ -54,14 +54,15 @@ int sidtab_init(struct sidtab *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 context_to_sid(struct sidtab *s, struct context *context)
|
||||
static u32 context_to_sid(struct sidtab *s, struct context *context, u32 hash)
|
||||
{
|
||||
struct sidtab_entry *entry;
|
||||
u32 sid = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
hash_for_each_possible_rcu(s->context_to_sid, entry, list,
|
||||
context->hash) {
|
||||
hash_for_each_possible_rcu(s->context_to_sid, entry, list, hash) {
|
||||
if (entry->hash != hash)
|
||||
continue;
|
||||
if (context_cmp(&entry->context, context)) {
|
||||
sid = entry->sid;
|
||||
break;
|
||||
@@ -74,6 +75,7 @@ static u32 context_to_sid(struct sidtab *s, struct context *context)
|
||||
int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context)
|
||||
{
|
||||
struct sidtab_isid_entry *isid;
|
||||
u32 hash;
|
||||
int rc;
|
||||
|
||||
if (sid == 0 || sid > SECINITSID_NUM)
|
||||
@@ -90,15 +92,18 @@ int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context)
|
||||
#endif
|
||||
isid->set = 1;
|
||||
|
||||
hash = context_compute_hash(context);
|
||||
|
||||
/*
|
||||
* Multiple initial sids may map to the same context. Check that this
|
||||
* context is not already represented in the context_to_sid hashtable
|
||||
* to avoid duplicate entries and long linked lists upon hash
|
||||
* collision.
|
||||
*/
|
||||
if (!context_to_sid(s, context)) {
|
||||
if (!context_to_sid(s, context, hash)) {
|
||||
isid->entry.sid = sid;
|
||||
hash_add(s->context_to_sid, &isid->entry.list, context->hash);
|
||||
isid->entry.hash = hash;
|
||||
hash_add(s->context_to_sid, &isid->entry.list, hash);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -259,12 +264,12 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
|
||||
u32 *sid)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 count;
|
||||
u32 count, hash = context_compute_hash(context);
|
||||
struct sidtab_convert_params *convert;
|
||||
struct sidtab_entry *dst, *dst_convert;
|
||||
int rc;
|
||||
|
||||
*sid = context_to_sid(s, context);
|
||||
*sid = context_to_sid(s, context, hash);
|
||||
if (*sid)
|
||||
return 0;
|
||||
|
||||
@@ -272,7 +277,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
|
||||
spin_lock_irqsave(&s->lock, flags);
|
||||
|
||||
rc = 0;
|
||||
*sid = context_to_sid(s, context);
|
||||
*sid = context_to_sid(s, context, hash);
|
||||
if (*sid)
|
||||
goto out_unlock;
|
||||
|
||||
@@ -291,6 +296,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
|
||||
goto out_unlock;
|
||||
|
||||
dst->sid = index_to_sid(count);
|
||||
dst->hash = hash;
|
||||
|
||||
rc = context_cpy(&dst->context, context);
|
||||
if (rc)
|
||||
@@ -315,10 +321,11 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
|
||||
goto out_unlock;
|
||||
}
|
||||
dst_convert->sid = index_to_sid(count);
|
||||
dst_convert->hash = context_compute_hash(&dst_convert->context);
|
||||
convert->target->count = count + 1;
|
||||
|
||||
hash_add_rcu(convert->target->context_to_sid,
|
||||
&dst_convert->list, dst_convert->context.hash);
|
||||
&dst_convert->list, dst_convert->hash);
|
||||
}
|
||||
|
||||
if (context->len)
|
||||
@@ -329,7 +336,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
|
||||
|
||||
/* write entries before updating count */
|
||||
smp_store_release(&s->count, count + 1);
|
||||
hash_add_rcu(s->context_to_sid, &dst->list, dst->context.hash);
|
||||
hash_add_rcu(s->context_to_sid, &dst->list, dst->hash);
|
||||
|
||||
rc = 0;
|
||||
out_unlock:
|
||||
@@ -345,10 +352,9 @@ static void sidtab_convert_hashtable(struct sidtab *s, u32 count)
|
||||
for (i = 0; i < count; i++) {
|
||||
entry = sidtab_do_lookup(s, i, 0);
|
||||
entry->sid = index_to_sid(i);
|
||||
entry->hash = context_compute_hash(&entry->context);
|
||||
|
||||
hash_add_rcu(s->context_to_sid, &entry->list,
|
||||
entry->context.hash);
|
||||
|
||||
hash_add_rcu(s->context_to_sid, &entry->list, entry->hash);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user