mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-04 04:04:19 +00:00
selinux: refactor avtab_node comparisons
In four separate functions within avtab, the same comparison logic is used. The only difference is how the result is handled or whether there is a unique specifier value to be checked for or used. Extracting this functionality into the avtab_node_cmp() function unifies the comparison logic between searching and insertion and gets rid of duplicative code so that the implementation is easier to maintain. Signed-off-by: Jacob Satterfield <jsatterfield.linux@gmail.com> Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
parent
f5364ecfd8
commit
1712ed6215
@ -96,12 +96,34 @@ avtab_insert_node(struct avtab *h, struct avtab_node **dst,
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static int avtab_node_cmp(const struct avtab_key *key1,
|
||||
const struct avtab_key *key2)
|
||||
{
|
||||
u16 specified = key1->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
|
||||
|
||||
if (key1->source_type == key2->source_type &&
|
||||
key1->target_type == key2->target_type &&
|
||||
key1->target_class == key2->target_class &&
|
||||
(specified & key2->specified))
|
||||
return 0;
|
||||
if (key1->source_type < key2->source_type)
|
||||
return -1;
|
||||
if (key1->source_type == key2->source_type &&
|
||||
key1->target_type < key2->target_type)
|
||||
return -1;
|
||||
if (key1->source_type == key2->source_type &&
|
||||
key1->target_type == key2->target_type &&
|
||||
key1->target_class < key2->target_class)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int avtab_insert(struct avtab *h, const struct avtab_key *key,
|
||||
const struct avtab_datum *datum)
|
||||
{
|
||||
u32 hvalue;
|
||||
struct avtab_node *prev, *cur, *newnode;
|
||||
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
|
||||
int cmp;
|
||||
|
||||
if (!h || !h->nslot || h->nel == U32_MAX)
|
||||
return -EINVAL;
|
||||
@ -110,23 +132,11 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key,
|
||||
for (prev = NULL, cur = h->htable[hvalue];
|
||||
cur;
|
||||
prev = cur, cur = cur->next) {
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type == cur->key.target_type &&
|
||||
key->target_class == cur->key.target_class &&
|
||||
(specified & cur->key.specified)) {
|
||||
/* extended perms may not be unique */
|
||||
if (specified & AVTAB_XPERMS)
|
||||
break;
|
||||
cmp = avtab_node_cmp(key, &cur->key);
|
||||
/* extended perms may not be unique */
|
||||
if (cmp == 0 && !(key->specified & AVTAB_XPERMS))
|
||||
return -EEXIST;
|
||||
}
|
||||
if (key->source_type < cur->key.source_type)
|
||||
break;
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type < cur->key.target_type)
|
||||
break;
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type == cur->key.target_type &&
|
||||
key->target_class < cur->key.target_class)
|
||||
if (cmp <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -148,7 +158,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
|
||||
{
|
||||
u32 hvalue;
|
||||
struct avtab_node *prev, *cur;
|
||||
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
|
||||
int cmp;
|
||||
|
||||
if (!h || !h->nslot || h->nel == U32_MAX)
|
||||
return NULL;
|
||||
@ -156,19 +166,8 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
|
||||
for (prev = NULL, cur = h->htable[hvalue];
|
||||
cur;
|
||||
prev = cur, cur = cur->next) {
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type == cur->key.target_type &&
|
||||
key->target_class == cur->key.target_class &&
|
||||
(specified & cur->key.specified))
|
||||
break;
|
||||
if (key->source_type < cur->key.source_type)
|
||||
break;
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type < cur->key.target_type)
|
||||
break;
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type == cur->key.target_type &&
|
||||
key->target_class < cur->key.target_class)
|
||||
cmp = avtab_node_cmp(key, &cur->key);
|
||||
if (cmp <= 0)
|
||||
break;
|
||||
}
|
||||
return avtab_insert_node(h, prev ? &prev->next : &h->htable[hvalue],
|
||||
@ -183,7 +182,7 @@ struct avtab_node *avtab_search_node(struct avtab *h,
|
||||
{
|
||||
u32 hvalue;
|
||||
struct avtab_node *cur;
|
||||
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
|
||||
int cmp;
|
||||
|
||||
if (!h || !h->nslot)
|
||||
return NULL;
|
||||
@ -191,20 +190,10 @@ struct avtab_node *avtab_search_node(struct avtab *h,
|
||||
hvalue = avtab_hash(key, h->mask);
|
||||
for (cur = h->htable[hvalue]; cur;
|
||||
cur = cur->next) {
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type == cur->key.target_type &&
|
||||
key->target_class == cur->key.target_class &&
|
||||
(specified & cur->key.specified))
|
||||
cmp = avtab_node_cmp(key, &cur->key);
|
||||
if (cmp == 0)
|
||||
return cur;
|
||||
|
||||
if (key->source_type < cur->key.source_type)
|
||||
break;
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type < cur->key.target_type)
|
||||
break;
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type == cur->key.target_type &&
|
||||
key->target_class < cur->key.target_class)
|
||||
if (cmp < 0)
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
@ -213,27 +202,19 @@ struct avtab_node *avtab_search_node(struct avtab *h,
|
||||
struct avtab_node*
|
||||
avtab_search_node_next(struct avtab_node *node, u16 specified)
|
||||
{
|
||||
struct avtab_key tmp_key;
|
||||
struct avtab_node *cur;
|
||||
int cmp;
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
specified &= ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
|
||||
tmp_key = node->key;
|
||||
tmp_key.specified = specified;
|
||||
for (cur = node->next; cur; cur = cur->next) {
|
||||
if (node->key.source_type == cur->key.source_type &&
|
||||
node->key.target_type == cur->key.target_type &&
|
||||
node->key.target_class == cur->key.target_class &&
|
||||
(specified & cur->key.specified))
|
||||
cmp = avtab_node_cmp(&tmp_key, &cur->key);
|
||||
if (cmp == 0)
|
||||
return cur;
|
||||
|
||||
if (node->key.source_type < cur->key.source_type)
|
||||
break;
|
||||
if (node->key.source_type == cur->key.source_type &&
|
||||
node->key.target_type < cur->key.target_type)
|
||||
break;
|
||||
if (node->key.source_type == cur->key.source_type &&
|
||||
node->key.target_type == cur->key.target_type &&
|
||||
node->key.target_class < cur->key.target_class)
|
||||
if (cmp < 0)
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user