[PATCH v2 1/2] selinux: dump statistics for more hash tables

From: Christian Göttsche
Date: Fri Mar 15 2024 - 14:14:40 EST


Dump in the SELinux debug configuration the statistics for the
conditional rules avtab, the role transition, and class and common
permission hash tables.

Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
---
v2:
print key in hash_eval() for class and common tables
---
security/selinux/ss/conditional.c | 3 +++
security/selinux/ss/policydb.c | 23 ++++++++++++++++-------
2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index f12476855b27..e868fc403d75 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -169,6 +169,9 @@ int cond_init_bool_indexes(struct policydb *p)
p->p_bools.nprim, sizeof(*p->bool_val_to_struct), GFP_KERNEL);
if (!p->bool_val_to_struct)
return -ENOMEM;
+
+ avtab_hash_eval(&p->te_cond_avtab, "conditional_rules");
+
return 0;
}

diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 3d22d5baa829..b0f688fe0737 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -672,14 +672,17 @@ static int (*const index_f[SYM_NUM])(void *key, void *datum, void *datap) = {
/* clang-format on */

#ifdef CONFIG_SECURITY_SELINUX_DEBUG
-static void hash_eval(struct hashtab *h, const char *hash_name)
+static void hash_eval(struct hashtab *h, const char *hash_name, const char *hash_details)
{
struct hashtab_info info;

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

@@ -688,11 +691,11 @@ static void symtab_hash_eval(struct symtab *s)
int i;

for (i = 0; i < SYM_NUM; i++)
- hash_eval(&s[i].table, symtab_name[i]);
+ hash_eval(&s[i].table, symtab_name[i], NULL);
}

#else
-static inline void hash_eval(struct hashtab *h, const char *hash_name)
+static inline void hash_eval(struct hashtab *h, const char *hash_name, const char *hash_details)
{
}
static inline void symtab_hash_eval(struct symtab *s)
@@ -1178,6 +1181,8 @@ static int common_read(struct policydb *p, struct symtab *s, void *fp)
goto bad;
}

+ hash_eval(&comdatum->permissions.table, "common_permissions", key);
+
rc = symtab_insert(s, key, comdatum);
if (rc)
goto bad;
@@ -1358,6 +1363,8 @@ static int class_read(struct policydb *p, struct symtab *s, void *fp)
goto bad;
}

+ hash_eval(&cladatum->permissions.table, "class_permissions", key);
+
rc = read_cons_helper(p, &cladatum->constraints, ncons, 0, fp);
if (rc)
goto bad;
@@ -1898,7 +1905,7 @@ static int range_read(struct policydb *p, void *fp)
rt = NULL;
r = NULL;
}
- hash_eval(&p->range_tr, "rangetr");
+ hash_eval(&p->range_tr, "rangetr", NULL);
rc = 0;
out:
kfree(rt);
@@ -2116,7 +2123,7 @@ static int filename_trans_read(struct policydb *p, void *fp)
return rc;
}
}
- hash_eval(&p->filename_trans, "filenametr");
+ hash_eval(&p->filename_trans, "filenametr", NULL);
return 0;
}

@@ -2649,6 +2656,8 @@ int policydb_read(struct policydb *p, void *fp)
rtd = NULL;
}

+ hash_eval(&p->role_tr, "roletr", NULL);
+
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto bad;
--
2.43.0