Skip to content

Commit f5fc9e4

Browse files
committed
Merge tag 'selinux-pr-20231030' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: - improve the SELinux debugging configuration controls in Kconfig - print additional information about the hash table chain lengths when when printing SELinux debugging information - simplify the SELinux access vector hash table calcaulations - use a better hashing function for the SELinux role tansition hash table - improve SELinux load policy time through the use of optimized functions for calculating the number of bits set in a field - addition of a __counted_by annotation - simplify the avtab_inert_node() function through a simplified prototype * tag 'selinux-pr-20231030' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: simplify avtab_insert_node() prototype selinux: hweight optimization in avtab_read_item selinux: improve role transition hashing selinux: simplify avtab slot calculation selinux: improve debug configuration selinux: print sum of chain lengths^2 for hash tables selinux: Annotate struct sidtab_str_cache with __counted_by
2 parents b9886c9 + 19c1c99 commit f5fc9e4

7 files changed

Lines changed: 33 additions & 30 deletions

File tree

security/selinux/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,13 @@ config SECURITY_SELINUX_DEBUG
7777
This enables debugging code designed to help SELinux kernel
7878
developers, unless you know what this does in the kernel code you
7979
should leave this disabled.
80+
81+
To fine control the messages to be printed enable
82+
CONFIG_DYNAMIC_DEBUG and see
83+
Documentation/admin-guide/dynamic-debug-howto.rst for additional
84+
information.
85+
86+
Example usage:
87+
88+
echo -n 'file "security/selinux/*" +p' > \
89+
/proc/dynamic_debug/control

security/selinux/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ obj-$(CONFIG_SECURITY_SELINUX) := selinux.o
1212

1313
ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
1414

15+
ccflags-$(CONFIG_SECURITY_SELINUX_DEBUG) += -DDEBUG
16+
1517
selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
1618
netnode.o netport.o status.o \
1719
ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \

security/selinux/ss/avtab.c

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* Tuned number of hash slots for avtab to reduce memory usage
1818
*/
1919

20+
#include <linux/bitops.h>
2021
#include <linux/kernel.h>
2122
#include <linux/slab.h>
2223
#include <linux/errno.h>
@@ -66,8 +67,7 @@ static inline u32 avtab_hash(const struct avtab_key *keyp, u32 mask)
6667
}
6768

6869
static struct avtab_node*
69-
avtab_insert_node(struct avtab *h, u32 hvalue,
70-
struct avtab_node *prev,
70+
avtab_insert_node(struct avtab *h, struct avtab_node **dst,
7171
const struct avtab_key *key, const struct avtab_datum *datum)
7272
{
7373
struct avtab_node *newnode;
@@ -89,15 +89,8 @@ avtab_insert_node(struct avtab *h, u32 hvalue,
8989
newnode->datum.u.data = datum->u.data;
9090
}
9191

92-
if (prev) {
93-
newnode->next = prev->next;
94-
prev->next = newnode;
95-
} else {
96-
struct avtab_node **n = &h->htable[hvalue];
97-
98-
newnode->next = *n;
99-
*n = newnode;
100-
}
92+
newnode->next = *dst;
93+
*dst = newnode;
10194

10295
h->nel++;
10396
return newnode;
@@ -137,7 +130,8 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key,
137130
break;
138131
}
139132

140-
newnode = avtab_insert_node(h, hvalue, prev, key, datum);
133+
newnode = avtab_insert_node(h, prev ? &prev->next : &h->htable[hvalue],
134+
key, datum);
141135
if (!newnode)
142136
return -ENOMEM;
143137

@@ -177,7 +171,8 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
177171
key->target_class < cur->key.target_class)
178172
break;
179173
}
180-
return avtab_insert_node(h, hvalue, prev, key, datum);
174+
return avtab_insert_node(h, prev ? &prev->next : &h->htable[hvalue],
175+
key, datum);
181176
}
182177

