diff mbox series

[v3,1/3] selinux: refactor avtab_node comparisons

Message ID 20231018175744.39667-2-jsatterfield.linux@gmail.com (mailing list archive)
State Superseded
Delegated to: Paul Moore
Headers show
Series selinux: avtab arrays and refactors | expand

Commit Message

Jacob Satterfield Oct. 18, 2023, 5:57 p.m. UTC
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>
---
 security/selinux/ss/avtab.c | 101 +++++++++++++++---------------------
 1 file changed, 41 insertions(+), 60 deletions(-)

Comments

Stephen Smalley Oct. 20, 2023, 1:52 p.m. UTC | #1
On Wed, Oct 18, 2023 at 1:58 PM Jacob Satterfield
<jsatterfield.linux@gmail.com> wrote:
>
> 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>

Nit: You can't retain a Reviewed-by line if you make any changes to
the previously reviewed patch.
That said, having re-reviewed this one, you can add my Reviewed-by tag
to your next one if there are no changes.

> ---
>  security/selinux/ss/avtab.c | 101 +++++++++++++++---------------------
>  1 file changed, 41 insertions(+), 60 deletions(-)
>
> diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
> index 8751a602ead2..697eb4352439 100644
> --- a/security/selinux/ss/avtab.c
> +++ b/security/selinux/ss/avtab.c
> @@ -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;
> --
> 2.41.0
>
Jacob Satterfield Oct. 20, 2023, 5:32 p.m. UTC | #2
On Fri, Oct 20, 2023 at 9:52 AM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> On Wed, Oct 18, 2023 at 1:58 PM Jacob Satterfield
> <jsatterfield.linux@gmail.com> wrote:
> >
> > 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>
>
> Nit: You can't retain a Reviewed-by line if you make any changes to
> the previously reviewed patch.
> That said, having re-reviewed this one, you can add my Reviewed-by tag
> to your next one if there are no changes.
>

My apologies. Understood for the future.

Thanks for the re-review.

> > ---
> >  security/selinux/ss/avtab.c | 101 +++++++++++++++---------------------
> >  1 file changed, 41 insertions(+), 60 deletions(-)
> >
> > diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
> > index 8751a602ead2..697eb4352439 100644
> > --- a/security/selinux/ss/avtab.c
> > +++ b/security/selinux/ss/avtab.c
> > @@ -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;
> > --
> > 2.41.0
> >
diff mbox series

Patch

diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 8751a602ead2..697eb4352439 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -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;