diff options
Diffstat (limited to 'security/selinux/ss')
-rw-r--r-- | security/selinux/ss/avtab.c | 121 | ||||
-rw-r--r-- | security/selinux/ss/avtab.h | 82 | ||||
-rw-r--r-- | security/selinux/ss/conditional.c | 100 | ||||
-rw-r--r-- | security/selinux/ss/conditional.h | 31 | ||||
-rw-r--r-- | security/selinux/ss/constraint.h | 67 | ||||
-rw-r--r-- | security/selinux/ss/context.c | 4 | ||||
-rw-r--r-- | security/selinux/ss/context.h | 45 | ||||
-rw-r--r-- | security/selinux/ss/ebitmap.c | 116 | ||||
-rw-r--r-- | security/selinux/ss/ebitmap.h | 87 | ||||
-rw-r--r-- | security/selinux/ss/hashtab.c | 29 | ||||
-rw-r--r-- | security/selinux/ss/hashtab.h | 37 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 89 | ||||
-rw-r--r-- | security/selinux/ss/mls.h | 58 | ||||
-rw-r--r-- | security/selinux/ss/mls_types.h | 32 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 546 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 210 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 186 | ||||
-rw-r--r-- | security/selinux/ss/services.h | 3 | ||||
-rw-r--r-- | security/selinux/ss/sidtab.c | 75 | ||||
-rw-r--r-- | security/selinux/ss/sidtab.h | 36 | ||||
-rw-r--r-- | security/selinux/ss/symtab.c | 22 | ||||
-rw-r--r-- | security/selinux/ss/symtab.h | 9 |
22 files changed, 1011 insertions, 974 deletions
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index 697eb4352439..c2c31521cace 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -1,20 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Implementation of the access vector table type. * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ -/* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> - * - * Added conditional policy language extensions - * - * Copyright (C) 2003 Tresys Technology, LLC - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2. +/* Updated: Frank Mayer <mayerf@tresys.com> and + * Karl MacMillan <kmacmillan@tresys.com> + * Added conditional policy language extensions + * Copyright (C) 2003 Tresys Technology, LLC * * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> - * Tuned number of hash slots for avtab to reduce memory usage + * Tuned number of hash slots for avtab to reduce memory usage */ #include <linux/bitops.h> @@ -36,19 +33,20 @@ static inline u32 avtab_hash(const struct avtab_key *keyp, u32 mask) static const u32 c2 = 0x1b873593; static const u32 r1 = 15; static const u32 r2 = 13; - static const u32 m = 5; - static const u32 n = 0xe6546b64; + static const u32 m = 5; + static const u32 n = 0xe6546b64; u32 hash = 0; -#define mix(input) do { \ - u32 v = input; \ - v *= c1; \ - v = (v << r1) | (v >> (32 - r1)); \ - v *= c2; \ - hash ^= v; \ +#define mix(input) \ + do { \ + u32 v = input; \ + v *= c1; \ + v = (v << r1) | (v >> (32 - r1)); \ + v *= c2; \ + hash ^= v; \ hash = (hash << r2) | (hash >> (32 - r2)); \ - hash = hash * m + n; \ + hash = hash * m + n; \ } while (0) mix(keyp->target_class); @@ -66,9 +64,10 @@ static inline u32 avtab_hash(const struct avtab_key *keyp, u32 mask) return hash & mask; } -static struct avtab_node* -avtab_insert_node(struct avtab *h, struct avtab_node **dst, - const struct avtab_key *key, const struct avtab_datum *datum) +static struct avtab_node *avtab_insert_node(struct avtab *h, + struct avtab_node **dst, + const struct avtab_key *key, + const struct avtab_datum *datum) { struct avtab_node *newnode; struct avtab_extended_perms *xperms; @@ -99,7 +98,7 @@ avtab_insert_node(struct avtab *h, struct avtab_node **dst, static int avtab_node_cmp(const struct avtab_key *key1, const struct avtab_key *key2) { - u16 specified = key1->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); + u16 specified = key1->specified & ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD); if (key1->source_type == key2->source_type && key1->target_type == key2->target_type && @@ -129,8 +128,7 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key, return -EINVAL; hvalue = avtab_hash(key, h->mask); - for (prev = NULL, cur = h->htable[hvalue]; - cur; + for (prev = NULL, cur = h->htable[hvalue]; cur; prev = cur, cur = cur->next) { cmp = avtab_node_cmp(key, &cur->key); /* extended perms may not be unique */ @@ -163,8 +161,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h, if (!h || !h->nslot || h->nel == U32_MAX) return NULL; hvalue = avtab_hash(key, h->mask); - for (prev = NULL, cur = h->htable[hvalue]; - cur; + for (prev = NULL, cur = h->htable[hvalue]; cur; prev = cur, cur = cur->next) { cmp = avtab_node_cmp(key, &cur->key); if (cmp <= 0) @@ -188,8 +185,7 @@ struct avtab_node *avtab_search_node(struct avtab *h, return NULL; hvalue = avtab_hash(key, h->mask); - for (cur = h->htable[hvalue]; cur; - cur = cur->next) { + for (cur = h->htable[hvalue]; cur; cur = cur->next) { cmp = avtab_node_cmp(key, &cur->key); if (cmp == 0) return cur; @@ -199,8 +195,8 @@ struct avtab_node *avtab_search_node(struct avtab *h, return NULL; } -struct avtab_node* -avtab_search_node_next(struct avtab_node *node, u16 specified) +struct avtab_node *avtab_search_node_next(struct avtab_node *node, + u16 specified) { struct avtab_key tmp_key; struct avtab_node *cur; @@ -314,17 +310,19 @@ void avtab_hash_eval(struct avtab *h, const char *tag) if (chain_len > max_chain_len) max_chain_len = chain_len; - chain2_len_sum += (unsigned long long)chain_len * chain_len; + chain2_len_sum += + (unsigned long long)chain_len * chain_len; } } pr_debug("SELinux: %s: %d entries and %d/%d buckets used, " - "longest chain length %d, sum of chain length^2 %llu\n", - tag, h->nel, slots_used, h->nslot, max_chain_len, - chain2_len_sum); + "longest chain length %d, sum of chain length^2 %llu\n", + tag, h->nel, slots_used, h->nslot, max_chain_len, + chain2_len_sum); } #endif /* CONFIG_SECURITY_SELINUX_DEBUG */ +/* clang-format off */ static const uint16_t spec_order[] = { AVTAB_ALLOWED, AVTAB_AUDITDENY, @@ -336,11 +334,12 @@ static const uint16_t spec_order[] = { AVTAB_XPERMS_AUDITALLOW, AVTAB_XPERMS_DONTAUDIT }; +/* clang-format on */ -int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, +int avtab_read_item(struct avtab *a, struct policy_file *fp, struct policydb *pol, int (*insertf)(struct avtab *a, const struct avtab_key *k, const struct avtab_datum *d, void *p), - void *p) + void *p, bool conditional) { __le16 buf16[4]; u16 enabled; @@ -365,9 +364,8 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, if (items2 > ARRAY_SIZE(buf32)) { pr_err("SELinux: avtab: entry overflow\n"); return -EINVAL; - } - rc = next_entry(buf32, fp, sizeof(u32)*items2); + rc = next_entry(buf32, fp, sizeof(u32) * items2); if (rc) { pr_err("SELinux: avtab: truncated entry\n"); return rc; @@ -400,8 +398,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, pr_err("SELinux: avtab: null entry\n"); return -EINVAL; } - if ((val & AVTAB_AV) && - (val & AVTAB_TYPE)) { + if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) { pr_err("SELinux: avtab: entry has both access vectors and types\n"); return -EINVAL; } @@ -428,7 +425,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, return 0; } - rc = next_entry(buf16, fp, sizeof(u16)*4); + rc = next_entry(buf16, fp, sizeof(u16) * 4); if (rc) { pr_err("SELinux: avtab: truncated entry\n"); return rc; @@ -454,10 +451,18 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, } if ((vers < POLICYDB_VERSION_XPERMS_IOCTL) && - (key.specified & AVTAB_XPERMS)) { + (key.specified & AVTAB_XPERMS)) { pr_err("SELinux: avtab: policy version %u does not " - "support extended permissions rules and one " - "was specified\n", vers); + "support extended permissions rules and one " + "was specified\n", + vers); + return -EINVAL; + } else if ((vers < POLICYDB_VERSION_COND_XPERMS) && + (key.specified & AVTAB_XPERMS) && conditional) { + pr_err("SELinux: avtab: policy version %u does not " + "support extended permissions rules in conditional " + "policies and one was specified\n", + vers); return -EINVAL; } else if (key.specified & AVTAB_XPERMS) { memset(&xperms, 0, sizeof(struct avtab_extended_perms)); @@ -471,7 +476,8 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, pr_err("SELinux: avtab: truncated entry\n"); return rc; } - rc = next_entry(buf32, fp, sizeof(u32)*ARRAY_SIZE(xperms.perms.p)); + rc = next_entry(buf32, fp, + sizeof(u32) * ARRAY_SIZE(xperms.perms.p)); if (rc) { pr_err("SELinux: avtab: truncated entry\n"); return rc; @@ -501,13 +507,12 @@ static int avtab_insertf(struct avtab *a, const struct avtab_key *k, return avtab_insert(a, k, d); } -int avtab_read(struct avtab *a, void *fp, struct policydb *pol) +int avtab_read(struct avtab *a, struct policy_file *fp, struct policydb *pol) { int rc; __le32 buf[1]; u32 nel, i; - rc = next_entry(buf, fp, sizeof(u32)); if (rc < 0) { pr_err("SELinux: avtab: truncated table\n"); @@ -525,7 +530,7 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol) goto bad; for (i = 0; i < nel; i++) { - rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL); + rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL, false); if (rc) { if (rc == -ENOMEM) pr_err("SELinux: avtab: out of memory\n"); @@ -545,7 +550,7 @@ bad: goto out; } -int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp) +int avtab_write_item(struct policydb *p, const struct avtab_node *cur, struct policy_file *fp) { __le16 buf16[4]; __le32 buf32[ARRAY_SIZE(cur->datum.u.xperms->perms.p)]; @@ -561,7 +566,8 @@ int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp) return rc; if (cur->key.specified & AVTAB_XPERMS) { - rc = put_entry(&cur->datum.u.xperms->specified, sizeof(u8), 1, fp); + rc = put_entry(&cur->datum.u.xperms->specified, sizeof(u8), 1, + fp); if (rc) return rc; rc = put_entry(&cur->datum.u.xperms->driver, sizeof(u8), 1, fp); @@ -570,7 +576,7 @@ int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp) for (i = 0; i < ARRAY_SIZE(cur->datum.u.xperms->perms.p); i++) buf32[i] = cpu_to_le32(cur->datum.u.xperms->perms.p[i]); rc = put_entry(buf32, sizeof(u32), - ARRAY_SIZE(cur->datum.u.xperms->perms.p), fp); + ARRAY_SIZE(cur->datum.u.xperms->perms.p), fp); } else { buf32[0] = cpu_to_le32(cur->datum.u.data); rc = put_entry(buf32, sizeof(u32), 1, fp); @@ -580,7 +586,7 @@ int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp) return 0; } -int avtab_write(struct policydb *p, struct avtab *a, void *fp) +int avtab_write(struct policydb *p, struct avtab *a, struct policy_file *fp) { u32 i; int rc = 0; @@ -593,8 +599,7 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp) return rc; for (i = 0; i < a->nslot; i++) { - for (cur = a->htable[i]; cur; - cur = cur->next) { + for (cur = a->htable[i]; cur; cur = cur->next) { rc = avtab_write_item(p, cur, fp); if (rc) return rc; @@ -606,10 +611,6 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp) void __init avtab_cache_init(void) { - avtab_node_cachep = kmem_cache_create("avtab_node", - sizeof(struct avtab_node), - 0, SLAB_PANIC, NULL); - avtab_xperms_cachep = kmem_cache_create("avtab_extended_perms", - sizeof(struct avtab_extended_perms), - 0, SLAB_PANIC, NULL); + avtab_node_cachep = KMEM_CACHE(avtab_node, SLAB_PANIC); + avtab_xperms_cachep = KMEM_CACHE(avtab_extended_perms, SLAB_PANIC); } diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 3c3904bf02b0..850b3453f259 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -9,42 +9,42 @@ * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ -/* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> - * - * Added conditional policy language extensions - * - * Copyright (C) 2003 Tresys Technology, LLC +/* Updated: Frank Mayer <mayerf@tresys.com> and + * Karl MacMillan <kmacmillan@tresys.com> + * Added conditional policy language extensions + * Copyright (C) 2003 Tresys Technology, LLC * * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> - * Tuned number of hash slots for avtab to reduce memory usage + * Tuned number of hash slots for avtab to reduce memory usage */ + #ifndef _SS_AVTAB_H_ #define _SS_AVTAB_H_ #include "security.h" struct avtab_key { - u16 source_type; /* source type */ - u16 target_type; /* target type */ - u16 target_class; /* target object class */ -#define AVTAB_ALLOWED 0x0001 -#define AVTAB_AUDITALLOW 0x0002 -#define AVTAB_AUDITDENY 0x0004 -#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) -#define AVTAB_TRANSITION 0x0010 -#define AVTAB_MEMBER 0x0020 -#define AVTAB_CHANGE 0x0040 -#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) + u16 source_type; /* source type */ + u16 target_type; /* target type */ + u16 target_class; /* target object class */ +#define AVTAB_ALLOWED 0x0001 +#define AVTAB_AUDITALLOW 0x0002 +#define AVTAB_AUDITDENY 0x0004 +#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) +#define AVTAB_TRANSITION 0x0010 +#define AVTAB_MEMBER 0x0020 +#define AVTAB_CHANGE 0x0040 +#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) /* extended permissions */ #define AVTAB_XPERMS_ALLOWED 0x0100 -#define AVTAB_XPERMS_AUDITALLOW 0x0200 +#define AVTAB_XPERMS_AUDITALLOW 0x0200 #define AVTAB_XPERMS_DONTAUDIT 0x0400 -#define AVTAB_XPERMS (AVTAB_XPERMS_ALLOWED | \ - AVTAB_XPERMS_AUDITALLOW | \ - AVTAB_XPERMS_DONTAUDIT) -#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ -#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ - u16 specified; /* what field is specified */ +#define AVTAB_XPERMS \ + (AVTAB_XPERMS_ALLOWED | AVTAB_XPERMS_AUDITALLOW | \ + AVTAB_XPERMS_DONTAUDIT) +#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ +#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ + u16 specified; /* what field is specified */ }; /* @@ -55,6 +55,7 @@ struct avtab_extended_perms { /* These are not flags. All 256 values may be used */ #define AVTAB_XPERMS_IOCTLFUNCTION 0x01 #define AVTAB_XPERMS_IOCTLDRIVER 0x02 +#define AVTAB_XPERMS_NLMSG 0x03 /* extension of the avtab_key specified */ u8 specified; /* ioctl, netfilter, ... */ /* @@ -82,16 +83,19 @@ struct avtab_node { struct avtab { struct avtab_node **htable; - u32 nel; /* number of elements */ - u32 nslot; /* number of hash slots */ - u32 mask; /* mask to compute hash func */ + u32 nel; /* number of elements */ + u32 nslot; /* number of hash slots */ + u32 mask; /* mask to compute hash func */ }; void avtab_init(struct avtab *h); -int avtab_alloc(struct avtab *, u32); +int avtab_alloc(struct avtab *h, u32 nrules); int avtab_alloc_dup(struct avtab *new, const struct avtab *orig); void avtab_destroy(struct avtab *h); +#define MAX_AVTAB_HASH_BITS 16 +#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) + #ifdef CONFIG_SECURITY_SELINUX_DEBUG void avtab_hash_eval(struct avtab *h, const char *tag); #else @@ -101,14 +105,16 @@ static inline void avtab_hash_eval(struct avtab *h, const char *tag) #endif struct policydb; -int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, +struct policy_file; +int avtab_read_item(struct avtab *a, struct policy_file *fp, struct policydb *pol, int (*insert)(struct avtab *a, const struct avtab_key *k, const struct avtab_datum *d, void *p), - void *p); + void *p, bool conditional); -int avtab_read(struct avtab *a, void *fp, struct policydb *pol); -int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp); -int avtab_write(struct policydb *p, struct avtab *a, void *fp); +int avtab_read(struct avtab *a, struct policy_file *fp, struct policydb *pol); +int avtab_write_item(struct policydb *p, const struct avtab_node *cur, + struct policy_file *fp); +int avtab_write(struct policydb *p, struct avtab *a, struct policy_file *fp); struct avtab_node *avtab_insert_nonunique(struct avtab *h, const struct avtab_key *key, @@ -116,11 +122,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_node *avtab_search_node(struct avtab *h, const struct avtab_key *key); +struct avtab_node *avtab_search_node_next(struct avtab_node *node, + u16 specified); -struct avtab_node *avtab_search_node_next(struct avtab_node *node, u16 specified); - -#define MAX_AVTAB_HASH_BITS 16 -#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) - -#endif /* _SS_AVTAB_H_ */ - +#endif /* _SS_AVTAB_H_ */ diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 81ff676f209a..1bebfcb9c6a1 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -1,8 +1,7 @@ -// SPDX-License-Identifier: GPL-2.0-only +/* SPDX-License-Identifier: GPL-2.0-only */ /* Authors: Karl MacMillan <kmacmillan@tresys.com> * Frank Mayer <mayerf@tresys.com> - * - * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * Copyright (C) 2003 - 2004 Tresys Technology, LLC */ #include <linux/kernel.h> @@ -166,11 +165,13 @@ void cond_policydb_destroy(struct policydb *p) int cond_init_bool_indexes(struct policydb *p) { kfree(p->bool_val_to_struct); - p->bool_val_to_struct = kmalloc_array(p->p_bools.nprim, - sizeof(*p->bool_val_to_struct), - GFP_KERNEL); + p->bool_val_to_struct = kmalloc_array( + 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; } @@ -205,7 +206,7 @@ static int bool_isvalid(struct cond_bool_datum *b) return 1; } -int cond_read_bool(struct policydb *p, struct symtab *s, void *fp) +int cond_read_bool(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct cond_bool_datum *booldatum; @@ -229,17 +230,11 @@ int cond_read_bool(struct policydb *p, struct symtab *s, void *fp) goto err; len = le32_to_cpu(buf[2]); - if (((len == 0) || (len == (u32)-1))) - goto err; - rc = -ENOMEM; - key = kmalloc(len + 1, GFP_KERNEL); - if (!key) - goto err; - rc = next_entry(key, fp, len); + rc = str_read(&key, GFP_KERNEL, fp, len); if (rc) goto err; - key[len] = '\0'; + rc = symtab_insert(s, key, booldatum); if (rc) goto err; @@ -287,7 +282,8 @@ static int cond_insertf(struct avtab *a, const struct avtab_key *k, if (other) { node_ptr = avtab_search_node(&p->te_cond_avtab, k); if (node_ptr) { - if (avtab_search_node_next(node_ptr, k->specified)) { + if (avtab_search_node_next(node_ptr, + k->specified)) { pr_err("SELinux: too many conflicting type rules.\n"); return -EINVAL; } @@ -321,7 +317,7 @@ static int cond_insertf(struct avtab *a, const struct avtab_key *k, return 0; } -static int cond_read_av_list(struct policydb *p, void *fp, +static int cond_read_av_list(struct policydb *p, struct policy_file *fp, struct cond_av_list *list, struct cond_av_list *other) { @@ -347,7 +343,7 @@ static int cond_read_av_list(struct policydb *p, void *fp, for (i = 0; i < len; i++) { data.dst = &list->nodes[i]; rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf, - &data); + &data, true); if (rc) { kfree(list->nodes); list->nodes = NULL; @@ -373,7 +369,7 @@ static int expr_node_isvalid(struct policydb *p, struct cond_expr_node *expr) return 1; } -static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) +static int cond_read_node(struct policydb *p, struct cond_node *node, struct policy_file *fp) { __le32 buf[2]; u32 i, len; @@ -413,7 +409,7 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) return cond_read_av_list(p, fp, &node->false_list, &node->true_list); } -int cond_read_list(struct policydb *p, void *fp) +int cond_read_list(struct policydb *p, struct policy_file *fp) { __le32 buf[1]; u32 i, len; @@ -451,7 +447,7 @@ int cond_write_bool(void *vkey, void *datum, void *ptr) char *key = vkey; struct cond_bool_datum *booldatum = datum; struct policy_data *pd = ptr; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; __le32 buf[3]; u32 len; int rc; @@ -478,8 +474,8 @@ int cond_write_bool(void *vkey, void *datum, void *ptr) * the conditional. This means that the avtab with the conditional * rules will not be saved but will be rebuilt on policy load. */ -static int cond_write_av_list(struct policydb *p, - struct cond_av_list *list, struct policy_file *fp) +static int cond_write_av_list(struct policydb *p, struct cond_av_list *list, + struct policy_file *fp) { __le32 buf[1]; u32 i; @@ -500,7 +496,7 @@ static int cond_write_av_list(struct policydb *p, } static int cond_write_node(struct policydb *p, struct cond_node *node, - struct policy_file *fp) + struct policy_file *fp) { __le32 buf[2]; int rc; @@ -534,7 +530,7 @@ static int cond_write_node(struct policydb *p, struct cond_node *node, return 0; } -int cond_write_list(struct policydb *p, void *fp) +int cond_write_list(struct policydb *p, struct policy_file *fp) { u32 i; __le32 buf[1]; @@ -555,7 +551,7 @@ int cond_write_list(struct policydb *p, void *fp) } void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, - struct extended_perms_decision *xpermd) + struct extended_perms_decision *xpermd) { struct avtab_node *node; @@ -563,7 +559,7 @@ void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, return; for (node = avtab_search_node(ctab, key); node; - node = avtab_search_node_next(node, key->specified)) { + node = avtab_search_node_next(node, key->specified)) { if (node->key.specified & AVTAB_ENABLED) services_compute_xperms_decision(xpermd, node); } @@ -572,7 +568,7 @@ void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, * av table, and if so, add them to the result */ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, - struct av_decision *avd, struct extended_perms *xperms) + struct av_decision *avd, struct extended_perms *xperms) { struct avtab_node *node; @@ -580,30 +576,30 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, return; for (node = avtab_search_node(ctab, key); node; - node = avtab_search_node_next(node, key->specified)) { - if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) == - (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) + node = avtab_search_node_next(node, key->specified)) { + if ((u16)(AVTAB_ALLOWED | AVTAB_ENABLED) == + (node->key.specified & (AVTAB_ALLOWED | AVTAB_ENABLED))) avd->allowed |= node->datum.u.data; - if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) == - (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) + if ((u16)(AVTAB_AUDITDENY | AVTAB_ENABLED) == + (node->key.specified & (AVTAB_AUDITDENY | AVTAB_ENABLED))) /* Since a '0' in an auditdeny mask represents a * permission we do NOT want to audit (dontaudit), we use * the '&' operand to ensure that all '0's in the mask * are retained (much unlike the allow and auditallow cases). */ avd->auditdeny &= node->datum.u.data; - if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == - (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) + if ((u16)(AVTAB_AUDITALLOW | AVTAB_ENABLED) == + (node->key.specified & (AVTAB_AUDITALLOW | AVTAB_ENABLED))) avd->auditallow |= node->datum.u.data; if (xperms && (node->key.specified & AVTAB_ENABLED) && - (node->key.specified & AVTAB_XPERMS)) + (node->key.specified & AVTAB_XPERMS)) services_compute_xperms_drivers(xperms, node); } } static int cond_dup_av_list(struct cond_av_list *new, - struct cond_av_list *orig, - struct avtab *avtab) + const struct cond_av_list *orig, + struct avtab *avtab) { u32 i; @@ -614,9 +610,8 @@ static int cond_dup_av_list(struct cond_av_list *new, return -ENOMEM; for (i = 0; i < orig->len; i++) { - new->nodes[i] = avtab_insert_nonunique(avtab, - &orig->nodes[i]->key, - &orig->nodes[i]->datum); + new->nodes[i] = avtab_insert_nonunique( + avtab, &orig->nodes[i]->key, &orig->nodes[i]->datum); if (!new->nodes[i]) return -ENOMEM; new->len++; @@ -626,7 +621,7 @@ static int cond_dup_av_list(struct cond_av_list *new, } static int duplicate_policydb_cond_list(struct policydb *newp, - struct policydb *origp) + const struct policydb *origp) { int rc; u32 i; @@ -637,19 +632,19 @@ static int duplicate_policydb_cond_list(struct policydb *newp, newp->cond_list_len = 0; newp->cond_list = kcalloc(origp->cond_list_len, - sizeof(*newp->cond_list), - GFP_KERNEL); + sizeof(*newp->cond_list), GFP_KERNEL); if (!newp->cond_list) goto error; for (i = 0; i < origp->cond_list_len; i++) { struct cond_node *newn = &newp->cond_list[i]; - struct cond_node *orign = &origp->cond_list[i]; + const struct cond_node *orign = &origp->cond_list[i]; newp->cond_list_len++; newn->cur_state = orign->cur_state; - newn->expr.nodes = kmemdup(orign->expr.nodes, + newn->expr.nodes = + kmemdup(orign->expr.nodes, orign->expr.len * sizeof(*orign->expr.nodes), GFP_KERNEL); if (!newn->expr.nodes) @@ -658,12 +653,12 @@ static int duplicate_policydb_cond_list(struct policydb *newp, newn->expr.len = orign->expr.len; rc = cond_dup_av_list(&newn->true_list, &orign->true_list, - &newp->te_cond_avtab); + &newp->te_cond_avtab); if (rc) goto error; rc = cond_dup_av_list(&newn->false_list, &orign->false_list, - &newp->te_cond_avtab); + &newp->te_cond_avtab); if (rc) goto error; } @@ -683,7 +678,8 @@ static int cond_bools_destroy(void *key, void *datum, void *args) return 0; } -static int cond_bools_copy(struct hashtab_node *new, struct hashtab_node *orig, void *args) +static int cond_bools_copy(struct hashtab_node *new, + const struct hashtab_node *orig, void *args) { struct cond_bool_datum *datum; @@ -709,7 +705,7 @@ static int cond_bools_index(void *key, void *datum, void *args) } static int duplicate_policydb_bools(struct policydb *newdb, - struct policydb *orig) + const struct policydb *orig) { struct cond_bool_datum **cond_bool_array; int rc; @@ -721,7 +717,7 @@ static int duplicate_policydb_bools(struct policydb *newdb, return -ENOMEM; rc = hashtab_duplicate(&newdb->p_bools.table, &orig->p_bools.table, - cond_bools_copy, cond_bools_destroy, NULL); + cond_bools_copy, cond_bools_destroy, NULL); if (rc) { kfree(cond_bool_array); return -ENOMEM; @@ -742,7 +738,7 @@ void cond_policydb_destroy_dup(struct policydb *p) cond_policydb_destroy(p); } -int cond_policydb_dup(struct policydb *new, struct policydb *orig) +int cond_policydb_dup(struct policydb *new, const struct policydb *orig) { cond_policydb_init(new); diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h index 5a7b51278dc6..468e98ad3ea1 100644 --- a/security/selinux/ss/conditional.h +++ b/security/selinux/ss/conditional.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Authors: Karl MacMillan <kmacmillan@tresys.com> * Frank Mayer <mayerf@tresys.com> - * - * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * Copyright (C) 2003 - 2004 Tresys Technology, LLC */ #ifndef _CONDITIONAL_H_ @@ -20,14 +19,14 @@ * in reverse polish notation. */ struct cond_expr_node { -#define COND_BOOL 1 /* plain bool */ -#define COND_NOT 2 /* !bool */ -#define COND_OR 3 /* bool || bool */ -#define COND_AND 4 /* bool && bool */ -#define COND_XOR 5 /* bool ^ bool */ -#define COND_EQ 6 /* bool == bool */ -#define COND_NEQ 7 /* bool != bool */ -#define COND_LAST COND_NEQ +#define COND_BOOL 1 /* plain bool */ +#define COND_NOT 2 /* !bool */ +#define COND_OR 3 /* bool || bool */ +#define COND_AND 4 /* bool && bool */ +#define COND_XOR 5 /* bool ^ bool */ +#define COND_EQ 6 /* bool == bool */ +#define COND_NEQ 7 /* bool != bool */ +#define COND_LAST COND_NEQ u32 expr_type; u32 boolean; }; @@ -69,17 +68,17 @@ int cond_destroy_bool(void *key, void *datum, void *p); int cond_index_bool(void *key, void *datum, void *datap); -int cond_read_bool(struct policydb *p, struct symtab *s, void *fp); -int cond_read_list(struct policydb *p, void *fp); +int cond_read_bool(struct policydb *p, struct symtab *s, struct policy_file *fp); +int cond_read_list(struct policydb *p, struct policy_file *fp); int cond_write_bool(void *key, void *datum, void *ptr); -int cond_write_list(struct policydb *p, void *fp); +int cond_write_list(struct policydb *p, struct policy_file *fp); void cond_compute_av(struct avtab *ctab, struct avtab_key *key, - struct av_decision *avd, struct extended_perms *xperms); + struct av_decision *avd, struct extended_perms *xperms); void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, - struct extended_perms_decision *xpermd); + struct extended_perms_decision *xpermd); void evaluate_cond_nodes(struct policydb *p); void cond_policydb_destroy_dup(struct policydb *p); -int cond_policydb_dup(struct policydb *new, struct policydb *orig); +int cond_policydb_dup(struct policydb *new, const struct policydb *orig); #endif /* _CONDITIONAL_H_ */ diff --git a/security/selinux/ss/constraint.h b/security/selinux/ss/constraint.h index f76eb3128ad5..203033cfad67 100644 --- a/security/selinux/ss/constraint.h +++ b/security/selinux/ss/constraint.h @@ -13,6 +13,7 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #ifndef _SS_CONSTRAINT_H_ #define _SS_CONSTRAINT_H_ @@ -21,43 +22,43 @@ #define CEXPR_MAXDEPTH 5 struct constraint_expr { -#define CEXPR_NOT 1 /* not expr */ -#define CEXPR_AND 2 /* expr and expr */ -#define CEXPR_OR 3 /* expr or expr */ -#define CEXPR_ATTR 4 /* attr op attr */ -#define CEXPR_NAMES 5 /* attr op names */ - u32 expr_type; /* expression type */ - -#define CEXPR_USER 1 /* user */ -#define CEXPR_ROLE 2 /* role */ -#define CEXPR_TYPE 4 /* type */ -#define CEXPR_TARGET 8 /* target if set, source otherwise */ -#define CEXPR_XTARGET 16 /* special 3rd target for validatetrans rule */ -#define CEXPR_L1L2 32 /* low level 1 vs. low level 2 */ -#define CEXPR_L1H2 64 /* low level 1 vs. high level 2 */ -#define CEXPR_H1L2 128 /* high level 1 vs. low level 2 */ -#define CEXPR_H1H2 256 /* high level 1 vs. high level 2 */ -#define CEXPR_L1H1 512 /* low level 1 vs. high level 1 */ -#define CEXPR_L2H2 1024 /* low level 2 vs. high level 2 */ - u32 attr; /* attribute */ - -#define CEXPR_EQ 1 /* == or eq */ -#define CEXPR_NEQ 2 /* != */ -#define CEXPR_DOM 3 /* dom */ -#define CEXPR_DOMBY 4 /* domby */ -#define CEXPR_INCOMP 5 /* incomp */ - u32 op; /* operator */ - - struct ebitmap names; /* names */ +#define CEXPR_NOT 1 /* not expr */ +#define CEXPR_AND 2 /* expr and expr */ +#define CEXPR_OR 3 /* expr or expr */ +#define CEXPR_ATTR 4 /* attr op attr */ +#define CEXPR_NAMES 5 /* attr op names */ + u32 expr_type; /* expression type */ + +#define CEXPR_USER 1 /* user */ +#define CEXPR_ROLE 2 /* role */ +#define CEXPR_TYPE 4 /* type */ +#define CEXPR_TARGET 8 /* target if set, source otherwise */ +#define CEXPR_XTARGET 16 /* special 3rd target for validatetrans rule */ +#define CEXPR_L1L2 32 /* low level 1 vs. low level 2 */ +#define CEXPR_L1H2 64 /* low level 1 vs. high level 2 */ +#define CEXPR_H1L2 128 /* high level 1 vs. low level 2 */ +#define CEXPR_H1H2 256 /* high level 1 vs. high level 2 */ +#define CEXPR_L1H1 512 /* low level 1 vs. high level 1 */ +#define CEXPR_L2H2 1024 /* low level 2 vs. high level 2 */ + u32 attr; /* attribute */ + +#define CEXPR_EQ 1 /* == or eq */ +#define CEXPR_NEQ 2 /* != */ +#define CEXPR_DOM 3 /* dom */ +#define CEXPR_DOMBY 4 /* domby */ +#define CEXPR_INCOMP 5 /* incomp */ + u32 op; /* operator */ + + struct ebitmap names; /* names */ struct type_set *type_names; - struct constraint_expr *next; /* next expression */ + struct constraint_expr *next; /* next expression */ }; struct constraint_node { - u32 permissions; /* constrained permissions */ - struct constraint_expr *expr; /* constraint on permissions */ - struct constraint_node *next; /* next constraint */ + u32 permissions; /* constrained permissions */ + struct constraint_expr *expr; /* constraint on permissions */ + struct constraint_node *next; /* next constraint */ }; -#endif /* _SS_CONSTRAINT_H_ */ +#endif /* _SS_CONSTRAINT_H_ */ diff --git a/security/selinux/ss/context.c b/security/selinux/ss/context.c index 38bc0aa524a6..a528b7f76280 100644 --- a/security/selinux/ss/context.c +++ b/security/selinux/ss/context.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Implementations of the security context functions. * @@ -20,7 +20,7 @@ u32 context_compute_hash(const struct context *c) * context struct with only the len & str set (and vice versa) * under a given policy. Since context structs from different * policies should never meet, it is safe to hash valid and - * invalid contexts differently. The context_cmp() function + * invalid contexts differently. The context_equal() function * already operates under the same assumption. */ if (c->len) diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h index 1f59468c0759..dd3b9b5b588e 100644 --- a/security/selinux/ss/context.h +++ b/security/selinux/ss/context.h @@ -13,6 +13,7 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #ifndef _SS_CONTEXT_H_ #define _SS_CONTEXT_H_ @@ -28,9 +29,9 @@ struct context { u32 user; u32 role; u32 type; - u32 len; /* length of string in bytes */ + u32 len; /* length of string in bytes */ struct mls_range range; - char *str; /* string representation if context cannot be mapped. */ + char *str; /* string representation if context cannot be mapped. */ }; static inline void mls_context_init(struct context *c) @@ -38,7 +39,8 @@ static inline void mls_context_init(struct context *c) memset(&c->range, 0, sizeof(c->range)); } -static inline int mls_context_cpy(struct context *dst, const struct context *src) +static inline int mls_context_cpy(struct context *dst, + const struct context *src) { int rc; @@ -58,7 +60,8 @@ out: /* * Sets both levels in the MLS range of 'dst' to the low level of 'src'. */ -static inline int mls_context_cpy_low(struct context *dst, const struct context *src) +static inline int mls_context_cpy_low(struct context *dst, + const struct context *src) { int rc; @@ -78,7 +81,8 @@ out: /* * Sets both levels in the MLS range of 'dst' to the high level of 'src'. */ -static inline int mls_context_cpy_high(struct context *dst, const struct context *src) +static inline int mls_context_cpy_high(struct context *dst, + const struct context *src) { int rc; @@ -95,9 +99,9 @@ out: return rc; } - static inline int mls_context_glblub(struct context *dst, - const struct context *c1, const struct context *c2) + const struct context *c1, + const struct context *c2) { struct mls_range *dr = &dst->range; const struct mls_range *r1 = &c1->range, *r2 = &c2->range; @@ -114,13 +118,13 @@ static inline int mls_context_glblub(struct context *dst, /* Take the least of the high */ dr->level[1].sens = min(r1->level[1].sens, r2->level[1].sens); - rc = ebitmap_and(&dr->level[0].cat, - &r1->level[0].cat, &r2->level[0].cat); + rc = ebitmap_and(&dr->level[0].cat, &r1->level[0].cat, + &r2->level[0].cat); if (rc) goto out; - rc = ebitmap_and(&dr->level[1].cat, - &r1->level[1].cat, &r2->level[1].cat); + rc = ebitmap_and(&dr->level[1].cat, &r1->level[1].cat, + &r2->level[1].cat); if (rc) goto out; @@ -128,12 +132,13 @@ out: return rc; } -static inline int mls_context_cmp(const struct context *c1, const struct context *c2) +static inline bool mls_context_equal(const struct context *c1, + const struct context *c2) { return ((c1->range.level[0].sens == c2->range.level[0].sens) && - ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) && + ebitmap_equal(&c1->range.level[0].cat, &c2->range.level[0].cat) && (c1->range.level[1].sens == c2->range.level[1].sens) && - ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat)); + ebitmap_equal(&c1->range.level[1].cat, &c2->range.level[1].cat)); } static inline void mls_context_destroy(struct context *c) @@ -183,19 +188,17 @@ static inline void context_destroy(struct context *c) mls_context_destroy(c); } -static inline int context_cmp(const struct context *c1, const struct context *c2) +static inline bool context_equal(const struct context *c1, + const struct context *c2) { if (c1->len && c2->len) return (c1->len == c2->len && !strcmp(c1->str, c2->str)); if (c1->len || c2->len) return 0; - return ((c1->user == c2->user) && - (c1->role == c2->role) && - (c1->type == c2->type) && - mls_context_cmp(c1, c2)); + return ((c1->user == c2->user) && (c1->role == c2->role) && + (c1->type == c2->type) && mls_context_equal(c1, c2)); } u32 context_compute_hash(const struct context *c); -#endif /* _SS_CONTEXT_H_ */ - +#endif /* _SS_CONTEXT_H_ */ diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index 77875ad355f7..43bc19e21960 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Implementation of the extensible bitmap type. * @@ -6,14 +6,11 @@ */ /* * Updated: Hewlett-Packard <paul@paul-moore.com> + * Added support to import/export the NetLabel category bitmap + * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 * - * Added support to import/export the NetLabel category bitmap - * - * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - */ -/* * Updated: KaiGai Kohei <kaigai@ak.jp.nec.com> - * Applied standard bit operations to improve bitmap scanning. + * Applied standard bit operations to improve bitmap scanning. */ #include <linux/kernel.h> @@ -24,30 +21,29 @@ #include "ebitmap.h" #include "policydb.h" -#define BITS_PER_U64 (sizeof(u64) * 8) +#define BITS_PER_U64 ((u32)(sizeof(u64) * 8)) static struct kmem_cache *ebitmap_node_cachep __ro_after_init; -int ebitmap_cmp(const struct ebitmap *e1, const struct ebitmap *e2) +bool ebitmap_equal(const struct ebitmap *e1, const struct ebitmap *e2) { const struct ebitmap_node *n1, *n2; if (e1->highbit != e2->highbit) - return 0; + return false; n1 = e1->node; n2 = e2->node; - while (n1 && n2 && - (n1->startbit == n2->startbit) && + while (n1 && n2 && (n1->startbit == n2->startbit) && !memcmp(n1->maps, n2->maps, EBITMAP_SIZE / 8)) { n1 = n1->next; n2 = n2->next; } if (n1 || n2) - return 0; + return false; - return 1; + return true; } int ebitmap_cpy(struct ebitmap *dst, const struct ebitmap *src) @@ -79,14 +75,17 @@ int ebitmap_cpy(struct ebitmap *dst, const struct ebitmap *src) return 0; } -int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1, const struct ebitmap *e2) +int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1, + const struct ebitmap *e2) { struct ebitmap_node *n; - int bit, rc; + u32 bit; + int rc; ebitmap_init(dst); - ebitmap_for_each_positive_bit(e1, n, bit) { + ebitmap_for_each_positive_bit(e1, n, bit) + { if (ebitmap_get_bit(e2, bit)) { rc = ebitmap_set_bit(dst, bit, 1); if (rc < 0) @@ -96,7 +95,6 @@ int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1, const struct ebit return 0; } - #ifdef CONFIG_NETLABEL /** * ebitmap_netlbl_export - Export an ebitmap into a NetLabel category bitmap @@ -131,10 +129,8 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap, for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) { e_map = e_iter->maps[iter]; if (e_map != 0) { - rc = netlbl_catmap_setlong(catmap, - offset, - e_map, - GFP_ATOMIC); + rc = netlbl_catmap_setlong(catmap, offset, + e_map, GFP_ATOMIC); if (rc != 0) goto netlbl_export_failure; } @@ -185,7 +181,8 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap, if (e_iter == NULL || offset >= e_iter->startbit + EBITMAP_SIZE) { e_prev = e_iter; - e_iter = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC); + e_iter = kmem_cache_zalloc(ebitmap_node_cachep, + GFP_ATOMIC); if (e_iter == NULL) goto netlbl_import_failure; e_iter->startbit = offset - (offset % EBITMAP_SIZE); @@ -218,7 +215,8 @@ netlbl_import_failure: * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed * last_e2bit. */ -int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2, u32 last_e2bit) +int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2, + u32 last_e2bit) { const struct ebitmap_node *n1, *n2; int i; @@ -234,8 +232,8 @@ int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2, u32 las n1 = n1->next; continue; } - for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; ) - i--; /* Skip trailing NULL map entries */ + for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i];) + i--; /* Skip trailing NULL map entries */ if (last_e2bit && (i >= 0)) { u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE + __fls(n2->maps[i]); @@ -259,7 +257,7 @@ int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2, u32 las return 1; } -int ebitmap_get_bit(const struct ebitmap *e, unsigned long bit) +int ebitmap_get_bit(const struct ebitmap *e, u32 bit) { const struct ebitmap_node *n; @@ -276,7 +274,7 @@ int ebitmap_get_bit(const struct ebitmap *e, unsigned long bit) return 0; } -int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value) +int ebitmap_set_bit(struct ebitmap *e, u32 bit, int value) { struct ebitmap_node *n, *prev, *new; @@ -287,7 +285,7 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value) if (value) { ebitmap_node_set_bit(n, bit); } else { - unsigned int s; + u32 s; ebitmap_node_clr_bit(n, bit); @@ -302,8 +300,8 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value) * within the bitmap */ if (prev) - e->highbit = prev->startbit - + EBITMAP_SIZE; + e->highbit = prev->startbit + + EBITMAP_SIZE; else e->highbit = 0; } @@ -362,15 +360,15 @@ void ebitmap_destroy(struct ebitmap *e) e->node = NULL; } -int ebitmap_read(struct ebitmap *e, void *fp) +int ebitmap_read(struct ebitmap *e, struct policy_file *fp) { struct ebitmap_node *n = NULL; - u32 mapunit, count, startbit, index; + u32 mapunit, count, startbit, index, i; __le32 ebitmap_start; u64 map; __le64 mapbits; __le32 buf[3]; - int rc, i; + int rc; ebitmap_init(e); @@ -384,7 +382,7 @@ int ebitmap_read(struct ebitmap *e, void *fp) if (mapunit != BITS_PER_U64) { pr_err("SELinux: ebitmap: map size %u does not " - "match my size %zd (high bit was %d)\n", + "match my size %u (high bit was %u)\n", mapunit, BITS_PER_U64, e->highbit); goto bad; } @@ -410,13 +408,13 @@ int ebitmap_read(struct ebitmap *e, void *fp) startbit = le32_to_cpu(ebitmap_start); if (startbit & (mapunit - 1)) { - pr_err("SELinux: ebitmap start bit (%d) is " + pr_err("SELinux: ebitmap start bit (%u) is " "not a multiple of the map unit size (%u)\n", startbit, mapunit); goto bad; } if (startbit > e->highbit - mapunit) { - pr_err("SELinux: ebitmap start bit (%d) is " + pr_err("SELinux: ebitmap start bit (%u) is " "beyond the end of the bitmap (%u)\n", startbit, (e->highbit - mapunit)); goto bad; @@ -424,7 +422,8 @@ int ebitmap_read(struct ebitmap *e, void *fp) if (!n || startbit >= n->startbit + EBITMAP_SIZE) { struct ebitmap_node *tmp; - tmp = kmem_cache_zalloc(ebitmap_node_cachep, GFP_KERNEL); + tmp = kmem_cache_zalloc(ebitmap_node_cachep, + GFP_KERNEL); if (!tmp) { pr_err("SELinux: ebitmap: out of memory\n"); rc = -ENOMEM; @@ -438,8 +437,8 @@ int ebitmap_read(struct ebitmap *e, void *fp) e->node = tmp; n = tmp; } else if (startbit <= n->startbit) { - pr_err("SELinux: ebitmap: start bit %d" - " comes after start bit %d\n", + pr_err("SELinux: ebitmap: start bit %u" + " comes after start bit %u\n", startbit, n->startbit); goto bad; } @@ -450,6 +449,10 @@ int ebitmap_read(struct ebitmap *e, void *fp) goto bad; } map = le64_to_cpu(mapbits); + if (!map) { + pr_err("SELinux: ebitmap: empty map\n"); + goto bad; + } index = (startbit - n->startbit) / EBITMAP_UNIT_SIZE; while (map) { @@ -457,6 +460,13 @@ int ebitmap_read(struct ebitmap *e, void *fp) map = EBITMAP_SHIFT_UNIT_SIZE(map); } } + + if (n && n->startbit + EBITMAP_SIZE != e->highbit) { + pr_err("SELinux: ebitmap: high bit %u is not equal to the expected value %zu\n", + e->highbit, n->startbit + EBITMAP_SIZE); + goto bad; + } + ok: rc = 0; out: @@ -468,21 +478,23 @@ bad: goto out; } -int ebitmap_write(const struct ebitmap *e, void *fp) +int ebitmap_write(const struct ebitmap *e, struct policy_file *fp) { struct ebitmap_node *n; - u32 count; + u32 bit, count, last_bit, last_startbit; __le32 buf[3]; u64 map; - int bit, last_bit, last_startbit, rc; + int rc; buf[0] = cpu_to_le32(BITS_PER_U64); count = 0; last_bit = 0; - last_startbit = -1; - ebitmap_for_each_positive_bit(e, n, bit) { - if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) { + last_startbit = U32_MAX; + ebitmap_for_each_positive_bit(e, n, bit) + { + if (last_startbit == U32_MAX || + rounddown(bit, BITS_PER_U64) > last_startbit) { count++; last_startbit = rounddown(bit, BITS_PER_U64); } @@ -496,9 +508,11 @@ int ebitmap_write(const struct ebitmap *e, void *fp) return rc; map = 0; - last_startbit = INT_MIN; - ebitmap_for_each_positive_bit(e, n, bit) { - if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) { + last_startbit = U32_MAX; + ebitmap_for_each_positive_bit(e, n, bit) + { + if (last_startbit == U32_MAX || + rounddown(bit, BITS_PER_U64) > last_startbit) { __le64 buf64[1]; /* this is the very first bit */ @@ -558,7 +572,5 @@ u32 ebitmap_hash(const struct ebitmap *e, u32 hash) void __init ebitmap_cache_init(void) { - ebitmap_node_cachep = kmem_cache_create("ebitmap_node", - sizeof(struct ebitmap_node), - 0, SLAB_PANIC, NULL); + ebitmap_node_cachep = KMEM_CACHE(ebitmap_node, SLAB_PANIC); } diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h index e3c807cfad90..c9569998f287 100644 --- a/security/selinux/ss/ebitmap.h +++ b/security/selinux/ss/ebitmap.h @@ -12,23 +12,25 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #ifndef _SS_EBITMAP_H_ #define _SS_EBITMAP_H_ #include <net/netlabel.h> #ifdef CONFIG_64BIT -#define EBITMAP_NODE_SIZE 64 +#define EBITMAP_NODE_SIZE 64 #else -#define EBITMAP_NODE_SIZE 32 +#define EBITMAP_NODE_SIZE 32 #endif -#define EBITMAP_UNIT_NUMS ((EBITMAP_NODE_SIZE-sizeof(void *)-sizeof(u32))\ - / sizeof(unsigned long)) -#define EBITMAP_UNIT_SIZE BITS_PER_LONG -#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE) -#define EBITMAP_BIT 1ULL -#define EBITMAP_SHIFT_UNIT_SIZE(x) \ +#define EBITMAP_UNIT_NUMS \ + ((EBITMAP_NODE_SIZE - sizeof(void *) - sizeof(u32)) / \ + sizeof(unsigned long)) +#define EBITMAP_UNIT_SIZE BITS_PER_LONG +#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE) +#define EBITMAP_BIT 1UL +#define EBITMAP_SHIFT_UNIT_SIZE(x) \ (((x) >> EBITMAP_UNIT_SIZE / 2) >> EBITMAP_UNIT_SIZE / 2) struct ebitmap_node { @@ -38,16 +40,16 @@ struct ebitmap_node { }; struct ebitmap { - struct ebitmap_node *node; /* first node in the bitmap */ - u32 highbit; /* highest position in the total bitmap */ + struct ebitmap_node *node; /* first node in the bitmap */ + u32 highbit; /* highest position in the total bitmap */ }; #define ebitmap_length(e) ((e)->highbit) -static inline unsigned int ebitmap_start_positive(const struct ebitmap *e, - struct ebitmap_node **n) +static inline u32 ebitmap_start_positive(const struct ebitmap *e, + struct ebitmap_node **n) { - unsigned int ofs; + u32 ofs; for (*n = e->node; *n; *n = (*n)->next) { ofs = find_first_bit((*n)->maps, EBITMAP_SIZE); @@ -62,11 +64,10 @@ static inline void ebitmap_init(struct ebitmap *e) memset(e, 0, sizeof(*e)); } -static inline unsigned int ebitmap_next_positive(const struct ebitmap *e, - struct ebitmap_node **n, - unsigned int bit) +static inline u32 ebitmap_next_positive(const struct ebitmap *e, + struct ebitmap_node **n, u32 bit) { - unsigned int ofs; + u32 ofs; ofs = find_next_bit((*n)->maps, EBITMAP_SIZE, bit - (*n)->startbit + 1); if (ofs < EBITMAP_SIZE) @@ -80,16 +81,15 @@ static inline unsigned int ebitmap_next_positive(const struct ebitmap *e, return ebitmap_length(e); } -#define EBITMAP_NODE_INDEX(node, bit) \ +#define EBITMAP_NODE_INDEX(node, bit) \ (((bit) - (node)->startbit) / EBITMAP_UNIT_SIZE) -#define EBITMAP_NODE_OFFSET(node, bit) \ +#define EBITMAP_NODE_OFFSET(node, bit) \ (((bit) - (node)->startbit) % EBITMAP_UNIT_SIZE) -static inline int ebitmap_node_get_bit(const struct ebitmap_node *n, - unsigned int bit) +static inline int ebitmap_node_get_bit(const struct ebitmap_node *n, u32 bit) { - unsigned int index = EBITMAP_NODE_INDEX(n, bit); - unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit); + u32 index = EBITMAP_NODE_INDEX(n, bit); + u32 ofs = EBITMAP_NODE_OFFSET(n, bit); BUG_ON(index >= EBITMAP_UNIT_NUMS); if ((n->maps[index] & (EBITMAP_BIT << ofs))) @@ -97,40 +97,41 @@ static inline int ebitmap_node_get_bit(const struct ebitmap_node *n, return 0; } -static inline void ebitmap_node_set_bit(struct ebitmap_node *n, - unsigned int bit) +static inline void ebitmap_node_set_bit(struct ebitmap_node *n, u32 bit) { - unsigned int index = EBITMAP_NODE_INDEX(n, bit); - unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit); + u32 index = EBITMAP_NODE_INDEX(n, bit); + u32 ofs = EBITMAP_NODE_OFFSET(n, bit); BUG_ON(index >= EBITMAP_UNIT_NUMS); n->maps[index] |= (EBITMAP_BIT << ofs); } -static inline void ebitmap_node_clr_bit(struct ebitmap_node *n, - unsigned int bit) +static inline void ebitmap_node_clr_bit(struct ebitmap_node *n, u32 bit) { - unsigned int index = EBITMAP_NODE_INDEX(n, bit); - unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit); + u32 index = EBITMAP_NODE_INDEX(n, bit); + u32 ofs = EBITMAP_NODE_OFFSET(n, bit); BUG_ON(index >= EBITMAP_UNIT_NUMS); n->maps[index] &= ~(EBITMAP_BIT << ofs); } -#define ebitmap_for_each_positive_bit(e, n, bit) \ - for ((bit) = ebitmap_start_positive(e, &(n)); \ - (bit) < ebitmap_length(e); \ - (bit) = ebitmap_next_positive(e, &(n), bit)) \ +#define ebitmap_for_each_positive_bit(e, n, bit) \ + for ((bit) = ebitmap_start_positive(e, &(n)); \ + (bit) < ebitmap_length(e); \ + (bit) = ebitmap_next_positive(e, &(n), bit)) -int ebitmap_cmp(const struct ebitmap *e1, const struct ebitmap *e2); +bool ebitmap_equal(const struct ebitmap *e1, const struct ebitmap *e2); int ebitmap_cpy(struct ebitmap *dst, const struct ebitmap *src); -int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1, const struct ebitmap *e2); -int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2, u32 last_e2bit); -int ebitmap_get_bit(const struct ebitmap *e, unsigned long bit); -int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); +int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1, + const struct ebitmap *e2); +int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2, + u32 last_e2bit); +int ebitmap_get_bit(const struct ebitmap *e, u32 bit); +int ebitmap_set_bit(struct ebitmap *e, u32 bit, int value); void ebitmap_destroy(struct ebitmap *e); -int ebitmap_read(struct ebitmap *e, void *fp); -int ebitmap_write(const struct ebitmap *e, void *fp); +struct policy_file; +int ebitmap_read(struct ebitmap *e, struct policy_file *fp); +int ebitmap_write(const struct ebitmap *e, struct policy_file *fp); u32 ebitmap_hash(const struct ebitmap *e, u32 hash); #ifdef CONFIG_NETLABEL @@ -151,4 +152,4 @@ static inline int ebitmap_netlbl_import(struct ebitmap *ebmap, } #endif -#endif /* _SS_EBITMAP_H_ */ +#endif /* _SS_EBITMAP_H_ */ diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index c05d8346a94a..383fd2d70878 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -4,6 +4,7 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #include <linux/kernel.h> #include <linux/slab.h> #include <linux/errno.h> @@ -47,8 +48,8 @@ int hashtab_init(struct hashtab *h, u32 nel_hint) return 0; } -int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, - void *key, void *datum) +int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, void *key, + void *datum) { struct hashtab_node *newnode; @@ -83,8 +84,7 @@ void hashtab_destroy(struct hashtab *h) h->htable = NULL; } -int hashtab_map(struct hashtab *h, - int (*apply)(void *k, void *d, void *args), +int hashtab_map(struct hashtab *h, int (*apply)(void *k, void *d, void *args), void *args) { u32 i; @@ -136,12 +136,12 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info) } #endif /* CONFIG_SECURITY_SELINUX_DEBUG */ -int hashtab_duplicate(struct hashtab *new, struct hashtab *orig, - int (*copy)(struct hashtab_node *new, - struct hashtab_node *orig, void *args), - int (*destroy)(void *k, void *d, void *args), - void *args) +int hashtab_duplicate(struct hashtab *new, const struct hashtab *orig, + int (*copy)(struct hashtab_node *new, + const struct hashtab_node *orig, void *args), + int (*destroy)(void *k, void *d, void *args), void *args) { + const struct hashtab_node *orig_cur; struct hashtab_node *cur, *tmp, *tail; u32 i; int rc; @@ -156,12 +156,13 @@ int hashtab_duplicate(struct hashtab *new, struct hashtab *orig, for (i = 0; i < orig->size; i++) { tail = NULL; - for (cur = orig->htable[i]; cur; cur = cur->next) { + for (orig_cur = orig->htable[i]; orig_cur; + orig_cur = orig_cur->next) { tmp = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL); if (!tmp) goto error; - rc = copy(tmp, cur, args); + rc = copy(tmp, orig_cur, args); if (rc) { kmem_cache_free(hashtab_node_cachep, tmp); goto error; @@ -178,7 +179,7 @@ int hashtab_duplicate(struct hashtab *new, struct hashtab *orig, return 0; - error: +error: for (i = 0; i < new->size; i++) { for (cur = new->htable[i]; cur; cur = tmp) { tmp = cur->next; @@ -193,7 +194,5 @@ int hashtab_duplicate(struct hashtab *new, struct hashtab *orig, void __init hashtab_cache_init(void) { - hashtab_node_cachep = kmem_cache_create("hashtab_node", - sizeof(struct hashtab_node), - 0, SLAB_PANIC, NULL); + hashtab_node_cachep = KMEM_CACHE(hashtab_node, SLAB_PANIC); } diff --git a/security/selinux/ss/hashtab.h b/security/selinux/ss/hashtab.h index 09b0a3744937..deba82d78c3a 100644 --- a/security/selinux/ss/hashtab.h +++ b/security/selinux/ss/hashtab.h @@ -8,6 +8,7 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #ifndef _SS_HASHTAB_H_ #define _SS_HASHTAB_H_ @@ -15,12 +16,11 @@ #include <linux/errno.h> #include <linux/sched.h> -#define HASHTAB_MAX_NODES U32_MAX +#define HASHTAB_MAX_NODES U32_MAX struct hashtab_key_params { - u32 (*hash)(const void *key); /* hash function */ - int (*cmp)(const void *key1, const void *key2); - /* key comparison function */ + u32 (*hash)(const void *key); /* hash func */ + int (*cmp)(const void *key1, const void *key2); /* comparison func */ }; struct hashtab_node { @@ -30,9 +30,9 @@ struct hashtab_node { }; struct hashtab { - struct hashtab_node **htable; /* hash table */ - u32 size; /* number of slots in hash table */ - u32 nel; /* number of elements in hash table */ + struct hashtab_node **htable; /* hash table */ + u32 size; /* number of slots in hash table */ + u32 nel; /* number of elements in hash table */ }; struct hashtab_info { @@ -48,8 +48,8 @@ struct hashtab_info { */ int hashtab_init(struct hashtab *h, u32 nel_hint); -int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, - void *key, void *datum); +int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, void *key, + void *datum); /* * Inserts the specified (key, datum) pair into the specified hash table. @@ -84,8 +84,8 @@ static inline int hashtab_insert(struct hashtab *h, void *key, void *datum, cur = cur->next; } - return __hashtab_insert(h, prev ? &prev->next : &h->htable[hvalue], - key, datum); + return __hashtab_insert(h, prev ? &prev->next : &h->htable[hvalue], key, + datum); } /* @@ -133,15 +133,13 @@ void hashtab_destroy(struct hashtab *h); * iterating through the hash table and will propagate the error * return to its caller. */ -int hashtab_map(struct hashtab *h, - int (*apply)(void *k, void *d, void *args), +int hashtab_map(struct hashtab *h, int (*apply)(void *k, void *d, void *args), void *args); -int hashtab_duplicate(struct hashtab *new, struct hashtab *orig, - int (*copy)(struct hashtab_node *new, - struct hashtab_node *orig, void *args), - int (*destroy)(void *k, void *d, void *args), - void *args); +int hashtab_duplicate(struct hashtab *new, const struct hashtab *orig, + int (*copy)(struct hashtab_node *new, + const struct hashtab_node *orig, void *args), + int (*destroy)(void *k, void *d, void *args), void *args); #ifdef CONFIG_SECURITY_SELINUX_DEBUG /* Fill info with some hash table statistics */ @@ -149,7 +147,8 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info); #else static inline void hashtab_stat(struct hashtab *h, struct hashtab_info *info) { + return; } #endif -#endif /* _SS_HASHTAB_H */ +#endif /* _SS_HASHTAB_H */ diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index cd38f5913b63..a6e49269f535 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -4,19 +4,15 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + /* * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> + * Support for enhanced MLS infrastructure. + * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. * - * Support for enhanced MLS infrastructure. - * - * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. - */ -/* * Updated: Hewlett-Packard <paul@paul-moore.com> - * - * Added support to import/export the MLS label from NetLabel - * - * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 + * Added support to import/export the MLS label from NetLabel + * Copyright (C) Hewlett-Packard Development Company, L.P., 2006 */ #include <linux/kernel.h> @@ -52,7 +48,8 @@ int mls_compute_context_len(struct policydb *p, struct context *context) head = -2; prev = -2; e = &context->range.level[l].cat; - ebitmap_for_each_positive_bit(e, node, i) { + ebitmap_for_each_positive_bit(e, node, i) + { if (i - prev > 1) { /* one or more negative bits are skipped */ if (head != prev) { @@ -86,8 +83,7 @@ int mls_compute_context_len(struct policydb *p, struct context *context) * the MLS fields of `context' into the string `*scontext'. * Update `*scontext' to point to the end of the MLS fields. */ -void mls_sid_to_context(struct policydb *p, - struct context *context, +void mls_sid_to_context(struct policydb *p, struct context *context, char **scontext) { char *scontextp, *nm; @@ -112,7 +108,8 @@ void mls_sid_to_context(struct policydb *p, head = -2; prev = -2; e = &context->range.level[l].cat; - ebitmap_for_each_positive_bit(e, node, i) { + ebitmap_for_each_positive_bit(e, node, i) + { if (i - prev > 1) { /* one or more negative bits are skipped */ if (prev != head) { @@ -174,7 +171,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l) * levdatum->level->cat and no bit in l->cat is larger than * p->p_cats.nprim. */ - return ebitmap_contains(&levdatum->level->cat, &l->cat, + return ebitmap_contains(&levdatum->level.cat, &l->cat, p->p_cats.nprim); } @@ -230,12 +227,8 @@ int mls_context_isvalid(struct policydb *p, struct context *c) * Policy read-lock must be held for sidtab lookup. * */ -int mls_context_to_sid(struct policydb *pol, - char oldc, - char *scontext, - struct context *context, - struct sidtab *s, - u32 def_sid) +int mls_context_to_sid(struct policydb *pol, char oldc, char *scontext, + struct context *context, struct sidtab *s, u32 def_sid) { char *sensitivity, *cur_cat, *next_cat, *rngptr; struct level_datum *levdatum; @@ -296,7 +289,7 @@ int mls_context_to_sid(struct policydb *pol, levdatum = symtab_search(&pol->p_levels, sensitivity); if (!levdatum) return -EINVAL; - context->range.level[l].sens = levdatum->level->sens; + context->range.level[l].sens = levdatum->level.sens; /* Extract category set. */ while (next_cat != NULL) { @@ -333,7 +326,8 @@ int mls_context_to_sid(struct policydb *pol, return -EINVAL; for (i = catdatum->value; i < rngdatum->value; i++) { - rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1); + rc = ebitmap_set_bit( + &context->range.level[l].cat, i, 1); if (rc) return rc; } @@ -371,8 +365,8 @@ int mls_from_string(struct policydb *p, char *str, struct context *context, if (!tmpstr) { rc = -ENOMEM; } else { - rc = mls_context_to_sid(p, ':', tmpstr, context, - NULL, SECSID_NULL); + rc = mls_context_to_sid(p, ':', tmpstr, context, NULL, + SECSID_NULL); kfree(tmpstr); } @@ -382,8 +376,7 @@ int mls_from_string(struct policydb *p, char *str, struct context *context, /* * Copies the MLS range `range' into `context'. */ -int mls_range_set(struct context *context, - struct mls_range *range) +int mls_range_set(struct context *context, struct mls_range *range) { int l, rc = 0; @@ -399,9 +392,8 @@ int mls_range_set(struct context *context, return rc; } -int mls_setup_user_range(struct policydb *p, - struct context *fromcon, struct user_datum *user, - struct context *usercon) +int mls_setup_user_range(struct policydb *p, struct context *fromcon, + struct user_datum *user, struct context *usercon) { if (p->mls_enabled) { struct mls_level *fromcon_sen = &(fromcon->range.level[0]); @@ -444,10 +436,8 @@ int mls_setup_user_range(struct policydb *p, * policy `oldp' to the values specified in the policy `newp', * storing the resulting context in `newc'. */ -int mls_convert_context(struct policydb *oldp, - struct policydb *newp, - struct context *oldc, - struct context *newc) +int mls_convert_context(struct policydb *oldp, struct policydb *newp, + struct context *oldc, struct context *newc) { struct level_datum *levdatum; struct cat_datum *catdatum; @@ -466,10 +456,11 @@ int mls_convert_context(struct policydb *oldp, if (!levdatum) return -EINVAL; - newc->range.level[l].sens = levdatum->level->sens; + newc->range.level[l].sens = levdatum->level.sens; - ebitmap_for_each_positive_bit(&oldc->range.level[l].cat, - node, i) { + ebitmap_for_each_positive_bit(&oldc->range.level[l].cat, node, + i) + { int rc; catdatum = symtab_search(&newp->p_cats, @@ -486,13 +477,9 @@ int mls_convert_context(struct policydb *oldp, return 0; } -int mls_compute_sid(struct policydb *p, - struct context *scontext, - struct context *tcontext, - u16 tclass, - u32 specified, - struct context *newcontext, - bool sock) +int mls_compute_sid(struct policydb *p, struct context *scontext, + struct context *tcontext, u16 tclass, u32 specified, + struct context *newcontext, bool sock) { struct range_trans rtr; struct mls_range *r; @@ -532,8 +519,8 @@ int mls_compute_sid(struct policydb *p, case DEFAULT_TARGET_LOW_HIGH: return mls_context_cpy(newcontext, tcontext); case DEFAULT_GLBLUB: - return mls_context_glblub(newcontext, - scontext, tcontext); + return mls_context_glblub(newcontext, scontext, + tcontext); } fallthrough; @@ -563,8 +550,7 @@ int mls_compute_sid(struct policydb *p, * NetLabel MLS sensitivity level field. * */ -void mls_export_netlbl_lvl(struct policydb *p, - struct context *context, +void mls_export_netlbl_lvl(struct policydb *p, struct context *context, struct netlbl_lsm_secattr *secattr) { if (!p->mls_enabled) @@ -585,8 +571,7 @@ void mls_export_netlbl_lvl(struct policydb *p, * NetLabel MLS sensitivity level into the context. * */ -void mls_import_netlbl_lvl(struct policydb *p, - struct context *context, +void mls_import_netlbl_lvl(struct policydb *p, struct context *context, struct netlbl_lsm_secattr *secattr) { if (!p->mls_enabled) @@ -607,8 +592,7 @@ void mls_import_netlbl_lvl(struct policydb *p, * MLS category field. Returns zero on success, negative values on failure. * */ -int mls_export_netlbl_cat(struct policydb *p, - struct context *context, +int mls_export_netlbl_cat(struct policydb *p, struct context *context, struct netlbl_lsm_secattr *secattr) { int rc; @@ -637,8 +621,7 @@ int mls_export_netlbl_cat(struct policydb *p, * negative values on failure. * */ -int mls_import_netlbl_cat(struct policydb *p, - struct context *context, +int mls_import_netlbl_cat(struct policydb *p, struct context *context, struct netlbl_lsm_secattr *secattr) { int rc; diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 107681dd1824..07980636751f 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -4,19 +4,15 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + /* * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> + * Support for enhanced MLS infrastructure. + * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. * - * Support for enhanced MLS infrastructure. - * - * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. - */ -/* * Updated: Hewlett-Packard <paul@paul-moore.com> - * - * Added support to import/export the MLS label from NetLabel - * - * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 + * Added support to import/export the MLS label from NetLabel + * Copyright (X) Hewlett-Packard Development Company, L.P., 2006 */ #ifndef _SS_MLS_H_ @@ -35,47 +31,32 @@ int mls_context_isvalid(struct policydb *p, struct context *c); int mls_range_isvalid(struct policydb *p, struct mls_range *r); int mls_level_isvalid(struct policydb *p, struct mls_level *l); -int mls_context_to_sid(struct policydb *p, - char oldc, - char *scontext, - struct context *context, - struct sidtab *s, - u32 def_sid); +int mls_context_to_sid(struct policydb *p, char oldc, char *scontext, + struct context *context, struct sidtab *s, u32 def_sid); int mls_from_string(struct policydb *p, char *str, struct context *context, gfp_t gfp_mask); int mls_range_set(struct context *context, struct mls_range *range); -int mls_convert_context(struct policydb *oldp, - struct policydb *newp, - struct context *oldc, - struct context *newc); +int mls_convert_context(struct policydb *oldp, struct policydb *newp, + struct context *oldc, struct context *newc); -int mls_compute_sid(struct policydb *p, - struct context *scontext, - struct context *tcontext, - u16 tclass, - u32 specified, - struct context *newcontext, - bool sock); +int mls_compute_sid(struct policydb *p, struct context *scontext, + struct context *tcontext, u16 tclass, u32 specified, + struct context *newcontext, bool sock); -int mls_setup_user_range(struct policydb *p, - struct context *fromcon, struct user_datum *user, - struct context *usercon); +int mls_setup_user_range(struct policydb *p, struct context *fromcon, + struct user_datum *user, struct context *usercon); #ifdef CONFIG_NETLABEL -void mls_export_netlbl_lvl(struct policydb *p, - struct context *context, +void mls_export_netlbl_lvl(struct policydb *p, struct context *context, struct netlbl_lsm_secattr *secattr); -void mls_import_netlbl_lvl(struct policydb *p, - struct context *context, +void mls_import_netlbl_lvl(struct policydb *p, struct context *context, struct netlbl_lsm_secattr *secattr); -int mls_export_netlbl_cat(struct policydb *p, - struct context *context, +int mls_export_netlbl_cat(struct policydb *p, struct context *context, struct netlbl_lsm_secattr *secattr); -int mls_import_netlbl_cat(struct policydb *p, - struct context *context, +int mls_import_netlbl_cat(struct policydb *p, struct context *context, struct netlbl_lsm_secattr *secattr); #else static inline void mls_export_netlbl_lvl(struct policydb *p, @@ -112,5 +93,4 @@ static inline u32 mls_range_hash(const struct mls_range *r, u32 hash) return hash; } -#endif /* _SS_MLS_H */ - +#endif /* _SS_MLS_H */ diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h index f492cf148891..51df2ebd1211 100644 --- a/security/selinux/ss/mls_types.h +++ b/security/selinux/ss/mls_types.h @@ -4,12 +4,11 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + /* * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> - * - * Support for enhanced MLS infrastructure. - * - * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Support for enhanced MLS infrastructure. + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. */ #ifndef _SS_MLS_TYPES_H_ @@ -19,34 +18,35 @@ #include "ebitmap.h" struct mls_level { - u32 sens; /* sensitivity */ - struct ebitmap cat; /* category set */ + u32 sens; /* sensitivity */ + struct ebitmap cat; /* category set */ }; struct mls_range { struct mls_level level[2]; /* low == level[0], high == level[1] */ }; -static inline int mls_level_eq(const struct mls_level *l1, const struct mls_level *l2) +static inline int mls_level_eq(const struct mls_level *l1, + const struct mls_level *l2) { - return ((l1->sens == l2->sens) && - ebitmap_cmp(&l1->cat, &l2->cat)); + return ((l1->sens == l2->sens) && ebitmap_equal(&l1->cat, &l2->cat)); } -static inline int mls_level_dom(const struct mls_level *l1, const struct mls_level *l2) +static inline int mls_level_dom(const struct mls_level *l1, + const struct mls_level *l2) { return ((l1->sens >= l2->sens) && ebitmap_contains(&l1->cat, &l2->cat, 0)); } #define mls_level_incomp(l1, l2) \ -(!mls_level_dom((l1), (l2)) && !mls_level_dom((l2), (l1))) + (!mls_level_dom((l1), (l2)) && !mls_level_dom((l2), (l1))) #define mls_level_between(l1, l2, l3) \ -(mls_level_dom((l1), (l2)) && mls_level_dom((l3), (l1))) + (mls_level_dom((l1), (l2)) && mls_level_dom((l3), (l1))) -#define mls_range_contains(r1, r2) \ -(mls_level_dom(&(r2).level[0], &(r1).level[0]) && \ - mls_level_dom(&(r1).level[1], &(r2).level[1])) +#define mls_range_contains(r1, r2) \ + (mls_level_dom(&(r2).level[0], &(r1).level[0]) && \ + mls_level_dom(&(r1).level[1], &(r2).level[1])) -#endif /* _SS_MLS_TYPES_H_ */ +#endif /* _SS_MLS_TYPES_H_ */ diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 3b19ad28c922..9ea971943713 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -7,25 +7,21 @@ /* * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> + * Support for enhanced MLS infrastructure. + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * - * Support for enhanced MLS infrastructure. - * - * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> - * - * Added conditional policy language extensions + * Updated: Frank Mayer <mayerf@tresys.com> and + * Karl MacMillan <kmacmillan@tresys.com> + * Added conditional policy language extensions + * Copyright (C) 2003-2004 Tresys Technology, LLC * * Updated: Hewlett-Packard <paul@paul-moore.com> - * - * Added support for the policy capability bitmap + * Added support for the policy capability bitmap + * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. * * Update: Mellanox Techonologies - * - * Added Infiniband support - * - * Copyright (C) 2016 Mellanox Techonologies - * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. - * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. - * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * Added Infiniband support + * Copyright (C) 2016 Mellanox Techonologies */ #include <linux/kernel.h> @@ -42,6 +38,7 @@ #include "services.h" #ifdef CONFIG_SECURITY_SELINUX_DEBUG +/* clang-format off */ static const char *const symtab_name[SYM_NUM] = { "common prefixes", "classes", @@ -52,6 +49,7 @@ static const char *const symtab_name[SYM_NUM] = { "levels", "categories", }; +/* clang-format off */ #endif struct policydb_compat_info { @@ -63,103 +61,109 @@ struct policydb_compat_info { /* These need to be updated if SYM_NUM or OCON_NUM changes */ static const struct policydb_compat_info policydb_compat[] = { { - .version = POLICYDB_VERSION_BASE, - .sym_num = SYM_NUM - 3, - .ocon_num = OCON_NUM - 3, + .version = POLICYDB_VERSION_BASE, + .sym_num = SYM_NUM - 3, + .ocon_num = OCON_NUM - 3, }, { - .version = POLICYDB_VERSION_BOOL, - .sym_num = SYM_NUM - 2, - .ocon_num = OCON_NUM - 3, + .version = POLICYDB_VERSION_BOOL, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_NUM - 3, }, { - .version = POLICYDB_VERSION_IPV6, - .sym_num = SYM_NUM - 2, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_IPV6, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_NLCLASS, - .sym_num = SYM_NUM - 2, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_NLCLASS, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_MLS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_MLS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_AVTAB, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_AVTAB, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_RANGETRANS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_RANGETRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_POLCAP, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_POLCAP, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_PERMISSIVE, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_PERMISSIVE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_BOUNDARY, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_BOUNDARY, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_FILENAME_TRANS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_FILENAME_TRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_ROLETRANS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_ROLETRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_DEFAULT_TYPE, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_DEFAULT_TYPE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_CONSTRAINT_NAMES, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_CONSTRAINT_NAMES, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_XPERMS_IOCTL, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM - 2, + .version = POLICYDB_VERSION_XPERMS_IOCTL, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM - 2, }, { - .version = POLICYDB_VERSION_INFINIBAND, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, + .version = POLICYDB_VERSION_INFINIBAND, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, }, { - .version = POLICYDB_VERSION_GLBLUB, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, + .version = POLICYDB_VERSION_GLBLUB, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, }, { - .version = POLICYDB_VERSION_COMP_FTRANS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, + .version = POLICYDB_VERSION_COMP_FTRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, + }, + { + .version = POLICYDB_VERSION_COND_XPERMS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, }, }; -static const struct policydb_compat_info *policydb_lookup_compat(unsigned int version) +static const struct policydb_compat_info * +policydb_lookup_compat(unsigned int version) { unsigned int i; @@ -297,9 +301,7 @@ static int sens_destroy(void *key, void *datum, void *p) kfree(key); if (datum) { levdatum = datum; - if (levdatum->level) - ebitmap_destroy(&levdatum->level->cat); - kfree(levdatum->level); + ebitmap_destroy(&levdatum->level.cat); } kfree(datum); return 0; @@ -312,7 +314,8 @@ static int cat_destroy(void *key, void *datum, void *p) return 0; } -static int (*const destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) = { +/* clang-format off */ +static int (*const destroy_f[SYM_NUM])(void *key, void *datum, void *datap) = { common_destroy, cls_destroy, role_destroy, @@ -322,6 +325,7 @@ static int (*const destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) = { sens_destroy, cat_destroy, }; +/* clang-format on */ static int filenametr_destroy(void *key, void *datum, void *p) { @@ -366,8 +370,8 @@ static void ocontext_destroy(struct ocontext *c, unsigned int i) context_destroy(&c->context[0]); context_destroy(&c->context[1]); - if (i == OCON_ISID || i == OCON_FS || - i == OCON_NETIF || i == OCON_FSUSE) + if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF || + i == OCON_FSUSE) kfree(c->u.name); kfree(c); } @@ -429,7 +433,6 @@ static int filenametr_cmp(const void *k1, const void *k2) return v; return strcmp(ft1->name, ft2->name); - } static const struct hashtab_key_params filenametr_key_params = { @@ -437,8 +440,8 @@ static const struct hashtab_key_params filenametr_key_params = { .cmp = filenametr_cmp, }; -struct filename_trans_datum *policydb_filenametr_search( - struct policydb *p, struct filename_trans_key *key) +struct filename_trans_datum * +policydb_filenametr_search(struct policydb *p, struct filename_trans_key *key) { return hashtab_search(&p->filename_trans, key, filenametr_key_params); } @@ -448,7 +451,7 @@ static u32 rangetr_hash(const void *k) const struct range_trans *key = k; return key->source_type + (key->target_type << 3) + - (key->target_class << 5); + (key->target_class << 5); } static int rangetr_cmp(const void *k1, const void *k2) @@ -484,7 +487,8 @@ static u32 role_trans_hash(const void *k) { const struct role_trans_key *key = k; - return jhash_3words(key->role, key->type, (u32)key->tclass << 16 | key->tclass, 0); + return jhash_3words(key->role, key->type, + (u32)key->tclass << 16 | key->tclass, 0); } static int role_trans_cmp(const void *k1, const void *k2) @@ -576,9 +580,8 @@ static int role_index(void *key, void *datum, void *datap) role = datum; p = datap; - if (!role->value - || role->value > p->p_roles.nprim - || role->bounds > p->p_roles.nprim) + if (!role->value || role->value > p->p_roles.nprim || + role->bounds > p->p_roles.nprim) return -EINVAL; p->sym_val_to_name[SYM_ROLES][role->value - 1] = key; @@ -595,9 +598,8 @@ static int type_index(void *key, void *datum, void *datap) p = datap; if (typdatum->primary) { - if (!typdatum->value - || typdatum->value > p->p_types.nprim - || typdatum->bounds > p->p_types.nprim) + if (!typdatum->value || typdatum->value > p->p_types.nprim || + typdatum->bounds > p->p_types.nprim) return -EINVAL; p->sym_val_to_name[SYM_TYPES][typdatum->value - 1] = key; p->type_val_to_struct[typdatum->value - 1] = typdatum; @@ -613,9 +615,8 @@ static int user_index(void *key, void *datum, void *datap) usrdatum = datum; p = datap; - if (!usrdatum->value - || usrdatum->value > p->p_users.nprim - || usrdatum->bounds > p->p_users.nprim) + if (!usrdatum->value || usrdatum->value > p->p_users.nprim || + usrdatum->bounds > p->p_users.nprim) return -EINVAL; p->sym_val_to_name[SYM_USERS][usrdatum->value - 1] = key; @@ -632,11 +633,11 @@ static int sens_index(void *key, void *datum, void *datap) p = datap; if (!levdatum->isalias) { - if (!levdatum->level->sens || - levdatum->level->sens > p->p_levels.nprim) + if (!levdatum->level.sens || + levdatum->level.sens > p->p_levels.nprim) return -EINVAL; - p->sym_val_to_name[SYM_LEVELS][levdatum->level->sens - 1] = key; + p->sym_val_to_name[SYM_LEVELS][levdatum->level.sens - 1] = key; } return 0; @@ -660,7 +661,8 @@ static int cat_index(void *key, void *datum, void *datap) return 0; } -static int (*const index_f[SYM_NUM]) (void *key, void *datum, void *datap) = { +/* clang-format off */ +static int (*const index_f[SYM_NUM])(void *key, void *datum, void *datap) = { common_index, class_index, role_index, @@ -670,16 +672,20 @@ static int (*const index_f[SYM_NUM]) (void *key, void *datum, void *datap) = { sens_index, cat_index, }; +/* 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, info.chain2_len_sum); + pr_debug( + "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); } static void symtab_hash_eval(struct symtab *s) @@ -687,11 +693,12 @@ 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) @@ -710,16 +717,17 @@ static int policydb_index(struct policydb *p) int i, rc; if (p->mls_enabled) - pr_debug("SELinux: %d users, %d roles, %d types, %d bools, %d sens, %d cats\n", - p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, - p->p_bools.nprim, p->p_levels.nprim, p->p_cats.nprim); + pr_debug( + "SELinux: %d users, %d roles, %d types, %d bools, %d sens, %d cats\n", + p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, + p->p_bools.nprim, p->p_levels.nprim, p->p_cats.nprim); else pr_debug("SELinux: %d users, %d roles, %d types, %d bools\n", p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); - pr_debug("SELinux: %d classes, %d rules\n", - p->p_classes.nprim, p->te_avtab.nel); + pr_debug("SELinux: %d classes, %d rules\n", p->p_classes.nprim, + p->te_avtab.nel); avtab_hash_eval(&p->te_avtab, "rules"); symtab_hash_eval(p->symtab); @@ -730,21 +738,18 @@ static int policydb_index(struct policydb *p) if (!p->class_val_to_struct) return -ENOMEM; - p->role_val_to_struct = kcalloc(p->p_roles.nprim, - sizeof(*p->role_val_to_struct), - GFP_KERNEL); + p->role_val_to_struct = kcalloc( + p->p_roles.nprim, sizeof(*p->role_val_to_struct), GFP_KERNEL); if (!p->role_val_to_struct) return -ENOMEM; - p->user_val_to_struct = kcalloc(p->p_users.nprim, - sizeof(*p->user_val_to_struct), - GFP_KERNEL); + p->user_val_to_struct = kcalloc( + p->p_users.nprim, sizeof(*p->user_val_to_struct), GFP_KERNEL); if (!p->user_val_to_struct) return -ENOMEM; - p->type_val_to_struct = kvcalloc(p->p_types.nprim, - sizeof(*p->type_val_to_struct), - GFP_KERNEL); + p->type_val_to_struct = kvcalloc( + p->p_types.nprim, sizeof(*p->type_val_to_struct), GFP_KERNEL); if (!p->type_val_to_struct) return -ENOMEM; @@ -754,8 +759,7 @@ static int policydb_index(struct policydb *p) for (i = 0; i < SYM_NUM; i++) { p->sym_val_to_name[i] = kvcalloc(p->symtab[i].nprim, - sizeof(char *), - GFP_KERNEL); + sizeof(char *), GFP_KERNEL); if (!p->sym_val_to_name[i]) return -ENOMEM; @@ -857,8 +861,7 @@ void policydb_destroy(struct policydb *p) int policydb_load_isids(struct policydb *p, struct sidtab *s) { struct ocontext *head, *c; - bool isid_init_supported = ebitmap_get_bit(&p->policycaps, - POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT); + bool isid_init; int rc; rc = sidtab_init(s); @@ -867,6 +870,9 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) return rc; } + isid_init = ebitmap_get_bit(&p->policycaps, + POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT); + head = p->ocontexts[OCON_ISID]; for (c = head; c; c = c->next) { u32 sid = c->sid[0]; @@ -886,7 +892,7 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) * Also ignore SECINITSID_INIT if the policy doesn't declare * support for it */ - if (sid == SECINITSID_INIT && !isid_init_supported) + if (sid == SECINITSID_INIT && !isid_init) continue; rc = sidtab_set_initial(s, sid, &c->context[0]); @@ -905,8 +911,9 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) * started before policy load would initially get the context * corresponding to SECINITSID_KERNEL. */ - if (sid == SECINITSID_KERNEL && !isid_init_supported) { - rc = sidtab_set_initial(s, SECINITSID_INIT, &c->context[0]); + if (sid == SECINITSID_KERNEL && !isid_init) { + rc = sidtab_set_initial(s, SECINITSID_INIT, + &c->context[0]); if (rc) { pr_err("SELinux: unable to load initial SID %s.\n", name); @@ -988,7 +995,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c) * Read a MLS range structure from a policydb binary * representation file. */ -static int mls_read_range_helper(struct mls_range *r, void *fp) +static int mls_read_range_helper(struct mls_range *r, struct policy_file *fp) { __le32 buf[2]; u32 items; @@ -1047,9 +1054,8 @@ out: * Read and validate a security context structure * from a policydb binary representation file. */ -static int context_read_and_validate(struct context *c, - struct policydb *p, - void *fp) +static int context_read_and_validate(struct context *c, struct policydb *p, + struct policy_file *fp) { __le32 buf[3]; int rc; @@ -1087,7 +1093,7 @@ out: * binary representation file. */ -static int str_read(char **strp, gfp_t flags, void *fp, u32 len) +int str_read(char **strp, gfp_t flags, struct policy_file *fp, u32 len) { int rc; char *str; @@ -1110,7 +1116,7 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len) return 0; } -static int perm_read(struct policydb *p, struct symtab *s, void *fp) +static int perm_read(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct perm_datum *perdatum; @@ -1143,7 +1149,7 @@ bad: return rc; } -static int common_read(struct policydb *p, struct symtab *s, void *fp) +static int common_read(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct common_datum *comdatum; @@ -1178,6 +1184,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; @@ -1193,7 +1201,7 @@ static void type_set_init(struct type_set *t) ebitmap_init(&t->negset); } -static int type_set_read(struct type_set *t, void *fp) +static int type_set_read(struct type_set *t, struct policy_file *fp) { __le32 buf[1]; int rc; @@ -1211,10 +1219,8 @@ static int type_set_read(struct type_set *t, void *fp) return 0; } - -static int read_cons_helper(struct policydb *p, - struct constraint_node **nodep, - u32 ncons, int allowxtarget, void *fp) +static int read_cons_helper(struct policydb *p, struct constraint_node **nodep, + u32 ncons, int allowxtarget, struct policy_file *fp) { struct constraint_node *c, *lc; struct constraint_expr *e, *le; @@ -1284,8 +1290,9 @@ static int read_cons_helper(struct policydb *p, return rc; if (p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) { - e->type_names = kzalloc(sizeof - (*e->type_names), GFP_KERNEL); + e->type_names = + kzalloc(sizeof(*e->type_names), + GFP_KERNEL); if (!e->type_names) return -ENOMEM; type_set_init(e->type_names); @@ -1307,7 +1314,7 @@ static int read_cons_helper(struct policydb *p, return 0; } -static int class_read(struct policydb *p, struct symtab *s, void *fp) +static int class_read(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct class_datum *cladatum; @@ -1319,7 +1326,7 @@ static int class_read(struct policydb *p, struct symtab *s, void *fp) if (!cladatum) return -ENOMEM; - rc = next_entry(buf, fp, sizeof(u32)*6); + rc = next_entry(buf, fp, sizeof(u32) * 6); if (rc) goto bad; @@ -1345,8 +1352,8 @@ static int class_read(struct policydb *p, struct symtab *s, void *fp) goto bad; rc = -EINVAL; - cladatum->comdatum = symtab_search(&p->p_commons, - cladatum->comkey); + cladatum->comdatum = + symtab_search(&p->p_commons, cladatum->comkey); if (!cladatum->comdatum) { pr_err("SELinux: unknown common %s\n", cladatum->comkey); @@ -1359,6 +1366,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; @@ -1369,8 +1378,8 @@ static int class_read(struct policydb *p, struct symtab *s, void *fp) if (rc) goto bad; ncons = le32_to_cpu(buf[0]); - rc = read_cons_helper(p, &cladatum->validatetrans, - ncons, 1, fp); + rc = read_cons_helper(p, &cladatum->validatetrans, ncons, 1, + fp); if (rc) goto bad; } @@ -1402,7 +1411,7 @@ bad: return rc; } -static int role_read(struct policydb *p, struct symtab *s, void *fp) +static int role_read(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct role_datum *role; @@ -1459,7 +1468,7 @@ bad: return rc; } -static int type_read(struct policydb *p, struct symtab *s, void *fp) +static int type_read(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct type_datum *typdatum; @@ -1507,12 +1516,11 @@ bad: return rc; } - /* * Read a MLS level structure from a policydb binary * representation file. */ -static int mls_read_level(struct mls_level *lp, void *fp) +static int mls_read_level(struct mls_level *lp, struct policy_file *fp) { __le32 buf[1]; int rc; @@ -1534,7 +1542,7 @@ static int mls_read_level(struct mls_level *lp, void *fp) return 0; } -static int user_read(struct policydb *p, struct symtab *s, void *fp) +static int user_read(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct user_datum *usrdatum; @@ -1585,7 +1593,7 @@ bad: return rc; } -static int sens_read(struct policydb *p, struct symtab *s, void *fp) +static int sens_read(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct level_datum *levdatum; @@ -1608,12 +1616,7 @@ static int sens_read(struct policydb *p, struct symtab *s, void *fp) if (rc) goto bad; - rc = -ENOMEM; - levdatum->level = kmalloc(sizeof(*levdatum->level), GFP_KERNEL); - if (!levdatum->level) - goto bad; - - rc = mls_read_level(levdatum->level, fp); + rc = mls_read_level(&levdatum->level, fp); if (rc) goto bad; @@ -1626,7 +1629,7 @@ bad: return rc; } -static int cat_read(struct policydb *p, struct symtab *s, void *fp) +static int cat_read(struct policydb *p, struct symtab *s, struct policy_file *fp) { char *key = NULL; struct cat_datum *catdatum; @@ -1659,8 +1662,9 @@ bad: return rc; } -static int (*const read_f[SYM_NUM]) (struct policydb *p, - struct symtab *s, void *fp) = { +/* clang-format off */ +static int (*const read_f[SYM_NUM])(struct policydb *p, struct symtab *s, + struct policy_file *fp) = { common_read, class_read, role_read, @@ -1670,6 +1674,7 @@ static int (*const read_f[SYM_NUM]) (struct policydb *p, sens_read, cat_read, }; +/* clang-format on */ static int user_bounds_sanity_check(void *key, void *datum, void *datap) { @@ -1685,12 +1690,13 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap) if (++depth == POLICYDB_BOUNDS_MAXDEPTH) { pr_err("SELinux: user %s: " "too deep or looped boundary\n", - (char *) key); + (char *)key); return -EINVAL; } upper = p->user_val_to_struct[upper->bounds - 1]; - ebitmap_for_each_positive_bit(&user->roles, node, bit) { + ebitmap_for_each_positive_bit(&user->roles, node, bit) + { if (ebitmap_get_bit(&upper->roles, bit)) continue; @@ -1721,12 +1727,13 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap) if (++depth == POLICYDB_BOUNDS_MAXDEPTH) { pr_err("SELinux: role %s: " "too deep or looped bounds\n", - (char *) key); + (char *)key); return -EINVAL; } upper = p->role_val_to_struct[upper->bounds - 1]; - ebitmap_for_each_positive_bit(&role->types, node, bit) { + ebitmap_for_each_positive_bit(&role->types, node, bit) + { if (ebitmap_get_bit(&upper->types, bit)) continue; @@ -1754,7 +1761,7 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap) if (++depth == POLICYDB_BOUNDS_MAXDEPTH) { pr_err("SELinux: type %s: " "too deep or looped boundary\n", - (char *) key); + (char *)key); return -EINVAL; } @@ -1764,7 +1771,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\n", - (char *) key, + (char *)key, sym_name(p, SYM_TYPES, upper->value - 1)); return -EINVAL; } @@ -1815,7 +1822,7 @@ u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name) if (!tclass || tclass > p->p_classes.nprim) return 0; - cladatum = p->class_val_to_struct[tclass-1]; + cladatum = p->class_val_to_struct[tclass - 1]; comdatum = cladatum->comdatum; if (comdatum) perdatum = symtab_search(&comdatum->permissions, name); @@ -1824,10 +1831,10 @@ u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name) if (!perdatum) return 0; - return 1U << (perdatum->value-1); + return 1U << (perdatum->value - 1); } -static int range_read(struct policydb *p, void *fp) +static int range_read(struct policydb *p, struct policy_file *fp) { struct range_trans *rt = NULL; struct mls_range *r = NULL; @@ -1896,7 +1903,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); @@ -1904,7 +1911,7 @@ out: return rc; } -static int filename_trans_read_helper_compat(struct policydb *p, void *fp) +static int filename_trans_read_helper_compat(struct policydb *p, struct policy_file *fp) { struct filename_trans_key key, *ft = NULL; struct filename_trans_datum *last, *datum = NULL; @@ -1941,6 +1948,7 @@ static int filename_trans_read_helper_compat(struct policydb *p, void *fp) if (unlikely(ebitmap_get_bit(&datum->stypes, stype - 1))) { /* conflicting/duplicate rules are ignored */ datum = NULL; + rc = 0; goto out; } if (likely(datum->otype == otype)) @@ -1988,7 +1996,7 @@ out: return rc; } -static int filename_trans_read_helper(struct policydb *p, void *fp) +static int filename_trans_read_helper(struct policydb *p, struct policy_file *fp) { struct filename_trans_key *ft = NULL; struct filename_trans_datum **dst, *datum, *first = NULL; @@ -2077,7 +2085,7 @@ out: return rc; } -static int filename_trans_read(struct policydb *p, void *fp) +static int filename_trans_read(struct policydb *p, struct policy_file *fp) { u32 nel, i; __le32 buf[1]; @@ -2114,11 +2122,11 @@ 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; } -static int genfs_read(struct policydb *p, void *fp) +static int genfs_read(struct policydb *p, struct policy_file *fp) { int rc; u32 i, j, nel, nel2, len, len2; @@ -2192,12 +2200,12 @@ static int genfs_read(struct policydb *p, void *fp) goto out; newc->v.sclass = le32_to_cpu(buf[0]); - rc = context_read_and_validate(&newc->context[0], p, fp); + rc = context_read_and_validate(&newc->context[0], p, + fp); if (rc) goto out; - for (l = NULL, c = genfs->head; c; - l = c, c = c->next) { + for (l = NULL, c = genfs->head; c; l = c, c = c->next) { rc = -EINVAL; if (!strcmp(newc->u.name, c->u.name) && (!c->v.sclass || !newc->v.sclass || @@ -2231,8 +2239,8 @@ out: return rc; } -static int ocontext_read(struct policydb *p, const struct policydb_compat_info *info, - void *fp) +static int ocontext_read(struct policydb *p, + const struct policydb_compat_info *info, struct policy_file *fp) { int rc; unsigned int i; @@ -2267,7 +2275,8 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * goto out; c->sid[0] = le32_to_cpu(buf[0]); - rc = context_read_and_validate(&c->context[0], p, fp); + rc = context_read_and_validate(&c->context[0], + p, fp); if (rc) goto out; break; @@ -2286,21 +2295,24 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * pr_warn("SELinux: void and deprecated fs ocon %s\n", c->u.name); - rc = context_read_and_validate(&c->context[0], p, fp); + rc = context_read_and_validate(&c->context[0], + p, fp); if (rc) goto out; - rc = context_read_and_validate(&c->context[1], p, fp); + rc = context_read_and_validate(&c->context[1], + p, fp); if (rc) goto out; break; case OCON_PORT: - rc = next_entry(buf, fp, sizeof(u32)*3); + rc = next_entry(buf, fp, sizeof(u32) * 3); if (rc) goto out; c->u.port.protocol = le32_to_cpu(buf[0]); c->u.port.low_port = le32_to_cpu(buf[1]); c->u.port.high_port = le32_to_cpu(buf[2]); - rc = context_read_and_validate(&c->context[0], p, fp); + rc = context_read_and_validate(&c->context[0], + p, fp); if (rc) goto out; break; @@ -2310,12 +2322,13 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * goto out; c->u.node.addr = nodebuf[0]; /* network order */ c->u.node.mask = nodebuf[1]; /* network order */ - rc = context_read_and_validate(&c->context[0], p, fp); + rc = context_read_and_validate(&c->context[0], + p, fp); if (rc) goto out; break; case OCON_FSUSE: - rc = next_entry(buf, fp, sizeof(u32)*2); + rc = next_entry(buf, fp, sizeof(u32) * 2); if (rc) goto out; @@ -2332,7 +2345,8 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * if (rc) goto out; - rc = context_read_and_validate(&c->context[0], p, fp); + rc = context_read_and_validate(&c->context[0], + p, fp); if (rc) goto out; break; @@ -2345,8 +2359,9 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * for (k = 0; k < 4; k++) c->u.node6.addr[k] = nodebuf[k]; for (k = 0; k < 4; k++) - c->u.node6.mask[k] = nodebuf[k+4]; - rc = context_read_and_validate(&c->context[0], p, fp); + c->u.node6.mask[k] = nodebuf[k + 4]; + rc = context_read_and_validate(&c->context[0], + p, fp); if (rc) goto out; break; @@ -2359,7 +2374,8 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * goto out; /* we need to have subnet_prefix in CPU order */ - c->u.ibpkey.subnet_prefix = be64_to_cpu(prefixbuf[0]); + c->u.ibpkey.subnet_prefix = + be64_to_cpu(prefixbuf[0]); rc = next_entry(buf, fp, sizeof(u32) * 2); if (rc) @@ -2373,12 +2389,11 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * goto out; } - c->u.ibpkey.low_pkey = pkey_lo; + c->u.ibpkey.low_pkey = pkey_lo; c->u.ibpkey.high_pkey = pkey_hi; rc = context_read_and_validate(&c->context[0], - p, - fp); + p, fp); if (rc) goto out; break; @@ -2391,7 +2406,8 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * goto out; len = le32_to_cpu(buf[0]); - rc = str_read(&c->u.ibendport.dev_name, GFP_KERNEL, fp, len); + rc = str_read(&c->u.ibendport.dev_name, + GFP_KERNEL, fp, len); if (rc) goto out; @@ -2404,8 +2420,7 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * c->u.ibendport.port = port; rc = context_read_and_validate(&c->context[0], - p, - fp); + p, fp); if (rc) goto out; break; @@ -2422,7 +2437,7 @@ out: * Read the configuration data from a policy database binary * representation file into a policy database structure. */ -int policydb_read(struct policydb *p, void *fp) +int policydb_read(struct policydb *p, struct policy_file *fp) { struct role_allow *ra, *lra; struct role_trans_key *rtk = NULL; @@ -2458,26 +2473,22 @@ int policydb_read(struct policydb *p, void *fp) goto bad; } - rc = -ENOMEM; - policydb_str = kmalloc(len + 1, GFP_KERNEL); - if (!policydb_str) { - pr_err("SELinux: unable to allocate memory for policydb " - "string of length %d\n", len); - goto bad; - } - - rc = next_entry(policydb_str, fp, len); + rc = str_read(&policydb_str, GFP_KERNEL, fp, len); if (rc) { - pr_err("SELinux: truncated policydb string identifier\n"); - kfree(policydb_str); + if (rc == -ENOMEM) { + pr_err("SELinux: unable to allocate memory for policydb string of length %d\n", + len); + } else { + pr_err("SELinux: truncated policydb string identifier\n"); + } goto bad; } rc = -EINVAL; - policydb_str[len] = '\0'; if (strcmp(policydb_str, POLICYDB_STRING)) { pr_err("SELinux: policydb string %s does not match " - "my string %s\n", policydb_str, POLICYDB_STRING); + "my string %s\n", + policydb_str, POLICYDB_STRING); kfree(policydb_str); goto bad; } @@ -2486,7 +2497,7 @@ int policydb_read(struct policydb *p, void *fp) policydb_str = NULL; /* Read the version and table sizes. */ - rc = next_entry(buf, fp, sizeof(u32)*4); + rc = next_entry(buf, fp, sizeof(u32) * 4); if (rc) goto bad; @@ -2496,7 +2507,8 @@ int policydb_read(struct policydb *p, void *fp) p->policyvers > POLICYDB_VERSION_MAX) { pr_err("SELinux: policydb version %d does not match " "my version range %d-%d\n", - le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); + le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, + POLICYDB_VERSION_MAX); goto bad; } @@ -2506,8 +2518,8 @@ int policydb_read(struct policydb *p, void *fp) rc = -EINVAL; if (p->policyvers < POLICYDB_VERSION_MLS) { pr_err("SELinux: security policydb version %d " - "(MLS) not backwards compatible\n", - p->policyvers); + "(MLS) not backwards compatible\n", + p->policyvers); goto bad; } } @@ -2530,22 +2542,23 @@ int policydb_read(struct policydb *p, void *fp) info = policydb_lookup_compat(p->policyvers); if (!info) { pr_err("SELinux: unable to find policy compat info " - "for version %d\n", p->policyvers); + "for version %d\n", + p->policyvers); goto bad; } rc = -EINVAL; if (le32_to_cpu(buf[2]) != info->sym_num || - le32_to_cpu(buf[3]) != info->ocon_num) { + le32_to_cpu(buf[3]) != info->ocon_num) { pr_err("SELinux: policydb table sizes (%d,%d) do " - "not match mine (%d,%d)\n", le32_to_cpu(buf[2]), - le32_to_cpu(buf[3]), - info->sym_num, info->ocon_num); + "not match mine (%d,%d)\n", + le32_to_cpu(buf[2]), le32_to_cpu(buf[3]), info->sym_num, + info->ocon_num); goto bad; } for (i = 0; i < info->sym_num; i++) { - rc = next_entry(buf, fp, sizeof(u32)*2); + rc = next_entry(buf, fp, sizeof(u32) * 2); if (rc) goto bad; nprim = le32_to_cpu(buf[0]); @@ -2606,7 +2619,7 @@ int policydb_read(struct policydb *p, void *fp) if (!rtd) goto bad; - rc = next_entry(buf, fp, sizeof(u32)*3); + rc = next_entry(buf, fp, sizeof(u32) * 3); if (rc) goto bad; @@ -2636,6 +2649,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; @@ -2650,7 +2665,7 @@ int policydb_read(struct policydb *p, void *fp) lra->next = ra; else p->role_allow = ra; - rc = next_entry(buf, fp, sizeof(u32)*2); + rc = next_entry(buf, fp, sizeof(u32) * 2); if (rc) goto bad; @@ -2698,9 +2713,8 @@ int policydb_read(struct policydb *p, void *fp) goto bad; rc = -ENOMEM; - p->type_attr_map_array = kvcalloc(p->p_types.nprim, - sizeof(*p->type_attr_map_array), - GFP_KERNEL); + p->type_attr_map_array = kvcalloc( + p->p_types.nprim, sizeof(*p->type_attr_map_array), GFP_KERNEL); if (!p->type_attr_map_array) goto bad; @@ -2740,7 +2754,7 @@ bad: * Write a MLS level structure to a policydb binary * representation file. */ -static int mls_write_level(struct mls_level *l, void *fp) +static int mls_write_level(struct mls_level *l, struct policy_file *fp) { __le32 buf[1]; int rc; @@ -2761,7 +2775,7 @@ static int mls_write_level(struct mls_level *l, void *fp) * Write a MLS range structure to a policydb binary * representation file. */ -static int mls_write_range_helper(struct mls_range *r, void *fp) +static int mls_write_range_helper(struct mls_range *r, struct policy_file *fp) { __le32 buf[3]; size_t items; @@ -2773,7 +2787,7 @@ static int mls_write_range_helper(struct mls_range *r, void *fp) items = 2; else items = 3; - buf[0] = cpu_to_le32(items-1); + buf[0] = cpu_to_le32(items - 1); buf[1] = cpu_to_le32(r->level[0].sens); if (!eq) buf[2] = cpu_to_le32(r->level[1].sens); @@ -2801,7 +2815,7 @@ static int sens_write(void *vkey, void *datum, void *ptr) char *key = vkey; struct level_datum *levdatum = datum; struct policy_data *pd = ptr; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; __le32 buf[2]; size_t len; int rc; @@ -2817,7 +2831,7 @@ static int sens_write(void *vkey, void *datum, void *ptr) if (rc) return rc; - rc = mls_write_level(levdatum->level, fp); + rc = mls_write_level(&levdatum->level, fp); if (rc) return rc; @@ -2829,7 +2843,7 @@ static int cat_write(void *vkey, void *datum, void *ptr) char *key = vkey; struct cat_datum *catdatum = datum; struct policy_data *pd = ptr; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; __le32 buf[3]; size_t len; int rc; @@ -2854,7 +2868,7 @@ static int role_trans_write_one(void *key, void *datum, void *ptr) struct role_trans_key *rtk = key; struct role_trans_datum *rtd = datum; struct policy_data *pd = ptr; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; struct policydb *p = pd->p; __le32 buf[3]; int rc; @@ -2874,7 +2888,7 @@ static int role_trans_write_one(void *key, void *datum, void *ptr) return 0; } -static int role_trans_write(struct policydb *p, void *fp) +static int role_trans_write(struct policydb *p, struct policy_file *fp) { struct policy_data pd = { .p = p, .fp = fp }; __le32 buf[1]; @@ -2888,7 +2902,7 @@ static int role_trans_write(struct policydb *p, void *fp) return hashtab_map(&p->role_tr, role_trans_write_one, &pd); } -static int role_allow_write(struct role_allow *r, void *fp) +static int role_allow_write(struct role_allow *r, struct policy_file *fp) { struct role_allow *ra; __le32 buf[2]; @@ -2916,8 +2930,7 @@ static int role_allow_write(struct role_allow *r, void *fp) * Write a security context structure * to a policydb binary representation file. */ -static int context_write(struct policydb *p, struct context *c, - void *fp) +static int context_write(struct policydb *p, struct context *c, struct policy_file *fp) { int rc; __le32 buf[3]; @@ -2970,7 +2983,7 @@ static int common_write(void *vkey, void *datum, void *ptr) char *key = vkey; struct common_datum *comdatum = datum; struct policy_data *pd = ptr; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; __le32 buf[4]; size_t len; int rc; @@ -2995,7 +3008,7 @@ static int common_write(void *vkey, void *datum, void *ptr) return 0; } -static int type_set_write(struct type_set *t, void *fp) +static int type_set_write(struct type_set *t, struct policy_file *fp) { int rc; __le32 buf[1]; @@ -3014,7 +3027,7 @@ static int type_set_write(struct type_set *t, void *fp) } static int write_cons_helper(struct policydb *p, struct constraint_node *node, - void *fp) + struct policy_file *fp) { struct constraint_node *c; struct constraint_expr *e; @@ -3045,7 +3058,7 @@ static int write_cons_helper(struct policydb *p, struct constraint_node *node, if (rc) return rc; if (p->policyvers >= - POLICYDB_VERSION_CONSTRAINT_NAMES) { + POLICYDB_VERSION_CONSTRAINT_NAMES) { rc = type_set_write(e->type_names, fp); if (rc) return rc; @@ -3065,7 +3078,7 @@ static int class_write(void *vkey, void *datum, void *ptr) char *key = vkey; struct class_datum *cladatum = datum; struct policy_data *pd = ptr; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; struct policydb *p = pd->p; struct constraint_node *c; __le32 buf[6]; @@ -3150,7 +3163,7 @@ static int role_write(void *vkey, void *datum, void *ptr) char *key = vkey; struct role_datum *role = datum; struct policy_data *pd = ptr; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; struct policydb *p = pd->p; __le32 buf[3]; size_t items, len; @@ -3190,7 +3203,7 @@ static int type_write(void *vkey, void *datum, void *ptr) struct type_datum *typdatum = datum; struct policy_data *pd = ptr; struct policydb *p = pd->p; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; __le32 buf[4]; int rc; size_t items, len; @@ -3231,7 +3244,7 @@ static int user_write(void *vkey, void *datum, void *ptr) struct user_datum *usrdatum = datum; struct policy_data *pd = ptr; struct policydb *p = pd->p; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; __le32 buf[3]; size_t items, len; int rc; @@ -3266,7 +3279,8 @@ static int user_write(void *vkey, void *datum, void *ptr) return 0; } -static int (*const write_f[SYM_NUM]) (void *key, void *datum, void *datap) = { +/* clang-format off */ +static int (*const write_f[SYM_NUM])(void *key, void *datum, void *datap) = { common_write, class_write, role_write, @@ -3276,9 +3290,11 @@ static int (*const write_f[SYM_NUM]) (void *key, void *datum, void *datap) = { sens_write, cat_write, }; +/* clang-format on */ -static int ocontext_write(struct policydb *p, const struct policydb_compat_info *info, - void *fp) +static int ocontext_write(struct policydb *p, + const struct policydb_compat_info *info, + struct policy_file *fp) { unsigned int i, j; int rc; @@ -3360,9 +3376,13 @@ static int ocontext_write(struct policydb *p, const struct policydb_compat_info break; case OCON_NODE6: for (j = 0; j < 4; j++) - nodebuf[j] = c->u.node6.addr[j]; /* network order */ + nodebuf[j] = + c->u.node6.addr + [j]; /* network order */ for (j = 0; j < 4; j++) - nodebuf[j + 4] = c->u.node6.mask[j]; /* network order */ + nodebuf[j + 4] = + c->u.node6.mask + [j]; /* network order */ rc = put_entry(nodebuf, sizeof(u32), 8, fp); if (rc) return rc; @@ -3372,7 +3392,8 @@ static int ocontext_write(struct policydb *p, const struct policydb_compat_info break; case OCON_IBPKEY: /* subnet_prefix is in CPU order */ - prefixbuf[0] = cpu_to_be64(c->u.ibpkey.subnet_prefix); + prefixbuf[0] = + cpu_to_be64(c->u.ibpkey.subnet_prefix); rc = put_entry(prefixbuf, sizeof(u64), 1, fp); if (rc) @@ -3395,7 +3416,8 @@ static int ocontext_write(struct policydb *p, const struct policydb_compat_info rc = put_entry(buf, sizeof(u32), 2, fp); if (rc) return rc; - rc = put_entry(c->u.ibendport.dev_name, 1, len, fp); + rc = put_entry(c->u.ibendport.dev_name, 1, len, + fp); if (rc) return rc; rc = context_write(p, &c->context[0], fp); @@ -3408,7 +3430,7 @@ static int ocontext_write(struct policydb *p, const struct policydb_compat_info return 0; } -static int genfs_write(struct policydb *p, void *fp) +static int genfs_write(struct policydb *p, struct policy_file *fp) { struct genfs *genfs; struct ocontext *c; @@ -3466,7 +3488,7 @@ static int range_write_helper(void *key, void *data, void *ptr) struct range_trans *rt = key; struct mls_range *r = data; struct policy_data *pd = ptr; - void *fp = pd->fp; + struct policy_file *fp = pd->fp; struct policydb *p = pd->p; int rc; @@ -3488,7 +3510,7 @@ static int range_write_helper(void *key, void *data, void *ptr) return 0; } -static int range_write(struct policydb *p, void *fp) +static int range_write(struct policydb *p, struct policy_file *fp) { __le32 buf[1]; int rc; @@ -3515,13 +3537,14 @@ static int filename_write_helper_compat(void *key, void *data, void *ptr) struct filename_trans_key *ft = key; struct filename_trans_datum *datum = data; struct ebitmap_node *node; - void *fp = ptr; + struct policy_file *fp = ptr; __le32 buf[4]; int rc; u32 bit, len = strlen(ft->name); do { - ebitmap_for_each_positive_bit(&datum->stypes, node, bit) { + ebitmap_for_each_positive_bit(&datum->stypes, node, bit) + { buf[0] = cpu_to_le32(len); rc = put_entry(buf, sizeof(u32), 1, fp); if (rc) @@ -3551,7 +3574,7 @@ static int filename_write_helper(void *key, void *data, void *ptr) { struct filename_trans_key *ft = key; struct filename_trans_datum *datum; - void *fp = ptr; + struct policy_file *fp = ptr; __le32 buf[3]; int rc; u32 ndatum, len = strlen(ft->name); @@ -3596,7 +3619,7 @@ static int filename_write_helper(void *key, void *data, void *ptr) return 0; } -static int filename_trans_write(struct policydb *p, void *fp) +static int filename_trans_write(struct policydb *p, struct policy_file *fp) { __le32 buf[1]; int rc; @@ -3628,7 +3651,7 @@ static int filename_trans_write(struct policydb *p, void *fp) * structure to a policy database binary representation * file. */ -int policydb_write(struct policydb *p, void *fp) +int policydb_write(struct policydb *p, struct policy_file *fp) { unsigned int num_syms; int rc; @@ -3645,8 +3668,8 @@ int policydb_write(struct policydb *p, void *fp) */ if (p->policyvers < POLICYDB_VERSION_AVTAB) { pr_err("SELinux: refusing to write policy version %d." - " Because it is less than version %d\n", p->policyvers, - POLICYDB_VERSION_AVTAB); + " Because it is less than version %d\n", + p->policyvers, POLICYDB_VERSION_AVTAB); return -EINVAL; } @@ -3674,7 +3697,8 @@ 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\n", p->policyvers); + "version %d\n", + p->policyvers); return -EINVAL; } diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index b97cda489753..25650224b6e7 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -8,15 +8,13 @@ /* * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> + * Support for enhanced MLS infrastructure. + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * - * Support for enhanced MLS infrastructure. - * - * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> - * - * Added conditional policy language extensions - * - * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. - * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * Updated: Frank Mayer <mayerf@tresys.com> and + * Karl MacMillan <kmacmillan@tresys.com> + * Added conditional policy language extensions + * Copyright (C) 2003-2004 Tresys Technology, LLC */ #ifndef _SS_POLICYDB_H_ @@ -39,104 +37,103 @@ /* Permission attributes */ struct perm_datum { - u32 value; /* permission bit + 1 */ + u32 value; /* permission bit + 1 */ }; /* Attributes of a common prefix for access vectors */ struct common_datum { - u32 value; /* internal common value */ - struct symtab permissions; /* common permissions */ + u32 value; /* internal common value */ + struct symtab permissions; /* common permissions */ }; /* Class attributes */ struct class_datum { - u32 value; /* class value */ - char *comkey; /* common name */ - struct common_datum *comdatum; /* common datum */ - struct symtab permissions; /* class-specific permission symbol table */ - struct constraint_node *constraints; /* constraints on class permissions */ - struct constraint_node *validatetrans; /* special transition rules */ + u32 value; /* class value */ + char *comkey; /* common name */ + struct common_datum *comdatum; /* common datum */ + struct symtab permissions; /* class-specific permission symbol table */ + struct constraint_node *constraints; /* constraints on class perms */ + struct constraint_node *validatetrans; /* special transition rules */ /* Options how a new object user, role, and type should be decided */ -#define DEFAULT_SOURCE 1 -#define DEFAULT_TARGET 2 +#define DEFAULT_SOURCE 1 +#define DEFAULT_TARGET 2 char default_user; char default_role; char default_type; /* Options how a new object range should be decided */ -#define DEFAULT_SOURCE_LOW 1 -#define DEFAULT_SOURCE_HIGH 2 -#define DEFAULT_SOURCE_LOW_HIGH 3 -#define DEFAULT_TARGET_LOW 4 -#define DEFAULT_TARGET_HIGH 5 -#define DEFAULT_TARGET_LOW_HIGH 6 +#define DEFAULT_SOURCE_LOW 1 +#define DEFAULT_SOURCE_HIGH 2 +#define DEFAULT_SOURCE_LOW_HIGH 3 +#define DEFAULT_TARGET_LOW 4 +#define DEFAULT_TARGET_HIGH 5 +#define DEFAULT_TARGET_LOW_HIGH 6 #define DEFAULT_GLBLUB 7 char default_range; }; /* Role attributes */ struct role_datum { - u32 value; /* internal role value */ - u32 bounds; /* boundary of role */ - struct ebitmap dominates; /* set of roles dominated by this role */ - struct ebitmap types; /* set of authorized types for role */ + u32 value; /* internal role value */ + u32 bounds; /* boundary of role */ + struct ebitmap dominates; /* set of roles dominated by this role */ + struct ebitmap types; /* set of authorized types for role */ }; struct role_trans_key { - u32 role; /* current role */ - u32 type; /* program executable type, or new object type */ - u32 tclass; /* process class, or new object class */ + u32 role; /* current role */ + u32 type; /* program executable type, or new object type */ + u32 tclass; /* process class, or new object class */ }; struct role_trans_datum { - u32 new_role; /* new role */ + u32 new_role; /* new role */ }; struct filename_trans_key { - u32 ttype; /* parent dir context */ - u16 tclass; /* class of new object */ - const char *name; /* last path component */ + u32 ttype; /* parent dir context */ + u16 tclass; /* class of new object */ + const char *name; /* last path component */ }; struct filename_trans_datum { - struct ebitmap stypes; /* bitmap of source types for this otype */ - u32 otype; /* resulting type of new object */ - struct filename_trans_datum *next; /* record for next otype*/ + struct ebitmap stypes; /* bitmap of source types for this otype */ + u32 otype; /* resulting type of new object */ + struct filename_trans_datum *next; /* record for next otype*/ }; struct role_allow { - u32 role; /* current role */ - u32 new_role; /* new role */ + u32 role; /* current role */ + u32 new_role; /* new role */ struct role_allow *next; }; /* Type attributes */ struct type_datum { - u32 value; /* internal type value */ - u32 bounds; /* boundary of type */ - unsigned char primary; /* primary name? */ - unsigned char attribute;/* attribute ?*/ + u32 value; /* internal type value */ + u32 bounds; /* boundary of type */ + unsigned char primary; /* primary name? */ + unsigned char attribute; /* attribute ?*/ }; /* User attributes */ struct user_datum { - u32 value; /* internal user value */ - u32 bounds; /* bounds of user */ - struct ebitmap roles; /* set of authorized roles for user */ - struct mls_range range; /* MLS range (min - max) for user */ - struct mls_level dfltlevel; /* default login MLS level for user */ + u32 value; /* internal user value */ + u32 bounds; /* bounds of user */ + struct ebitmap roles; /* set of authorized roles for user */ + struct mls_range range; /* MLS range (min - max) for user */ + struct mls_level dfltlevel; /* default login MLS level for user */ }; - /* Sensitivity attributes */ struct level_datum { - struct mls_level *level; /* sensitivity and associated categories */ - unsigned char isalias; /* is this sensitivity an alias for another? */ + struct mls_level level; /* sensitivity and associated categories */ + unsigned char isalias; /* is this sensitivity an alias for another? */ }; /* Category attributes */ struct cat_datum { - u32 value; /* internal category bit + 1 */ - unsigned char isalias; /* is this category an alias for another? */ + u32 value; /* internal category bit + 1 */ + unsigned char isalias; /* is this category an alias for another? */ }; struct range_trans { @@ -147,7 +144,7 @@ struct range_trans { /* Boolean data type */ struct cond_bool_datum { - __u32 value; /* internal type value */ + u32 value; /* internal type value */ int state; }; @@ -173,20 +170,20 @@ struct type_set { */ struct ocontext { union { - char *name; /* name of initial SID, fs, netif, fstype, path */ + char *name; /* name of initial SID, fs, netif, fstype, path */ struct { u8 protocol; u16 low_port; u16 high_port; - } port; /* TCP or UDP port information */ + } port; /* TCP or UDP port information */ struct { u32 addr; u32 mask; - } node; /* node information */ + } node; /* node information */ struct { u32 addr[4]; u32 mask[4]; - } node6; /* IPv6 node information */ + } node6; /* IPv6 node information */ struct { u64 subnet_prefix; u16 low_pkey; @@ -198,11 +195,11 @@ struct ocontext { } ibendport; } u; union { - u32 sclass; /* security class for genfs */ - u32 behavior; /* labeling behavior for fs_use */ + u32 sclass; /* security class for genfs */ + u32 behavior; /* labeling behavior for fs_use */ } v; - struct context context[2]; /* security context(s) */ - u32 sid[2]; /* SID(s) */ + struct context context[2]; /* security context(s) */ + u32 sid[2]; /* SID(s) */ struct ocontext *next; }; @@ -221,19 +218,19 @@ struct genfs { #define SYM_BOOLS 5 #define SYM_LEVELS 6 #define SYM_CATS 7 -#define SYM_NUM 8 +#define SYM_NUM 8 /* object context array indices */ -#define OCON_ISID 0 /* initial SIDs */ -#define OCON_FS 1 /* unlabeled file systems (deprecated) */ -#define OCON_PORT 2 /* TCP and UDP port numbers */ -#define OCON_NETIF 3 /* network interfaces */ -#define OCON_NODE 4 /* nodes */ -#define OCON_FSUSE 5 /* fs_use */ -#define OCON_NODE6 6 /* IPv6 nodes */ -#define OCON_IBPKEY 7 /* Infiniband PKeys */ -#define OCON_IBENDPORT 8 /* Infiniband end ports */ -#define OCON_NUM 9 +#define OCON_ISID 0 /* initial SIDs */ +#define OCON_FS 1 /* unlabeled file systems (deprecated) */ +#define OCON_PORT 2 /* TCP and UDP port numbers */ +#define OCON_NETIF 3 /* network interfaces */ +#define OCON_NODE 4 /* nodes */ +#define OCON_FSUSE 5 /* fs_use */ +#define OCON_NODE6 6 /* IPv6 nodes */ +#define OCON_IBPKEY 7 /* Infiniband PKeys */ +#define OCON_IBENDPORT 8 /* Infiniband end ports */ +#define OCON_NUM 9 /* The policy database */ struct policydb { @@ -243,15 +240,15 @@ struct policydb { struct symtab symtab[SYM_NUM]; #define p_commons symtab[SYM_COMMONS] #define p_classes symtab[SYM_CLASSES] -#define p_roles symtab[SYM_ROLES] -#define p_types symtab[SYM_TYPES] -#define p_users symtab[SYM_USERS] -#define p_bools symtab[SYM_BOOLS] -#define p_levels symtab[SYM_LEVELS] -#define p_cats symtab[SYM_CATS] +#define p_roles symtab[SYM_ROLES] +#define p_types symtab[SYM_TYPES] +#define p_users symtab[SYM_USERS] +#define p_bools symtab[SYM_BOOLS] +#define p_levels symtab[SYM_LEVELS] +#define p_cats symtab[SYM_CATS] /* symbol names indexed by (value - 1) */ - char **sym_val_to_name[SYM_NUM]; + char **sym_val_to_name[SYM_NUM]; /* class, role, and user attributes indexed by (value - 1) */ struct class_datum **class_val_to_struct; @@ -315,44 +312,44 @@ struct policydb { u32 process_trans_perms; } __randomize_layout; +struct policy_file { + char *data; + size_t len; +}; + extern void policydb_destroy(struct policydb *p); extern int policydb_load_isids(struct policydb *p, struct sidtab *s); extern int policydb_context_isvalid(struct policydb *p, struct context *c); extern int policydb_class_isvalid(struct policydb *p, unsigned int class); extern int policydb_type_isvalid(struct policydb *p, unsigned int type); extern int policydb_role_isvalid(struct policydb *p, unsigned int role); -extern int policydb_read(struct policydb *p, void *fp); -extern int policydb_write(struct policydb *p, void *fp); +extern int policydb_read(struct policydb *p, struct policy_file *fp); +extern int policydb_write(struct policydb *p, struct policy_file *fp); -extern struct filename_trans_datum *policydb_filenametr_search( - struct policydb *p, struct filename_trans_key *key); +extern struct filename_trans_datum * +policydb_filenametr_search(struct policydb *p, struct filename_trans_key *key); -extern struct mls_range *policydb_rangetr_search( - struct policydb *p, struct range_trans *key); +extern struct mls_range *policydb_rangetr_search(struct policydb *p, + struct range_trans *key); -extern struct role_trans_datum *policydb_roletr_search( - struct policydb *p, struct role_trans_key *key); +extern struct role_trans_datum * +policydb_roletr_search(struct policydb *p, struct role_trans_key *key); -#define POLICYDB_CONFIG_MLS 1 +#define POLICYDB_CONFIG_MLS 1 /* the config flags related to unknown classes/perms are bits 2 and 3 */ -#define REJECT_UNKNOWN 0x00000002 -#define ALLOW_UNKNOWN 0x00000004 +#define REJECT_UNKNOWN 0x00000002 +#define ALLOW_UNKNOWN 0x00000004 -#define OBJECT_R "object_r" +#define OBJECT_R "object_r" #define OBJECT_R_VAL 1 -#define POLICYDB_MAGIC SELINUX_MAGIC +#define POLICYDB_MAGIC SELINUX_MAGIC #define POLICYDB_STRING "SE Linux" -struct policy_file { - char *data; - size_t len; -}; - struct policy_data { struct policydb *p; - void *fp; + struct policy_file *fp; }; static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes) @@ -366,7 +363,8 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes) return 0; } -static inline int put_entry(const void *buf, size_t bytes, size_t num, struct policy_file *fp) +static inline int put_entry(const void *buf, size_t bytes, size_t num, + struct policy_file *fp) { size_t len; @@ -382,13 +380,15 @@ static inline int put_entry(const void *buf, size_t bytes, size_t num, struct po return 0; } -static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr) +static inline char *sym_name(struct policydb *p, unsigned int sym_num, + unsigned int element_nr) { return p->sym_val_to_name[sym_num][element_nr]; } +extern int str_read(char **strp, gfp_t flags, struct policy_file *fp, u32 len); + extern u16 string_to_security_class(struct policydb *p, const char *name); extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); -#endif /* _SS_POLICYDB_H_ */ - +#endif /* _SS_POLICYDB_H_ */ diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index e88b1b6c4adb..8478842fbf9e 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -582,8 +582,7 @@ static void type_attribute_bounds_av(struct policydb *policydb, } /* - * flag which drivers have permissions - * only looking for ioctl based extended permissions + * Flag which drivers have permissions and which base permissions are covered. */ void services_compute_xperms_drivers( struct extended_perms *xperms, @@ -591,14 +590,25 @@ void services_compute_xperms_drivers( { unsigned int i; - if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + switch (node->datum.u.xperms->specified) { + case AVTAB_XPERMS_IOCTLDRIVER: + xperms->base_perms |= AVC_EXT_IOCTL; /* if one or more driver has all permissions allowed */ for (i = 0; i < ARRAY_SIZE(xperms->drivers.p); i++) xperms->drivers.p[i] |= node->datum.u.xperms->perms.p[i]; - } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + break; + case AVTAB_XPERMS_IOCTLFUNCTION: + xperms->base_perms |= AVC_EXT_IOCTL; + /* if allowing permissions within a driver */ + security_xperm_set(xperms->drivers.p, + node->datum.u.xperms->driver); + break; + case AVTAB_XPERMS_NLMSG: + xperms->base_perms |= AVC_EXT_NLMSG; /* if allowing permissions within a driver */ security_xperm_set(xperms->drivers.p, node->datum.u.xperms->driver); + break; } xperms->len = 1; @@ -628,13 +638,11 @@ static void context_struct_compute_av(struct policydb *policydb, avd->auditallow = 0; avd->auditdeny = 0xffffffff; if (xperms) { - memset(&xperms->drivers, 0, sizeof(xperms->drivers)); - xperms->len = 0; + memset(xperms, 0, sizeof(*xperms)); } if (unlikely(!tclass || tclass > policydb->p_classes.nprim)) { - if (printk_ratelimit()) - pr_warn("SELinux: Invalid class %hu\n", tclass); + pr_warn_ratelimited("SELinux: Invalid class %u\n", tclass); return; } @@ -943,57 +951,74 @@ static void avd_init(struct selinux_policy *policy, struct av_decision *avd) avd->flags = 0; } +static void update_xperms_extended_data(u8 specified, + const struct extended_perms_data *from, + struct extended_perms_data *xp_data) +{ + unsigned int i; + + switch (specified) { + case AVTAB_XPERMS_IOCTLDRIVER: + memset(xp_data->p, 0xff, sizeof(xp_data->p)); + break; + case AVTAB_XPERMS_IOCTLFUNCTION: + case AVTAB_XPERMS_NLMSG: + for (i = 0; i < ARRAY_SIZE(xp_data->p); i++) + xp_data->p[i] |= from->p[i]; + break; + } + +} + void services_compute_xperms_decision(struct extended_perms_decision *xpermd, struct avtab_node *node) { - unsigned int i; + u16 specified; - if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { - if (xpermd->driver != node->datum.u.xperms->driver) + switch (node->datum.u.xperms->specified) { + case AVTAB_XPERMS_IOCTLFUNCTION: + if (xpermd->base_perm != AVC_EXT_IOCTL || + xpermd->driver != node->datum.u.xperms->driver) return; - } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { - if (!security_xperm_test(node->datum.u.xperms->perms.p, - xpermd->driver)) + break; + case AVTAB_XPERMS_IOCTLDRIVER: + if (xpermd->base_perm != AVC_EXT_IOCTL || + !security_xperm_test(node->datum.u.xperms->perms.p, + xpermd->driver)) return; - } else { - BUG(); + break; + case AVTAB_XPERMS_NLMSG: + if (xpermd->base_perm != AVC_EXT_NLMSG || + xpermd->driver != node->datum.u.xperms->driver) + return; + break; + default: + pr_warn_once( + "SELinux: unknown extended permission (%u) will be ignored\n", + node->datum.u.xperms->specified); + return; } - if (node->key.specified == AVTAB_XPERMS_ALLOWED) { + specified = node->key.specified & ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD); + + if (specified == AVTAB_XPERMS_ALLOWED) { xpermd->used |= XPERMS_ALLOWED; - if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { - memset(xpermd->allowed->p, 0xff, - sizeof(xpermd->allowed->p)); - } - if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { - for (i = 0; i < ARRAY_SIZE(xpermd->allowed->p); i++) - xpermd->allowed->p[i] |= - node->datum.u.xperms->perms.p[i]; - } - } else if (node->key.specified == AVTAB_XPERMS_AUDITALLOW) { + update_xperms_extended_data(node->datum.u.xperms->specified, + &node->datum.u.xperms->perms, + xpermd->allowed); + } else if (specified == AVTAB_XPERMS_AUDITALLOW) { xpermd->used |= XPERMS_AUDITALLOW; - if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { - memset(xpermd->auditallow->p, 0xff, - sizeof(xpermd->auditallow->p)); - } - if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { - for (i = 0; i < ARRAY_SIZE(xpermd->auditallow->p); i++) - xpermd->auditallow->p[i] |= - node->datum.u.xperms->perms.p[i]; - } - } else if (node->key.specified == AVTAB_XPERMS_DONTAUDIT) { + update_xperms_extended_data(node->datum.u.xperms->specified, + &node->datum.u.xperms->perms, + xpermd->auditallow); + } else if (specified == AVTAB_XPERMS_DONTAUDIT) { xpermd->used |= XPERMS_DONTAUDIT; - if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { - memset(xpermd->dontaudit->p, 0xff, - sizeof(xpermd->dontaudit->p)); - } - if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { - for (i = 0; i < ARRAY_SIZE(xpermd->dontaudit->p); i++) - xpermd->dontaudit->p[i] |= - node->datum.u.xperms->perms.p[i]; - } + update_xperms_extended_data(node->datum.u.xperms->specified, + &node->datum.u.xperms->perms, + xpermd->dontaudit); } else { - BUG(); + pr_warn_once("SELinux: unknown specified key (%u)\n", + node->key.specified); } } @@ -1001,6 +1026,7 @@ void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 orig_tclass, u8 driver, + u8 base_perm, struct extended_perms_decision *xpermd) { struct selinux_policy *policy; @@ -1014,6 +1040,7 @@ void security_compute_xperms_decision(u32 ssid, struct ebitmap_node *snode, *tnode; unsigned int i, j; + xpermd->base_perm = base_perm; xpermd->driver = driver; xpermd->used = 0; memset(xpermd->allowed->p, 0, sizeof(xpermd->allowed->p)); @@ -1805,22 +1832,9 @@ retry: newcontext.role = OBJECT_R_VAL; } - /* Set the type to default values. */ - if (cladatum && cladatum->default_type == DEFAULT_SOURCE) { - newcontext.type = scontext->type; - } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { - newcontext.type = tcontext->type; - } else { - if ((tclass == policydb->process_class) || sock) { - /* Use the type of process. */ - newcontext.type = scontext->type; - } else { - /* Use the type of the related object. */ - newcontext.type = tcontext->type; - } - } - - /* Look for a type transition/member/change rule. */ + /* Set the type. + * Look for a type transition/member/change rule. + */ avkey.source_type = scontext->type; avkey.target_type = tcontext->type; avkey.target_class = tclass; @@ -1838,9 +1852,24 @@ retry: } } + /* If a permanent rule is found, use the type from + * the type transition/member/change rule. Otherwise, + * set the type to its default values. + */ if (avnode) { - /* Use the type from the type transition/member/change rule. */ newcontext.type = avnode->datum.u.data; + } else if (cladatum && cladatum->default_type == DEFAULT_SOURCE) { + newcontext.type = scontext->type; + } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { + newcontext.type = tcontext->type; + } else { + if ((tclass == policydb->process_class) || sock) { + /* Use the type of process. */ + newcontext.type = scontext->type; + } else { + /* Use the type of the related object. */ + newcontext.type = tcontext->type; + } } /* if we have a objname this is a file trans check so check those rules */ @@ -2586,17 +2615,15 @@ out: return rc; } -static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask) +static bool match_ipv6_addrmask(const u32 input[4], const u32 addr[4], const u32 mask[4]) { - int i, fail = 0; + int i; for (i = 0; i < 4; i++) - if (addr[i] != (input[i] & mask[i])) { - fail = 1; - break; - } + if (addr[i] != (input[i] & mask[i])) + return false; - return !fail; + return true; } /** @@ -2701,7 +2728,7 @@ out: */ int security_get_user_sids(u32 fromsid, - char *username, + const char *username, u32 **sids, u32 *nel) { @@ -3023,7 +3050,7 @@ err: } -int security_set_bools(u32 len, int *values) +int security_set_bools(u32 len, const int *values) { struct selinux_state *state = &selinux_state; struct selinux_policy *newpolicy, *oldpolicy; @@ -3322,7 +3349,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, __func__, xfrm_sid); goto out; } - rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); + rc = (mls_context_equal(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); if (rc) goto out; @@ -3508,7 +3535,8 @@ void selinux_audit_rule_free(void *vrule) } } -int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, + gfp_t gfp) { struct selinux_state *state = &selinux_state; struct selinux_policy *policy; @@ -3549,7 +3577,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) return -EINVAL; } - tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); + tmprule = kzalloc(sizeof(struct selinux_audit_rule), gfp); if (!tmprule) return -ENOMEM; context_init(&tmprule->au_ctxt); @@ -3633,7 +3661,7 @@ int selinux_audit_rule_known(struct audit_krule *rule) return 0; } -int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule) +int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, void *vrule) { struct selinux_state *state = &selinux_state; struct selinux_policy *policy; @@ -3659,10 +3687,10 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule) goto out; } - ctxt = sidtab_search(policy->sidtab, sid); + ctxt = sidtab_search(policy->sidtab, prop->selinux.secid); if (unlikely(!ctxt)) { WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", - sid); + prop->selinux.secid); match = -ENOENT; goto out; } diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index d24b0a3d198e..93358e7a649c 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -4,6 +4,7 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #ifndef _SS_SERVICES_H_ #define _SS_SERVICES_H_ @@ -43,4 +44,4 @@ int services_convert_context(struct convert_context_args *args, struct context *oldc, struct context *newc, gfp_t gfp_flags); -#endif /* _SS_SERVICES_H_ */ +#endif /* _SS_SERVICES_H_ */ diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index 732fd8e22a12..59f8c09158ef 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -7,6 +7,7 @@ * * Copyright (C) 2018 Red Hat, Inc. */ + #include <linux/errno.h> #include <linux/kernel.h> #include <linux/list.h> @@ -29,7 +30,7 @@ struct sidtab_str_cache { }; #define index_to_sid(index) ((index) + SECINITSID_NUM + 1) -#define sid_to_index(sid) ((sid) - (SECINITSID_NUM + 1)) +#define sid_to_index(sid) ((sid) - (SECINITSID_NUM + 1)) int sidtab_init(struct sidtab *s) { @@ -65,7 +66,7 @@ static u32 context_to_sid(struct sidtab *s, struct context *context, u32 hash) hash_for_each_possible_rcu(s->context_to_sid, entry, list, hash) { if (entry->hash != hash) continue; - if (context_cmp(&entry->context, context)) { + if (context_equal(&entry->context, context)) { sid = entry->sid; break; } @@ -113,12 +114,12 @@ int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context) int sidtab_hash_stats(struct sidtab *sidtab, char *page) { - int i; + unsigned int i; int chain_len = 0; int slots_used = 0; int entries = 0; int max_chain_len = 0; - int cur_bucket = 0; + unsigned int cur_bucket = 0; struct sidtab_entry *entry; rcu_read_lock(); @@ -140,9 +141,11 @@ int sidtab_hash_stats(struct sidtab *sidtab, char *page) if (chain_len > max_chain_len) max_chain_len = chain_len; - return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n" - "longest chain: %d\n", entries, - slots_used, SIDTAB_HASH_BUCKETS, max_chain_len); + return scnprintf(page, PAGE_SIZE, + "entries: %d\nbuckets used: %d/%d\n" + "longest chain: %d\n", + entries, slots_used, SIDTAB_HASH_BUCKETS, + max_chain_len); } static u32 sidtab_level_from_count(u32 count) @@ -162,15 +165,15 @@ static int sidtab_alloc_roots(struct sidtab *s, u32 level) u32 l; if (!s->roots[0].ptr_leaf) { - s->roots[0].ptr_leaf = kzalloc(SIDTAB_NODE_ALLOC_SIZE, - GFP_ATOMIC); + s->roots[0].ptr_leaf = + kzalloc(SIDTAB_NODE_ALLOC_SIZE, GFP_ATOMIC); if (!s->roots[0].ptr_leaf) return -ENOMEM; } for (l = 1; l <= level; ++l) if (!s->roots[l].ptr_inner) { - s->roots[l].ptr_inner = kzalloc(SIDTAB_NODE_ALLOC_SIZE, - GFP_ATOMIC); + s->roots[l].ptr_inner = + kzalloc(SIDTAB_NODE_ALLOC_SIZE, GFP_ATOMIC); if (!s->roots[l].ptr_inner) return -ENOMEM; s->roots[l].ptr_inner->entries[0] = s->roots[l - 1]; @@ -203,16 +206,16 @@ static struct sidtab_entry *sidtab_do_lookup(struct sidtab *s, u32 index, if (!entry->ptr_inner) { if (alloc) - entry->ptr_inner = kzalloc(SIDTAB_NODE_ALLOC_SIZE, - GFP_ATOMIC); + entry->ptr_inner = kzalloc( + SIDTAB_NODE_ALLOC_SIZE, GFP_ATOMIC); if (!entry->ptr_inner) return NULL; } } if (!entry->ptr_leaf) { if (alloc) - entry->ptr_leaf = kzalloc(SIDTAB_NODE_ALLOC_SIZE, - GFP_ATOMIC); + entry->ptr_leaf = + kzalloc(SIDTAB_NODE_ALLOC_SIZE, GFP_ATOMIC); if (!entry->ptr_leaf) return NULL; } @@ -262,8 +265,7 @@ struct sidtab_entry *sidtab_search_entry_force(struct sidtab *s, u32 sid) return sidtab_search_core(s, sid, 1); } -int sidtab_context_to_sid(struct sidtab *s, struct context *context, - u32 *sid) +int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid) { unsigned long flags; u32 count, hash = context_compute_hash(context); @@ -327,8 +329,8 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, goto out_unlock; } - rc = services_convert_context(convert->args, - context, &dst_convert->context, + rc = services_convert_context(convert->args, context, + &dst_convert->context, GFP_ATOMIC); if (rc) { context_destroy(&dst->context); @@ -338,8 +340,8 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, dst_convert->hash = context_compute_hash(&dst_convert->context); target->count = count + 1; - hash_add_rcu(target->context_to_sid, - &dst_convert->list, dst_convert->hash); + hash_add_rcu(target->context_to_sid, &dst_convert->list, + dst_convert->hash); } if (context->len) @@ -373,8 +375,8 @@ static void sidtab_convert_hashtable(struct sidtab *s, u32 count) } static int sidtab_convert_tree(union sidtab_entry_inner *edst, - union sidtab_entry_inner *esrc, - u32 *pos, u32 count, u32 level, + union sidtab_entry_inner *esrc, u32 *pos, + u32 count, u32 level, struct sidtab_convert_params *convert) { int rc; @@ -382,8 +384,8 @@ static int sidtab_convert_tree(union sidtab_entry_inner *edst, if (level != 0) { if (!edst->ptr_inner) { - edst->ptr_inner = kzalloc(SIDTAB_NODE_ALLOC_SIZE, - GFP_KERNEL); + edst->ptr_inner = + kzalloc(SIDTAB_NODE_ALLOC_SIZE, GFP_KERNEL); if (!edst->ptr_inner) return -ENOMEM; } @@ -399,17 +401,18 @@ static int sidtab_convert_tree(union sidtab_entry_inner *edst, } } else { if (!edst->ptr_leaf) { - edst->ptr_leaf = kzalloc(SIDTAB_NODE_ALLOC_SIZE, - GFP_KERNEL); + edst->ptr_leaf = + kzalloc(SIDTAB_NODE_ALLOC_SIZE, GFP_KERNEL); if (!edst->ptr_leaf) return -ENOMEM; } i = 0; while (i < SIDTAB_LEAF_ENTRIES && *pos < count) { - rc = services_convert_context(convert->args, - &esrc->ptr_leaf->entries[i].context, - &edst->ptr_leaf->entries[i].context, - GFP_KERNEL); + rc = services_convert_context( + convert->args, + &esrc->ptr_leaf->entries[i].context, + &edst->ptr_leaf->entries[i].context, + GFP_KERNEL); if (rc) return rc; (*pos)++; @@ -489,13 +492,15 @@ void sidtab_cancel_convert(struct sidtab *s) spin_unlock_irqrestore(&s->lock, flags); } -void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) __acquires(&s->lock) +void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) + __acquires(&s->lock) { spin_lock_irqsave(&s->lock, *flags); s->frozen = true; s->convert = NULL; } -void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) __releases(&s->lock) +void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) + __releases(&s->lock) { spin_unlock_irqrestore(&s->lock, *flags); } @@ -600,8 +605,8 @@ out_unlock: kfree_rcu(victim, rcu_member); } -int sidtab_sid2str_get(struct sidtab *s, struct sidtab_entry *entry, - char **out, u32 *out_len) +int sidtab_sid2str_get(struct sidtab *s, struct sidtab_entry *entry, char **out, + u32 *out_len) { struct sidtab_str_cache *cache; int rc = 0; diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index 22258201cd14..832c85c70d83 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -8,6 +8,7 @@ * * Copyright (C) 2018 Red Hat, Inc. */ + #ifndef _SS_SIDTAB_H_ #define _SS_SIDTAB_H_ @@ -29,25 +30,26 @@ struct sidtab_entry { union sidtab_entry_inner { struct sidtab_node_inner *ptr_inner; - struct sidtab_node_leaf *ptr_leaf; + struct sidtab_node_leaf *ptr_leaf; }; /* align node size to page boundary */ #define SIDTAB_NODE_ALLOC_SHIFT PAGE_SHIFT -#define SIDTAB_NODE_ALLOC_SIZE PAGE_SIZE +#define SIDTAB_NODE_ALLOC_SIZE PAGE_SIZE -#define size_to_shift(size) ((size) == 1 ? 1 : (const_ilog2((size) - 1) + 1)) +#define size_to_shift(size) ((size) == 1 ? 1 : (const_ilog2((size)-1) + 1)) -#define SIDTAB_INNER_SHIFT \ - (SIDTAB_NODE_ALLOC_SHIFT - size_to_shift(sizeof(union sidtab_entry_inner))) +#define SIDTAB_INNER_SHIFT \ + (SIDTAB_NODE_ALLOC_SHIFT - \ + size_to_shift(sizeof(union sidtab_entry_inner))) #define SIDTAB_INNER_ENTRIES ((size_t)1 << SIDTAB_INNER_SHIFT) #define SIDTAB_LEAF_ENTRIES \ (SIDTAB_NODE_ALLOC_SIZE / sizeof(struct sidtab_entry)) #define SIDTAB_MAX_BITS 32 -#define SIDTAB_MAX U32_MAX +#define SIDTAB_MAX U32_MAX /* ensure enough tree levels for SIDTAB_MAX entries */ -#define SIDTAB_MAX_LEVEL \ +#define SIDTAB_MAX_LEVEL \ DIV_ROUND_UP(SIDTAB_MAX_BITS - size_to_shift(SIDTAB_LEAF_ENTRIES), \ SIDTAB_INNER_SHIFT) @@ -69,7 +71,7 @@ struct sidtab_convert_params { struct sidtab *target; }; -#define SIDTAB_HASH_BITS CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS +#define SIDTAB_HASH_BITS CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS #define SIDTAB_HASH_BUCKETS (1 << SIDTAB_HASH_BITS) struct sidtab { @@ -125,8 +127,10 @@ int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params); void sidtab_cancel_convert(struct sidtab *s); -void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) __acquires(&s->lock); -void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) __releases(&s->lock); +void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) + __acquires(&s->lock); +void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) + __releases(&s->lock); int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid); @@ -137,8 +141,8 @@ int sidtab_hash_stats(struct sidtab *sidtab, char *page); #if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 void sidtab_sid2str_put(struct sidtab *s, struct sidtab_entry *entry, const char *str, u32 str_len); -int sidtab_sid2str_get(struct sidtab *s, struct sidtab_entry *entry, - char **out, u32 *out_len); +int sidtab_sid2str_get(struct sidtab *s, struct sidtab_entry *entry, char **out, + u32 *out_len); #else static inline void sidtab_sid2str_put(struct sidtab *s, struct sidtab_entry *entry, @@ -146,13 +150,11 @@ static inline void sidtab_sid2str_put(struct sidtab *s, { } static inline int sidtab_sid2str_get(struct sidtab *s, - struct sidtab_entry *entry, - char **out, u32 *out_len) + struct sidtab_entry *entry, char **out, + u32 *out_len) { return -ENOENT; } #endif /* CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 */ -#endif /* _SS_SIDTAB_H_ */ - - +#endif /* _SS_SIDTAB_H_ */ diff --git a/security/selinux/ss/symtab.c b/security/selinux/ss/symtab.c index 43d7f0319ccd..832660fd84a9 100644 --- a/security/selinux/ss/symtab.c +++ b/security/selinux/ss/symtab.c @@ -4,6 +4,7 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #include <linux/kernel.h> #include <linux/string.h> #include <linux/errno.h> @@ -11,16 +12,17 @@ static unsigned int symhash(const void *key) { - const char *p, *keyp; - unsigned int size; - unsigned int val; - - val = 0; - keyp = key; - size = strlen(keyp); - for (p = keyp; (p - keyp) < size; p++) - val = (val << 4 | (val >> (8*sizeof(unsigned int)-4))) ^ (*p); - return val; + /* + * djb2a + * Public domain from cdb v0.75 + */ + unsigned int hash = 5381; + unsigned char c; + + while ((c = *(const unsigned char *)key++)) + hash = ((hash << 5) + hash) ^ c; + + return hash; } static int symcmp(const void *key1, const void *key2) diff --git a/security/selinux/ss/symtab.h b/security/selinux/ss/symtab.h index 0a3b5de79a0f..8e667cdbf38f 100644 --- a/security/selinux/ss/symtab.h +++ b/security/selinux/ss/symtab.h @@ -7,14 +7,15 @@ * * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #ifndef _SS_SYMTAB_H_ #define _SS_SYMTAB_H_ #include "hashtab.h" struct symtab { - struct hashtab table; /* hash table (keyed on a string) */ - u32 nprim; /* number of primary names in table */ + struct hashtab table; /* hash table (keyed on a string) */ + u32 nprim; /* number of primary names in table */ }; int symtab_init(struct symtab *s, u32 size); @@ -22,6 +23,4 @@ int symtab_init(struct symtab *s, u32 size); int symtab_insert(struct symtab *s, char *name, void *datum); void *symtab_search(struct symtab *s, const char *name); -#endif /* _SS_SYMTAB_H_ */ - - +#endif /* _SS_SYMTAB_H_ */ |