183178
/* This search function returns a node pointer, and can be used in
@@ -298,13 +293,7 @@ int avtab_alloc(struct avtab *h, u32 nrules)
298293
u32 nslot = 0;
299294

300295
if (nrules != 0) {
301-
u32 shift = 1;
302-
u32 work = nrules >> 3;
303-
while (work) {
304-
work >>= 1;
305-
shift++;
306-
}
307-
nslot = 1 << shift;
296+
nslot = nrules > 3 ? rounddown_pow_of_two(nrules / 2) : 2;
308297
if (nslot > MAX_AVTAB_HASH_BUCKETS)
309298
nslot = MAX_AVTAB_HASH_BUCKETS;
310299

@@ -349,7 +338,7 @@ void avtab_hash_eval(struct avtab *h, const char *tag)
349338
}
350339

351340
pr_debug("SELinux: %s: %d entries and %d/%d buckets used, "
352-
"longest chain length %d sum of chain length^2 %llu\n",
341+
"longest chain length %d, sum of chain length^2 %llu\n",
353342
tag, h->nel, slots_used, h->nslot, max_chain_len,
354343
chain2_len_sum);
355344
}
@@ -477,11 +466,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
477466
return -EINVAL;
478467
}
479468

480-
set = 0;
481-
for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
482-
if (key.specified & spec_order[i])
483-
set++;
484-
}
469+
set = hweight16(key.specified & (AVTAB_XPERMS | AVTAB_TYPE | AVTAB_AV));
485470
if (!set || set > 1) {
486471
pr_err("SELinux: avtab: more than one specifier\n");
487472
return -EINVAL;

security/selinux/ss/hashtab.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,12 @@ int hashtab_map(struct hashtab *h,
107107
void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
108108
{
109109
u32 i, chain_len, slots_used, max_chain_len;
110+
u64 chain2_len_sum;
110111
struct hashtab_node *cur;
111112

112113
slots_used = 0;
113114
max_chain_len = 0;
115+
chain2_len_sum = 0;
114116
for (i = 0; i < h->size; i++) {
115117
cur = h->htable[i];
116118
if (cur) {
@@ -123,11 +125,14 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
123125

124126
if (chain_len > max_chain_len)
125127
max_chain_len = chain_len;
128+
129+
chain2_len_sum += (u64)chain_len * chain_len;
126130
}
127131
}
128132

129133
info->slots_used = slots_used;
130134
info->max_chain_len = max_chain_len;
135+
info->chain2_len_sum = chain2_len_sum;
131136
}
132137
#endif /* CONFIG_SECURITY_SELINUX_DEBUG */
133138

security/selinux/ss/hashtab.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct hashtab {
3838
struct hashtab_info {
3939
u32 slots_used;
4040
u32 max_chain_len;
41+
u64 chain2_len_sum;
4142
};
4243

4344
/*

security/selinux/ss/policydb.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ static u32 role_trans_hash(const void *k)
491491
{
492492
const struct role_trans_key *key = k;
493493

494-
return key->role + (key->type << 3) + (key->tclass << 5);
494+
return jhash_3words(key->role, key->type, (u32)key->tclass << 16 | key->tclass, 0);
495495
}
496496

497497
static int role_trans_cmp(const void *k1, const void *k2)
@@ -684,9 +684,9 @@ static void hash_eval(struct hashtab *h, const char *hash_name)
684684
struct hashtab_info info;
685685

686686
hashtab_stat(h, &info);
687-
pr_debug("SELinux: %s: %d entries and %d/%d buckets used, longest chain length %d\n",
687+
pr_debug("SELinux: %s: %d entries and %d/%d buckets used, longest chain length %d, sum of chain length^2 %llu\n",
688688
hash_name, h->nel, info.slots_used, h->size,
689-
info.max_chain_len);
689+
info.max_chain_len, info.chain2_len_sum);
690690
}
691691

692692
static void symtab_hash_eval(struct symtab *s)

security/selinux/ss/sidtab.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct sidtab_str_cache {
2525
struct list_head lru_member;
2626
struct sidtab_entry *parent;
2727
u32 len;
28-
char str[];
28+
char str[] __counted_by(len);
2929
};
3030

3131
#define index_to_sid(index) ((index) + SECINITSID_NUM + 1)

0 commit comments

Comments
 (0)