Commit f5fc9e4a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents b9886c97 19c1c991
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -77,3 +77,13 @@ config SECURITY_SELINUX_DEBUG
	  This enables debugging code designed to help SELinux kernel
	  developers, unless you know what this does in the kernel code you
	  should leave this disabled.

	  To fine control the messages to be printed enable
	  CONFIG_DYNAMIC_DEBUG and see
	  Documentation/admin-guide/dynamic-debug-howto.rst for additional
	  information.

	  Example usage:

		echo -n 'file "security/selinux/*" +p' > \
			/proc/dynamic_debug/control
+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@ obj-$(CONFIG_SECURITY_SELINUX) := selinux.o

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

ccflags-$(CONFIG_SECURITY_SELINUX_DEBUG) += -DDEBUG

selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
	     netnode.o netport.o status.o \
	     ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \
+11 −26
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
 *	Tuned number of hash slots for avtab to reduce memory usage
 */

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

static struct avtab_node*
avtab_insert_node(struct avtab *h, u32 hvalue,
		  struct avtab_node *prev,
avtab_insert_node(struct avtab *h, struct avtab_node **dst,
		  const struct avtab_key *key, const struct avtab_datum *datum)
{
	struct avtab_node *newnode;
@@ -89,15 +89,8 @@ avtab_insert_node(struct avtab *h, u32 hvalue,
		newnode->datum.u.data = datum->u.data;
	}

	if (prev) {
		newnode->next = prev->next;
		prev->next = newnode;
	} else {
		struct avtab_node **n = &h->htable[hvalue];

		newnode->next = *n;
		*n = newnode;
	}
	newnode->next = *dst;
	*dst = newnode;

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

	newnode = avtab_insert_node(h, hvalue, prev, key, datum);
	newnode = avtab_insert_node(h, prev ? &prev->next : &h->htable[hvalue],
				    key, datum);
	if (!newnode)
		return -ENOMEM;

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

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

	if (nrules != 0) {
		u32 shift = 1;
		u32 work = nrules >> 3;
		while (work) {
			work >>= 1;
			shift++;
		}
		nslot = 1 << shift;
		nslot = nrules > 3 ? rounddown_pow_of_two(nrules / 2) : 2;
		if (nslot > MAX_AVTAB_HASH_BUCKETS)
			nslot = MAX_AVTAB_HASH_BUCKETS;

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

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

	set = 0;
	for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
		if (key.specified & spec_order[i])
			set++;
	}
	set = hweight16(key.specified & (AVTAB_XPERMS | AVTAB_TYPE | AVTAB_AV));
	if (!set || set > 1) {
		pr_err("SELinux:  avtab:  more than one specifier\n");
		return -EINVAL;
+5 −0
Original line number Diff line number Diff line
@@ -107,10 +107,12 @@ int hashtab_map(struct hashtab *h,
void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
{
	u32 i, chain_len, slots_used, max_chain_len;
	u64 chain2_len_sum;
	struct hashtab_node *cur;

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

			if (chain_len > max_chain_len)
				max_chain_len = chain_len;

			chain2_len_sum += (u64)chain_len * chain_len;
		}
	}

	info->slots_used = slots_used;
	info->max_chain_len = max_chain_len;
	info->chain2_len_sum = chain2_len_sum;
}
#endif /* CONFIG_SECURITY_SELINUX_DEBUG */

+1 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ struct hashtab {
struct hashtab_info {
	u32 slots_used;
	u32 max_chain_len;
	u64 chain2_len_sum;
};

/*
Loading