]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selinux: avoid nontransitive comparison
authorChristian Göttsche <cgzones@googlemail.com>
Sun, 11 May 2025 17:30:01 +0000 (19:30 +0200)
committerPaul Moore <paul@paul-moore.com>
Wed, 6 May 2026 23:43:16 +0000 (19:43 -0400)
Avoid using nontransitive comparison to prevent unexpected sorting
results due to (well-defined) overflows.
See https://www.qualys.com/2024/01/30/qsort.txt for a related issue in
glibc's qsort(3).

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: use the cmp_int() macro from sort.h]
Signed-off-by: Paul Moore <paul@paul-moore.com>
security/selinux/ss/policydb.c

index 738fd47f33e688934085563c1ce167bb73c3492a..250402a03758d723c7aeb4b570efb62eddd25afb 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/audit.h>
+#include <linux/sort.h>
 #include "security.h"
 
 #include "policydb.h"
@@ -429,11 +430,11 @@ static int filenametr_cmp(const void *k1, const void *k2)
        const struct filename_trans_key *ft2 = k2;
        int v;
 
-       v = ft1->ttype - ft2->ttype;
+       v = cmp_int(ft1->ttype, ft2->ttype);
        if (v)
                return v;
 
-       v = ft1->tclass - ft2->tclass;
+       v = cmp_int(ft1->tclass, ft2->tclass);
        if (v)
                return v;
 
@@ -464,15 +465,15 @@ static int rangetr_cmp(const void *k1, const void *k2)
        const struct range_trans *key1 = k1, *key2 = k2;
        int v;
 
-       v = key1->source_type - key2->source_type;
+       v = cmp_int(key1->source_type, key2->source_type);
        if (v)
                return v;
 
-       v = key1->target_type - key2->target_type;
+       v = cmp_int(key1->target_type, key2->target_type);
        if (v)
                return v;
 
-       v = key1->target_class - key2->target_class;
+       v = cmp_int(key1->target_class, key2->target_class);
 
        return v;
 }
@@ -501,15 +502,15 @@ static int role_trans_cmp(const void *k1, const void *k2)
        const struct role_trans_key *key1 = k1, *key2 = k2;
        int v;
 
-       v = key1->role - key2->role;
+       v = cmp_int(key1->role, key2->role);
        if (v)
                return v;
 
-       v = key1->type - key2->type;
+       v = cmp_int(key1->type, key2->type);
        if (v)
                return v;
 
-       return key1->tclass - key2->tclass;
+       return cmp_int(key1->tclass, key2->tclass);
 }
 
 static const struct hashtab_key_params roletr_key_params = {