aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/security/selinux/ss/policydb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-08-30 08:51:16 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-08-30 08:51:16 -0700
commit1dbae189873066e817fe94b4e4ac7c8c42b51d77 (patch)
treef2323eef50fab4578685aadeaa70c1ad528eba61 /security/selinux/ss/policydb.c
parentMerge tag 'audit-pr-20230829' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit (diff)
parentselinux: prevent KMSAN warning in selinux_inet_conn_request() (diff)
downloadwireguard-linux-1dbae189873066e817fe94b4e4ac7c8c42b51d77.tar.xz
wireguard-linux-1dbae189873066e817fe94b4e4ac7c8c42b51d77.zip
Merge tag 'selinux-pr-20230829' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: "Thirty three SELinux patches, which is a pretty big number for us, but there isn't really anything scary in here; in fact we actually manage to remove 10 lines of code with this :) - Promote the SELinux DEBUG_HASHES macro to CONFIG_SECURITY_SELINUX_DEBUG The DEBUG_HASHES macro was a buried SELinux specific preprocessor debug macro that was a problem waiting to happen. Promoting the debug macro to a proper Kconfig setting should help both improve the visibility of the feature as well enable improved test coverage. We've moved some additional debug functions under the CONFIG_SECURITY_SELINUX_DEBUG flag and we may see more work in the future. - Emit a pr_notice() message if virtual memory is executable by default As this impacts the SELinux access control policy enforcement, if the system's configuration is such that virtual memory is executable by default we print a single line notice to the console. - Drop avtab_search() in favor of avtab_search_node() Both functions are nearly identical so we removed avtab_search() and converted the callers to avtab_search_node(). - Add some SELinux network auditing helpers The helpers not only reduce a small amount of code duplication, but they provide an opportunity to improve UDP flood performance slightly by delaying initialization of the audit data in some cases. - Convert GFP_ATOMIC allocators to GFP_KERNEL when reading SELinux policy There were two SELinux policy load helper functions that were allocating memory using GFP_ATOMIC, they have been converted to GFP_KERNEL. - Quiet a KMSAN warning in selinux_inet_conn_request() A one-line error path (re)set patch that resolves a KMSAN warning. It is important to note that this doesn't represent a real bug in the current code, but it quiets KMSAN and arguably hardens the code against future changes. - Cleanup the policy capability accessor functions This is a follow-up to the patch which reverted SELinux to using a global selinux_state pointer. This patch cleans up some artifacts of that change and turns each accessor into a one-line READ_ONCE() call into the policy capabilities array. - A number of patches from Christian Göttsche Christian submitted almost two-thirds of the patches in this pull request as he worked to harden the SELinux code against type differences, variable overflows, etc. - Support for separating early userspace from the kernel in policy, with a later revert We did have a patch that added a new userspace initial SID which would allow SELinux to distinguish between early user processes created before the initial policy load and the kernel itself. Unfortunately additional post-merge testing revealed a problematic interaction with an old SELinux userspace on an old version of Ubuntu so we've reverted the patch until we can resolve the compatibility issue. - Remove some outdated comments dealing with LSM hook registration When we removed the runtime disable functionality we forgot to remove some old comments discussing the importance of LSM hook registration ordering. - Minor administrative changes Stephen Smalley updated his email address and "debranded" SELinux from "NSA SELinux" to simply "SELinux". We've come a long way from the original NSA submission and I would consider SELinux a true community project at this point so removing the NSA branding just makes sense" * tag 'selinux-pr-20230829' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: (33 commits) selinux: prevent KMSAN warning in selinux_inet_conn_request() selinux: use unsigned iterator in nlmsgtab code selinux: avoid implicit conversions in policydb code selinux: avoid implicit conversions in selinuxfs code selinux: make left shifts well defined selinux: update type for number of class permissions in services code selinux: avoid implicit conversions in avtab code selinux: revert SECINITSID_INIT support selinux: use GFP_KERNEL while reading binary policy selinux: update comment on selinux_hooks[] selinux: avoid implicit conversions in services code selinux: avoid implicit conversions in mls code selinux: use identical iterator type in hashtab_duplicate() selinux: move debug functions into debug configuration selinux: log about VM being executable by default selinux: fix a 0/NULL mistmatch in ad_net_init_from_iif() selinux: introduce SECURITY_SELINUX_DEBUG configuration selinux: introduce and use lsm_ad_net_init*() helpers selinux: update my email address selinux: add missing newlines in pr_err() statements ...
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r--security/selinux/ss/policydb.c98
1 files changed, 52 insertions, 46 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index dc904865af58..2d528f699a22 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -2,7 +2,7 @@
/*
* Implementation of the policy database.
*
- * Author : Stephen Smalley, <sds@tycho.nsa.gov>
+ * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
*/
/*
@@ -41,7 +41,7 @@
#include "mls.h"
#include "services.h"
-#ifdef DEBUG_HASHES
+#ifdef CONFIG_SECURITY_SELINUX_DEBUG
static const char *const symtab_name[SYM_NUM] = {
"common prefixes",
"classes",
@@ -55,9 +55,9 @@ static const char *const symtab_name[SYM_NUM] = {
#endif
struct policydb_compat_info {
- int version;
- int sym_num;
- int ocon_num;
+ unsigned int version;
+ unsigned int sym_num;
+ unsigned int ocon_num;
};
/* These need to be updated if SYM_NUM or OCON_NUM changes */
@@ -159,9 +159,9 @@ static const struct policydb_compat_info policydb_compat[] = {
},
};
-static const struct policydb_compat_info *policydb_lookup_compat(int version)
+static const struct policydb_compat_info *policydb_lookup_compat(unsigned int version)
{
- int i;
+ unsigned int i;
for (i = 0; i < ARRAY_SIZE(policydb_compat); i++) {
if (policydb_compat[i].version == version)
@@ -359,7 +359,7 @@ static int role_tr_destroy(void *key, void *datum, void *p)
return 0;
}
-static void ocontext_destroy(struct ocontext *c, int i)
+static void ocontext_destroy(struct ocontext *c, unsigned int i)
{
if (!c)
return;
@@ -678,7 +678,7 @@ static int (*const index_f[SYM_NUM]) (void *key, void *datum, void *datap) = {
cat_index,
};
-#ifdef DEBUG_HASHES
+#ifdef CONFIG_SECURITY_SELINUX_DEBUG
static void hash_eval(struct hashtab *h, const char *hash_name)
{
struct hashtab_info info;
@@ -701,7 +701,10 @@ static void symtab_hash_eval(struct symtab *s)
static inline void hash_eval(struct hashtab *h, const char *hash_name)
{
}
-#endif
+static inline void symtab_hash_eval(struct symtab *s)
+{
+}
+#endif /* CONFIG_SECURITY_SELINUX_DEBUG */
/*
* Define the other val_to_name and val_to_struct arrays
@@ -725,10 +728,8 @@ static int policydb_index(struct policydb *p)
pr_debug("SELinux: %d classes, %d rules\n",
p->p_classes.nprim, p->te_avtab.nel);
-#ifdef DEBUG_HASHES
avtab_hash_eval(&p->te_avtab, "rules");
symtab_hash_eval(p->symtab);
-#endif
p->class_val_to_struct = kcalloc(p->p_classes.nprim,
sizeof(*p->class_val_to_struct),
@@ -781,7 +782,7 @@ void policydb_destroy(struct policydb *p)
{
struct ocontext *c, *ctmp;
struct genfs *g, *gtmp;
- int i;
+ u32 i;
struct role_allow *ra, *lra = NULL;
for (i = 0; i < SYM_NUM; i++) {
@@ -1127,8 +1128,8 @@ static int common_read(struct policydb *p, struct symtab *s, void *fp)
char *key = NULL;
struct common_datum *comdatum;
__le32 buf[4];
- u32 len, nel;
- int i, rc;
+ u32 i, len, nel;
+ int rc;
comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
if (!comdatum)
@@ -1193,13 +1194,13 @@ static int type_set_read(struct type_set *t, void *fp)
static int read_cons_helper(struct policydb *p,
struct constraint_node **nodep,
- int ncons, int allowxtarget, void *fp)
+ u32 ncons, int allowxtarget, void *fp)
{
struct constraint_node *c, *lc;
struct constraint_expr *e, *le;
__le32 buf[3];
- u32 nexpr;
- int rc, i, j, depth;
+ u32 i, j, nexpr;
+ int rc, depth;
lc = NULL;
for (i = 0; i < ncons; i++) {
@@ -1291,8 +1292,8 @@ static int class_read(struct policydb *p, struct symtab *s, void *fp)
char *key = NULL;
struct class_datum *cladatum;
__le32 buf[6];
- u32 len, len2, ncons, nel;
- int i, rc;
+ u32 i, len, len2, ncons, nel;
+ int rc;
cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
if (!cladatum)
@@ -1385,7 +1386,8 @@ static int role_read(struct policydb *p, struct symtab *s, void *fp)
{
char *key = NULL;
struct role_datum *role;
- int rc, to_read = 2;
+ int rc;
+ unsigned int to_read = 2;
__le32 buf[3];
u32 len;
@@ -1441,7 +1443,8 @@ static int type_read(struct policydb *p, struct symtab *s, void *fp)
{
char *key = NULL;
struct type_datum *typdatum;
- int rc, to_read = 3;
+ int rc;
+ unsigned int to_read = 3;
__le32 buf[4];
u32 len;
@@ -1515,7 +1518,8 @@ static int user_read(struct policydb *p, struct symtab *s, void *fp)
{
char *key = NULL;
struct user_datum *usrdatum;
- int rc, to_read = 2;
+ int rc;
+ unsigned int to_read = 2;
__le32 buf[3];
u32 len;
@@ -1569,7 +1573,7 @@ static int sens_read(struct policydb *p, struct symtab *s, void *fp)
__le32 buf[2];
u32 len;
- levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
+ levdatum = kzalloc(sizeof(*levdatum), GFP_KERNEL);
if (!levdatum)
return -ENOMEM;
@@ -1580,12 +1584,12 @@ static int sens_read(struct policydb *p, struct symtab *s, void *fp)
len = le32_to_cpu(buf[0]);
levdatum->isalias = le32_to_cpu(buf[1]);
- rc = str_read(&key, GFP_ATOMIC, fp, len);
+ rc = str_read(&key, GFP_KERNEL, fp, len);
if (rc)
goto bad;
rc = -ENOMEM;
- levdatum->level = kmalloc(sizeof(*levdatum->level), GFP_ATOMIC);
+ levdatum->level = kmalloc(sizeof(*levdatum->level), GFP_KERNEL);
if (!levdatum->level)
goto bad;
@@ -1610,7 +1614,7 @@ static int cat_read(struct policydb *p, struct symtab *s, void *fp)
__le32 buf[3];
u32 len;
- catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
+ catdatum = kzalloc(sizeof(*catdatum), GFP_KERNEL);
if (!catdatum)
return -ENOMEM;
@@ -1622,7 +1626,7 @@ static int cat_read(struct policydb *p, struct symtab *s, void *fp)
catdatum->value = le32_to_cpu(buf[1]);
catdatum->isalias = le32_to_cpu(buf[2]);
- rc = str_read(&key, GFP_ATOMIC, fp, len);
+ rc = str_read(&key, GFP_KERNEL, fp, len);
if (rc)
goto bad;
@@ -1656,11 +1660,11 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap)
upper = user = datum;
while (upper->bounds) {
struct ebitmap_node *node;
- unsigned long bit;
+ u32 bit;
if (++depth == POLICYDB_BOUNDS_MAXDEPTH) {
pr_err("SELinux: user %s: "
- "too deep or looped boundary",
+ "too deep or looped boundary\n",
(char *) key);
return -EINVAL;
}
@@ -1692,7 +1696,7 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
upper = role = datum;
while (upper->bounds) {
struct ebitmap_node *node;
- unsigned long bit;
+ u32 bit;
if (++depth == POLICYDB_BOUNDS_MAXDEPTH) {
pr_err("SELinux: role %s: "
@@ -1739,7 +1743,7 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
if (upper->attribute) {
pr_err("SELinux: type %s: "
- "bounded by attribute %s",
+ "bounded by attribute %s\n",
(char *) key,
sym_name(p, SYM_TYPES, upper->value - 1));
return -EINVAL;
@@ -1807,9 +1811,9 @@ static int range_read(struct policydb *p, void *fp)
{
struct range_trans *rt = NULL;
struct mls_range *r = NULL;
- int i, rc;
+ int rc;
__le32 buf[2];
- u32 nel;
+ u32 i, nel;
if (p->policyvers < POLICYDB_VERSION_MLS)
return 0;
@@ -2055,9 +2059,9 @@ out:
static int filename_trans_read(struct policydb *p, void *fp)
{
- u32 nel;
+ u32 nel, i;
__le32 buf[1];
- int rc, i;
+ int rc;
if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
return 0;
@@ -2096,8 +2100,8 @@ static int filename_trans_read(struct policydb *p, void *fp)
static int genfs_read(struct policydb *p, void *fp)
{
- int i, j, rc;
- u32 nel, nel2, len, len2;
+ int rc;
+ u32 i, j, nel, nel2, len, len2;
__le32 buf[1];
struct ocontext *l, *c;
struct ocontext *newc = NULL;
@@ -2210,8 +2214,9 @@ out:
static int ocontext_read(struct policydb *p, const struct policydb_compat_info *info,
void *fp)
{
- int i, j, rc;
- u32 nel, len;
+ int rc;
+ unsigned int i;
+ u32 j, nel, len;
__be64 prefixbuf[1];
__le32 buf[3];
struct ocontext *l, *c;
@@ -2402,9 +2407,9 @@ int policydb_read(struct policydb *p, void *fp)
struct role_allow *ra, *lra;
struct role_trans_key *rtk = NULL;
struct role_trans_datum *rtd = NULL;
- int i, j, rc;
+ int rc;
__le32 buf[4];
- u32 len, nprim, nel, perm;
+ u32 i, j, len, nprim, nel, perm;
char *policydb_str;
const struct policydb_compat_info *info;
@@ -3255,7 +3260,8 @@ static int (*const write_f[SYM_NUM]) (void *key, void *datum, void *datap) = {
static int ocontext_write(struct policydb *p, const struct policydb_compat_info *info,
void *fp)
{
- unsigned int i, j, rc;
+ unsigned int i, j;
+ int rc;
size_t nel, len;
__be64 prefixbuf[1];
__le32 buf[3];
@@ -3604,10 +3610,10 @@ static int filename_trans_write(struct policydb *p, void *fp)
*/
int policydb_write(struct policydb *p, void *fp)
{
- unsigned int i, num_syms;
+ unsigned int num_syms;
int rc;
__le32 buf[4];
- u32 config;
+ u32 config, i;
size_t len;
const struct policydb_compat_info *info;
@@ -3648,7 +3654,7 @@ int policydb_write(struct policydb *p, void *fp)
info = policydb_lookup_compat(p->policyvers);
if (!info) {
pr_err("SELinux: compatibility lookup failed for policy "
- "version %d", p->policyvers);
+ "version %d\n", p->policyvers);
return -EINVAL;
}