diff options
Diffstat (limited to 'security/selinux/ss')
-rw-r--r-- | security/selinux/ss/avtab.c | 66 | ||||
-rw-r--r-- | security/selinux/ss/conditional.c | 76 | ||||
-rw-r--r-- | security/selinux/ss/ebitmap.c | 19 | ||||
-rw-r--r-- | security/selinux/ss/hashtab.c | 4 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 27 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 213 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 292 | ||||
-rw-r--r-- | security/selinux/ss/sidtab.c | 6 |
9 files changed, 372 insertions, 333 deletions
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index cd10e27fc9e6..9e6626362bfd 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -6,15 +6,15 @@ /* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> * - * Added conditional policy language extensions + * 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 + * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. * * 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/kernel.h> @@ -33,10 +33,10 @@ static inline int avtab_hash(struct avtab_key *keyp, u16 mask) static struct avtab_node* avtab_insert_node(struct avtab *h, int hvalue, - struct avtab_node * prev, struct avtab_node * cur, + struct avtab_node *prev, struct avtab_node *cur, struct avtab_key *key, struct avtab_datum *datum) { - struct avtab_node * newnode; + struct avtab_node *newnode; newnode = kmem_cache_zalloc(avtab_node_cachep, GFP_KERNEL); if (newnode == NULL) return NULL; @@ -84,7 +84,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat } newnode = avtab_insert_node(h, hvalue, prev, cur, key, datum); - if(!newnode) + if (!newnode) return -ENOMEM; return 0; @@ -95,7 +95,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat * It also returns a pointer to the node inserted. */ struct avtab_node * -avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_datum * datum) +avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datum *datum) { int hvalue; struct avtab_node *prev, *cur, *newnode; @@ -280,8 +280,8 @@ int avtab_alloc(struct avtab *h, u32 nrules) h->nel = 0; h->nslot = nslot; h->mask = mask; - printk(KERN_DEBUG "SELinux:%d avtab hash slots allocated. " - "Num of rules:%d\n", h->nslot, nrules); + printk(KERN_DEBUG "SELinux: %d avtab hash slots, %d rules.\n", + h->nslot, nrules); return 0; } @@ -310,8 +310,8 @@ void avtab_hash_eval(struct avtab *h, char *tag) } } - printk(KERN_DEBUG "%s: %d entries and %d/%d buckets used, longest " - "chain length %d sum of chain length^2 %Lu\n", + printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, " + "longest chain length %d sum of chain length^2 %Lu\n", tag, h->nel, slots_used, h->nslot, max_chain_len, chain2_len_sum); } @@ -326,7 +326,7 @@ static uint16_t spec_order[] = { }; int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, - int (*insertf)(struct avtab *a, struct avtab_key *k, + int (*insertf)(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *p), void *p) { @@ -345,18 +345,18 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, if (vers < POLICYDB_VERSION_AVTAB) { rc = next_entry(buf32, fp, sizeof(u32)); if (rc < 0) { - printk(KERN_ERR "security: avtab: truncated entry\n"); + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return -1; } items2 = le32_to_cpu(buf32[0]); if (items2 > ARRAY_SIZE(buf32)) { - printk(KERN_ERR "security: avtab: entry overflow\n"); + printk(KERN_ERR "SELinux: avtab: entry overflow\n"); return -1; } rc = next_entry(buf32, fp, sizeof(u32)*items2); if (rc < 0) { - printk(KERN_ERR "security: avtab: truncated entry\n"); + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return -1; } items = 0; @@ -364,19 +364,19 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, val = le32_to_cpu(buf32[items++]); key.source_type = (u16)val; if (key.source_type != val) { - printk("security: avtab: truncated source type\n"); + printk(KERN_ERR "SELinux: avtab: truncated source type\n"); return -1; } val = le32_to_cpu(buf32[items++]); key.target_type = (u16)val; if (key.target_type != val) { - printk("security: avtab: truncated target type\n"); + printk(KERN_ERR "SELinux: avtab: truncated target type\n"); return -1; } val = le32_to_cpu(buf32[items++]); key.target_class = (u16)val; if (key.target_class != val) { - printk("security: avtab: truncated target class\n"); + printk(KERN_ERR "SELinux: avtab: truncated target class\n"); return -1; } @@ -384,12 +384,12 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0; if (!(val & (AVTAB_AV | AVTAB_TYPE))) { - printk("security: avtab: null entry\n"); + printk(KERN_ERR "SELinux: avtab: null entry\n"); return -1; } if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) { - printk("security: avtab: entry has both access vectors and types\n"); + printk(KERN_ERR "SELinux: avtab: entry has both access vectors and types\n"); return -1; } @@ -398,12 +398,13 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, key.specified = spec_order[i] | enabled; datum.data = le32_to_cpu(buf32[items++]); rc = insertf(a, &key, &datum, p); - if (rc) return rc; + if (rc) + return rc; } } if (items != items2) { - printk("security: avtab: entry only had %d items, expected %d\n", items2, items); + printk(KERN_ERR "SELinux: avtab: entry only had %d items, expected %d\n", items2, items); return -1; } return 0; @@ -411,7 +412,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, rc = next_entry(buf16, fp, sizeof(u16)*4); if (rc < 0) { - printk("security: avtab: truncated entry\n"); + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return -1; } @@ -424,7 +425,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, if (!policydb_type_isvalid(pol, key.source_type) || !policydb_type_isvalid(pol, key.target_type) || !policydb_class_isvalid(pol, key.target_class)) { - printk(KERN_WARNING "security: avtab: invalid type or class\n"); + printk(KERN_ERR "SELinux: avtab: invalid type or class\n"); return -1; } @@ -434,20 +435,19 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, set++; } if (!set || set > 1) { - printk(KERN_WARNING - "security: avtab: more than one specifier\n"); + printk(KERN_ERR "SELinux: avtab: more than one specifier\n"); return -1; } rc = next_entry(buf32, fp, sizeof(u32)); if (rc < 0) { - printk("security: avtab: truncated entry\n"); + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return -1; } datum.data = le32_to_cpu(*buf32); if ((key.specified & AVTAB_TYPE) && !policydb_type_isvalid(pol, datum.data)) { - printk(KERN_WARNING "security: avtab: invalid type\n"); + printk(KERN_ERR "SELinux: avtab: invalid type\n"); return -1; } return insertf(a, &key, &datum, p); @@ -468,12 +468,12 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol) rc = next_entry(buf, fp, sizeof(u32)); if (rc < 0) { - printk(KERN_ERR "security: avtab: truncated table\n"); + printk(KERN_ERR "SELinux: avtab: truncated table\n"); goto bad; } nel = le32_to_cpu(buf[0]); if (!nel) { - printk(KERN_ERR "security: avtab: table is empty\n"); + printk(KERN_ERR "SELinux: avtab: table is empty\n"); rc = -EINVAL; goto bad; } @@ -486,9 +486,9 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol) rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL); if (rc) { if (rc == -ENOMEM) - printk(KERN_ERR "security: avtab: out of memory\n"); + printk(KERN_ERR "SELinux: avtab: out of memory\n"); else if (rc == -EEXIST) - printk(KERN_ERR "security: avtab: duplicate entry\n"); + printk(KERN_ERR "SELinux: avtab: duplicate entry\n"); else rc = -EINVAL; goto bad; @@ -513,5 +513,5 @@ void avtab_cache_init(void) void avtab_cache_destroy(void) { - kmem_cache_destroy (avtab_node_cachep); + kmem_cache_destroy(avtab_node_cachep); } diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 50ad85d4b77c..fb4efe4f4bc8 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -1,9 +1,9 @@ /* Authors: Karl MacMillan <kmacmillan@tresys.com> - * Frank Mayer <mayerf@tresys.com> + * Frank Mayer <mayerf@tresys.com> * * Copyright (C) 2003 - 2004 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 + * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. */ @@ -11,7 +11,6 @@ #include <linux/errno.h> #include <linux/string.h> #include <linux/spinlock.h> -#include <asm/semaphore.h> #include <linux/slab.h> #include "security.h" @@ -90,29 +89,27 @@ static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr) int evaluate_cond_node(struct policydb *p, struct cond_node *node) { int new_state; - struct cond_av_list* cur; + struct cond_av_list *cur; new_state = cond_evaluate_expr(p, node->expr); if (new_state != node->cur_state) { node->cur_state = new_state; if (new_state == -1) - printk(KERN_ERR "security: expression result was undefined - disabling all rules.\n"); + printk(KERN_ERR "SELinux: expression result was undefined - disabling all rules.\n"); /* turn the rules on or off */ for (cur = node->true_list; cur != NULL; cur = cur->next) { - if (new_state <= 0) { + if (new_state <= 0) cur->node->key.specified &= ~AVTAB_ENABLED; - } else { + else cur->node->key.specified |= AVTAB_ENABLED; - } } for (cur = node->false_list; cur != NULL; cur = cur->next) { /* -1 or 1 */ - if (new_state) { + if (new_state) cur->node->key.specified &= ~AVTAB_ENABLED; - } else { + else cur->node->key.specified |= AVTAB_ENABLED; - } } } return 0; @@ -174,8 +171,8 @@ 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 = (struct cond_bool_datum**) - kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum*), GFP_KERNEL); + p->bool_val_to_struct = (struct cond_bool_datum **) + kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL); if (!p->bool_val_to_struct) return -1; return 0; @@ -200,7 +197,7 @@ int cond_index_bool(void *key, void *datum, void *datap) return -EINVAL; p->p_bool_val_to_name[booldatum->value - 1] = key; - p->bool_val_to_struct[booldatum->value -1] = booldatum; + p->bool_val_to_struct[booldatum->value - 1] = booldatum; return 0; } @@ -252,8 +249,7 @@ err: return -1; } -struct cond_insertf_data -{ +struct cond_insertf_data { struct policydb *p; struct cond_av_list *other; struct cond_av_list *head; @@ -276,7 +272,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum */ if (k->specified & AVTAB_TYPE) { if (avtab_search(&p->te_avtab, k)) { - printk("security: type rule already exists outside of a conditional."); + printk(KERN_ERR "SELinux: type rule already exists outside of a conditional.\n"); goto err; } /* @@ -291,7 +287,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum node_ptr = avtab_search_node(&p->te_cond_avtab, k); if (node_ptr) { if (avtab_search_node_next(node_ptr, k->specified)) { - printk("security: too many conflicting type rules."); + printk(KERN_ERR "SELinux: too many conflicting type rules.\n"); goto err; } found = 0; @@ -302,13 +298,13 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum } } if (!found) { - printk("security: conflicting type rules.\n"); + printk(KERN_ERR "SELinux: conflicting type rules.\n"); goto err; } } } else { if (avtab_search(&p->te_cond_avtab, k)) { - printk("security: conflicting type rules when adding type rule for true.\n"); + printk(KERN_ERR "SELinux: conflicting type rules when adding type rule for true.\n"); goto err; } } @@ -316,7 +312,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d); if (!node_ptr) { - printk("security: could not insert rule."); + printk(KERN_ERR "SELinux: could not insert rule.\n"); goto err; } @@ -353,9 +349,8 @@ static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list * return -1; len = le32_to_cpu(buf[0]); - if (len == 0) { + if (len == 0) return 0; - } data.p = p; data.other = other; @@ -376,12 +371,12 @@ static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list * static int expr_isvalid(struct policydb *p, struct cond_expr *expr) { if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) { - printk("security: conditional expressions uses unknown operator.\n"); + printk(KERN_ERR "SELinux: conditional expressions uses unknown operator.\n"); return 0; } if (expr->bool > p->p_bools.nprim) { - printk("security: conditional expressions uses unknown bool.\n"); + printk(KERN_ERR "SELinux: conditional expressions uses unknown bool.\n"); return 0; } return 1; @@ -408,15 +403,14 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) /* expr */ len = le32_to_cpu(buf[0]); - for (i = 0; i < len; i++ ) { + for (i = 0; i < len; i++) { rc = next_entry(buf, fp, sizeof(u32) * 2); if (rc < 0) goto err; expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL); - if (!expr) { + if (!expr) goto err; - } expr->expr_type = le32_to_cpu(buf[0]); expr->bool = le32_to_cpu(buf[1]); @@ -426,11 +420,10 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) goto err; } - if (i == 0) { + if (i == 0) node->expr = expr; - } else { + else last->next = expr; - } last = expr; } @@ -469,11 +462,10 @@ int cond_read_list(struct policydb *p, void *fp) if (cond_read_node(p, node, fp) != 0) goto err; - if (i == 0) { + if (i == 0) p->cond_list = node; - } else { + else last->next = node; - } last = node; } return 0; @@ -490,24 +482,24 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi { struct avtab_node *node; - if(!ctab || !key || !avd) + if (!ctab || !key || !avd) return; - for(node = avtab_search_node(ctab, key); node != NULL; + for (node = avtab_search_node(ctab, key); node != NULL; node = avtab_search_node_next(node, key->specified)) { - if ( (u16) (AVTAB_ALLOWED|AVTAB_ENABLED) == - (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) + if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) == + (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) avd->allowed |= node->datum.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.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.data; } return; diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index 920b5e36a1af..ddc275490af8 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c @@ -364,7 +364,7 @@ int ebitmap_read(struct ebitmap *e, void *fp) count = le32_to_cpu(buf[2]); if (mapunit != sizeof(u64) * 8) { - printk(KERN_ERR "security: ebitmap: map size %u does not " + printk(KERN_ERR "SELinux: ebitmap: map size %u does not " "match my size %Zd (high bit was %d)\n", mapunit, sizeof(u64) * 8, e->highbit); goto bad; @@ -382,19 +382,19 @@ int ebitmap_read(struct ebitmap *e, void *fp) for (i = 0; i < count; i++) { rc = next_entry(&startbit, fp, sizeof(u32)); if (rc < 0) { - printk(KERN_ERR "security: ebitmap: truncated map\n"); + printk(KERN_ERR "SELinux: ebitmap: truncated map\n"); goto bad; } startbit = le32_to_cpu(startbit); if (startbit & (mapunit - 1)) { - printk(KERN_ERR "security: ebitmap start bit (%d) is " + printk(KERN_ERR "SELinux: ebitmap start bit (%d) is " "not a multiple of the map unit size (%u)\n", startbit, mapunit); goto bad; } if (startbit > e->highbit - mapunit) { - printk(KERN_ERR "security: ebitmap start bit (%d) is " + printk(KERN_ERR "SELinux: ebitmap start bit (%d) is " "beyond the end of the bitmap (%u)\n", startbit, (e->highbit - mapunit)); goto bad; @@ -405,20 +405,19 @@ int ebitmap_read(struct ebitmap *e, void *fp) tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); if (!tmp) { printk(KERN_ERR - "security: ebitmap: out of memory\n"); + "SELinux: ebitmap: out of memory\n"); rc = -ENOMEM; goto bad; } /* round down */ tmp->startbit = startbit - (startbit % EBITMAP_SIZE); - if (n) { + if (n) n->next = tmp; - } else { + else e->node = tmp; - } n = tmp; } else if (startbit <= n->startbit) { - printk(KERN_ERR "security: ebitmap: start bit %d" + printk(KERN_ERR "SELinux: ebitmap: start bit %d" " comes after start bit %d\n", startbit, n->startbit); goto bad; @@ -426,7 +425,7 @@ int ebitmap_read(struct ebitmap *e, void *fp) rc = next_entry(&map, fp, sizeof(u64)); if (rc < 0) { - printk(KERN_ERR "security: ebitmap: truncated map\n"); + printk(KERN_ERR "SELinux: ebitmap: truncated map\n"); goto bad; } map = le64_to_cpu(map); diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index 77b530c3bbce..2e7788e13213 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -9,8 +9,8 @@ #include "hashtab.h" struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), - int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), - u32 size) + int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), + u32 size) { struct hashtab *p; u32 i; diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index feaf0a5b828f..8b1706b7b3cc 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -32,7 +32,7 @@ * Return the length in bytes for the MLS fields of the * security context string representation of `context'. */ -int mls_compute_context_len(struct context * context) +int mls_compute_context_len(struct context *context) { int i, l, len, head, prev; char *nm; @@ -86,7 +86,7 @@ int mls_compute_context_len(struct context * context) * Update `*scontext' to point to the end of the MLS fields. */ void mls_sid_to_context(struct context *context, - char **scontext) + char **scontext) { char *scontextp, *nm; int i, l, head, prev; @@ -146,7 +146,7 @@ void mls_sid_to_context(struct context *context, if (l == 0) { if (mls_level_eq(&context->range.level[0], - &context->range.level[1])) + &context->range.level[1])) break; else *scontextp++ = '-'; @@ -305,20 +305,21 @@ int mls_context_to_sid(char oldc, *p++ = 0; /* Separate into range if exists */ - if ((rngptr = strchr(scontextp, '.')) != NULL) { + rngptr = strchr(scontextp, '.'); + if (rngptr != NULL) { /* Remove '.' */ *rngptr++ = 0; } catdatum = hashtab_search(policydb.p_cats.table, - scontextp); + scontextp); if (!catdatum) { rc = -EINVAL; goto out; } rc = ebitmap_set_bit(&context->range.level[l].cat, - catdatum->value - 1, 1); + catdatum->value - 1, 1); if (rc) goto out; @@ -395,7 +396,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) rc = -ENOMEM; } else { rc = mls_context_to_sid(':', &tmpstr, context, - NULL, SECSID_NULL); + NULL, SECSID_NULL); kfree(freestr); } @@ -406,7 +407,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) * Copies the MLS range `range' into `context'. */ static inline int mls_range_set(struct context *context, - struct mls_range *range) + struct mls_range *range) { int l, rc = 0; @@ -423,7 +424,7 @@ static inline int mls_range_set(struct context *context, } int mls_setup_user_range(struct context *fromcon, struct user_datum *user, - struct context *usercon) + struct context *usercon) { if (selinux_mls_enabled) { struct mls_level *fromcon_sen = &(fromcon->range.level[0]); @@ -449,11 +450,11 @@ int mls_setup_user_range(struct context *fromcon, struct user_datum *user, that of the user's default clearance (but only if the "fromcon" clearance dominates the user's computed sensitivity level) */ - if (mls_level_dom(user_clr, fromcon_clr)) { + if (mls_level_dom(user_clr, fromcon_clr)) *usercon_clr = *fromcon_clr; - } else if (mls_level_dom(fromcon_clr, user_clr)) { + else if (mls_level_dom(fromcon_clr, user_clr)) *usercon_clr = *user_clr; - } else + else return -EINVAL; } @@ -525,7 +526,7 @@ int mls_compute_sid(struct context *scontext, rtr->target_class == tclass) { /* Set the range from the rule */ return mls_range_set(newcontext, - &rtr->target_range); + &rtr->target_range); } } /* Fallthrough */ diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index bd7d6a00342d..84f8cc73c7db 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -11,7 +11,7 @@ * * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> * - * Added conditional policy language extensions + * Added conditional policy language extensions * * Updated: Hewlett-Packard <paul.moore@hp.com> * @@ -21,7 +21,7 @@ * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2004 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 + * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. */ @@ -51,7 +51,7 @@ static char *symtab_name[SYM_NUM] = { }; #endif -int selinux_mls_enabled = 0; +int selinux_mls_enabled; static unsigned int symtab_sizes[SYM_NUM] = { 2, @@ -73,44 +73,49 @@ struct policydb_compat_info { /* These need to be updated if SYM_NUM or OCON_NUM changes */ static struct policydb_compat_info policydb_compat[] = { { - .version = POLICYDB_VERSION_BASE, - .sym_num = SYM_NUM - 3, - .ocon_num = OCON_NUM - 1, + .version = POLICYDB_VERSION_BASE, + .sym_num = SYM_NUM - 3, + .ocon_num = OCON_NUM - 1, }, { - .version = POLICYDB_VERSION_BOOL, - .sym_num = SYM_NUM - 2, - .ocon_num = OCON_NUM - 1, + .version = POLICYDB_VERSION_BOOL, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_NUM - 1, }, { - .version = POLICYDB_VERSION_IPV6, - .sym_num = SYM_NUM - 2, - .ocon_num = OCON_NUM, + .version = POLICYDB_VERSION_IPV6, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_NUM, }, { - .version = POLICYDB_VERSION_NLCLASS, - .sym_num = SYM_NUM - 2, - .ocon_num = OCON_NUM, + .version = POLICYDB_VERSION_NLCLASS, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_NUM, }, { - .version = POLICYDB_VERSION_MLS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, + .version = POLICYDB_VERSION_MLS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, }, { - .version = POLICYDB_VERSION_AVTAB, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, + .version = POLICYDB_VERSION_AVTAB, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, }, { - .version = POLICYDB_VERSION_RANGETRANS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, + .version = POLICYDB_VERSION_RANGETRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, }, { .version = POLICYDB_VERSION_POLCAP, .sym_num = SYM_NUM, .ocon_num = OCON_NUM, + }, + { + .version = POLICYDB_VERSION_PERMISSIVE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, } }; @@ -147,7 +152,7 @@ static int roles_init(struct policydb *p) rc = -EINVAL; goto out_free_role; } - key = kmalloc(strlen(OBJECT_R)+1,GFP_KERNEL); + key = kmalloc(strlen(OBJECT_R)+1, GFP_KERNEL); if (!key) { rc = -ENOMEM; goto out_free_role; @@ -194,6 +199,7 @@ static int policydb_init(struct policydb *p) goto out_free_symtab; ebitmap_init(&p->policycaps); + ebitmap_init(&p->permissive_map); out: return rc; @@ -384,7 +390,7 @@ static void symtab_hash_eval(struct symtab *s) struct hashtab_info info; hashtab_stat(h, &info); - printk(KERN_DEBUG "%s: %d entries and %d/%d buckets used, " + printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, " "longest chain length %d\n", symtab_name[i], h->nel, info.slots_used, h->size, info.max_chain_len); } @@ -401,14 +407,14 @@ static int policydb_index_others(struct policydb *p) { int i, rc = 0; - printk(KERN_DEBUG "security: %d users, %d roles, %d types, %d bools", + printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); if (selinux_mls_enabled) printk(", %d sens, %d cats", p->p_levels.nprim, p->p_cats.nprim); printk("\n"); - printk(KERN_DEBUG "security: %d classes, %d rules\n", + printk(KERN_DEBUG "SELinux: %d classes, %d rules\n", p->p_classes.nprim, p->te_avtab.nel); #ifdef DEBUG_HASHES @@ -418,7 +424,7 @@ static int policydb_index_others(struct policydb *p) p->role_val_to_struct = kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), - GFP_KERNEL); + GFP_KERNEL); if (!p->role_val_to_struct) { rc = -ENOMEM; goto out; @@ -426,7 +432,7 @@ static int policydb_index_others(struct policydb *p) p->user_val_to_struct = kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), - GFP_KERNEL); + GFP_KERNEL); if (!p->user_val_to_struct) { rc = -ENOMEM; goto out; @@ -628,7 +634,7 @@ void policydb_destroy(struct policydb *p) while (c) { ctmp = c; c = c->next; - ocontext_destroy(ctmp,i); + ocontext_destroy(ctmp, i); } p->ocontexts[i] = NULL; } @@ -641,7 +647,7 @@ void policydb_destroy(struct policydb *p) while (c) { ctmp = c; c = c->next; - ocontext_destroy(ctmp,OCON_FSUSE); + ocontext_destroy(ctmp, OCON_FSUSE); } gtmp = g; g = g->next; @@ -658,14 +664,14 @@ void policydb_destroy(struct policydb *p) } kfree(ltr); - for (ra = p->role_allow; ra; ra = ra -> next) { + for (ra = p->role_allow; ra; ra = ra->next) { cond_resched(); kfree(lra); lra = ra; } kfree(lra); - for (rt = p->range_tr; rt; rt = rt -> next) { + for (rt = p->range_tr; rt; rt = rt->next) { cond_resched(); if (lrt) { ebitmap_destroy(&lrt->target_range.level[0].cat); @@ -687,6 +693,7 @@ void policydb_destroy(struct policydb *p) kfree(p->type_attr_map); kfree(p->undefined_perms); ebitmap_destroy(&p->policycaps); + ebitmap_destroy(&p->permissive_map); return; } @@ -702,20 +709,20 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) rc = sidtab_init(s); if (rc) { - printk(KERN_ERR "security: out of memory on SID table init\n"); + printk(KERN_ERR "SELinux: out of memory on SID table init\n"); goto out; } head = p->ocontexts[OCON_ISID]; for (c = head; c; c = c->next) { if (!c->context[0].user) { - printk(KERN_ERR "security: SID %s was never " + printk(KERN_ERR "SELinux: SID %s was never " "defined.\n", c->u.name); rc = -EINVAL; goto out; } if (sidtab_insert(s, c->sid[0], &c->context[0])) { - printk(KERN_ERR "security: unable to load initial " + printk(KERN_ERR "SELinux: unable to load initial " "SID %s.\n", c->u.name); rc = -EINVAL; goto out; @@ -809,13 +816,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) items = le32_to_cpu(buf[0]); if (items > ARRAY_SIZE(buf)) { - printk(KERN_ERR "security: mls: range overflow\n"); + printk(KERN_ERR "SELinux: mls: range overflow\n"); rc = -EINVAL; goto out; } rc = next_entry(buf, fp, sizeof(u32) * items); if (rc < 0) { - printk(KERN_ERR "security: mls: truncated range\n"); + printk(KERN_ERR "SELinux: mls: truncated range\n"); goto out; } r->level[0].sens = le32_to_cpu(buf[0]); @@ -826,21 +833,21 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) rc = ebitmap_read(&r->level[0].cat, fp); if (rc) { - printk(KERN_ERR "security: mls: error reading low " + printk(KERN_ERR "SELinux: mls: error reading low " "categories\n"); goto out; } if (items > 1) { rc = ebitmap_read(&r->level[1].cat, fp); if (rc) { - printk(KERN_ERR "security: mls: error reading high " + printk(KERN_ERR "SELinux: mls: error reading high " "categories\n"); goto bad_high; } } else { rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat); if (rc) { - printk(KERN_ERR "security: mls: out of memory\n"); + printk(KERN_ERR "SELinux: mls: out of memory\n"); goto bad_high; } } @@ -866,7 +873,7 @@ static int context_read_and_validate(struct context *c, rc = next_entry(buf, fp, sizeof buf); if (rc < 0) { - printk(KERN_ERR "security: context truncated\n"); + printk(KERN_ERR "SELinux: context truncated\n"); goto out; } c->user = le32_to_cpu(buf[0]); @@ -874,7 +881,7 @@ static int context_read_and_validate(struct context *c, c->type = le32_to_cpu(buf[2]); if (p->policyvers >= POLICYDB_VERSION_MLS) { if (mls_read_range_helper(&c->range, fp)) { - printk(KERN_ERR "security: error reading MLS range of " + printk(KERN_ERR "SELinux: error reading MLS range of " "context\n"); rc = -EINVAL; goto out; @@ -882,7 +889,7 @@ static int context_read_and_validate(struct context *c, } if (!policydb_context_isvalid(p, c)) { - printk(KERN_ERR "security: invalid security context\n"); + printk(KERN_ERR "SELinux: invalid security context\n"); context_destroy(c); rc = -EINVAL; } @@ -917,7 +924,7 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp) len = le32_to_cpu(buf[0]); perdatum->value = le32_to_cpu(buf[1]); - key = kmalloc(len + 1,GFP_KERNEL); + key = kmalloc(len + 1, GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; @@ -964,7 +971,7 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) comdatum->permissions.nprim = le32_to_cpu(buf[2]); nel = le32_to_cpu(buf[3]); - key = kmalloc(len + 1,GFP_KERNEL); + key = kmalloc(len + 1, GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; @@ -991,7 +998,7 @@ bad: } static int read_cons_helper(struct constraint_node **nodep, int ncons, - int allowxtarget, void *fp) + int allowxtarget, void *fp) { struct constraint_node *c, *lc; struct constraint_expr *e, *le; @@ -1005,11 +1012,10 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, if (!c) return -ENOMEM; - if (lc) { + if (lc) lc->next = c; - } else { + else *nodep = c; - } rc = next_entry(buf, fp, (sizeof(u32) * 2)); if (rc < 0) @@ -1023,11 +1029,10 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, if (!e) return -ENOMEM; - if (le) { + if (le) le->next = e; - } else { + else c->expr = e; - } rc = next_entry(buf, fp, (sizeof(u32) * 3)); if (rc < 0) @@ -1104,7 +1109,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) ncons = le32_to_cpu(buf[5]); - key = kmalloc(len + 1,GFP_KERNEL); + key = kmalloc(len + 1, GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; @@ -1115,7 +1120,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) key[len] = 0; if (len2) { - cladatum->comkey = kmalloc(len2 + 1,GFP_KERNEL); + cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); if (!cladatum->comkey) { rc = -ENOMEM; goto bad; @@ -1128,7 +1133,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey); if (!cladatum->comdatum) { - printk(KERN_ERR "security: unknown common %s\n", + printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey); rc = -EINVAL; goto bad; @@ -1188,7 +1193,7 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) len = le32_to_cpu(buf[0]); role->value = le32_to_cpu(buf[1]); - key = kmalloc(len + 1,GFP_KERNEL); + key = kmalloc(len + 1, GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; @@ -1208,7 +1213,7 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) if (strcmp(key, OBJECT_R) == 0) { if (role->value != OBJECT_R_VAL) { - printk(KERN_ERR "Role %s has wrong value %d\n", + printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", OBJECT_R, role->value); rc = -EINVAL; goto bad; @@ -1235,7 +1240,7 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[3]; u32 len; - typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL); + typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); if (!typdatum) { rc = -ENOMEM; return rc; @@ -1249,7 +1254,7 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) typdatum->value = le32_to_cpu(buf[1]); typdatum->primary = le32_to_cpu(buf[2]); - key = kmalloc(len + 1,GFP_KERNEL); + key = kmalloc(len + 1, GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; @@ -1283,13 +1288,13 @@ static int mls_read_level(struct mls_level *lp, void *fp) rc = next_entry(buf, fp, sizeof buf); if (rc < 0) { - printk(KERN_ERR "security: mls: truncated level\n"); + printk(KERN_ERR "SELinux: mls: truncated level\n"); goto bad; } lp->sens = le32_to_cpu(buf[0]); if (ebitmap_read(&lp->cat, fp)) { - printk(KERN_ERR "security: mls: error reading level " + printk(KERN_ERR "SELinux: mls: error reading level " "categories\n"); goto bad; } @@ -1321,7 +1326,7 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) len = le32_to_cpu(buf[0]); usrdatum->value = le32_to_cpu(buf[1]); - key = kmalloc(len + 1,GFP_KERNEL); + key = kmalloc(len + 1, GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; @@ -1375,7 +1380,7 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp) len = le32_to_cpu(buf[0]); levdatum->isalias = le32_to_cpu(buf[1]); - key = kmalloc(len + 1,GFP_ATOMIC); + key = kmalloc(len + 1, GFP_ATOMIC); if (!key) { rc = -ENOMEM; goto bad; @@ -1427,7 +1432,7 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp) catdatum->value = le32_to_cpu(buf[1]); catdatum->isalias = le32_to_cpu(buf[2]); - key = kmalloc(len + 1,GFP_ATOMIC); + key = kmalloc(len + 1, GFP_ATOMIC); if (!key) { rc = -ENOMEM; goto bad; @@ -1486,12 +1491,12 @@ int policydb_read(struct policydb *p, void *fp) goto out; /* Read the magic number and string length. */ - rc = next_entry(buf, fp, sizeof(u32)* 2); + rc = next_entry(buf, fp, sizeof(u32) * 2); if (rc < 0) goto bad; if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { - printk(KERN_ERR "security: policydb magic number 0x%x does " + printk(KERN_ERR "SELinux: policydb magic number 0x%x does " "not match expected magic number 0x%x\n", le32_to_cpu(buf[0]), POLICYDB_MAGIC); goto bad; @@ -1499,27 +1504,27 @@ int policydb_read(struct policydb *p, void *fp) len = le32_to_cpu(buf[1]); if (len != strlen(POLICYDB_STRING)) { - printk(KERN_ERR "security: policydb string length %d does not " + printk(KERN_ERR "SELinux: policydb string length %d does not " "match expected length %Zu\n", len, strlen(POLICYDB_STRING)); goto bad; } - policydb_str = kmalloc(len + 1,GFP_KERNEL); + policydb_str = kmalloc(len + 1, GFP_KERNEL); if (!policydb_str) { - printk(KERN_ERR "security: unable to allocate memory for policydb " + printk(KERN_ERR "SELinux: unable to allocate memory for policydb " "string of length %d\n", len); rc = -ENOMEM; goto bad; } rc = next_entry(policydb_str, fp, len); if (rc < 0) { - printk(KERN_ERR "security: truncated policydb string identifier\n"); + printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); kfree(policydb_str); goto bad; } policydb_str[len] = 0; if (strcmp(policydb_str, POLICYDB_STRING)) { - printk(KERN_ERR "security: policydb string %s does not match " + printk(KERN_ERR "SELinux: policydb string %s does not match " "my string %s\n", policydb_str, POLICYDB_STRING); kfree(policydb_str); goto bad; @@ -1536,30 +1541,31 @@ int policydb_read(struct policydb *p, void *fp) p->policyvers = le32_to_cpu(buf[0]); if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX) { - printk(KERN_ERR "security: policydb version %d does not match " - "my version range %d-%d\n", - le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); - goto bad; + printk(KERN_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); + goto bad; } if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { if (ss_initialized && !selinux_mls_enabled) { - printk(KERN_ERR "Cannot switch between non-MLS and MLS " - "policies\n"); + printk(KERN_ERR "SELinux: Cannot switch between non-MLS" + " and MLS policies\n"); goto bad; } selinux_mls_enabled = 1; config |= POLICYDB_CONFIG_MLS; if (p->policyvers < POLICYDB_VERSION_MLS) { - printk(KERN_ERR "security policydb version %d (MLS) " - "not backwards compatible\n", p->policyvers); + printk(KERN_ERR "SELinux: security policydb version %d " + "(MLS) not backwards compatible\n", + p->policyvers); goto bad; } } else { if (ss_initialized && selinux_mls_enabled) { - printk(KERN_ERR "Cannot switch between MLS and non-MLS " - "policies\n"); + printk(KERN_ERR "SELinux: Cannot switch between MLS and" + " non-MLS policies\n"); goto bad; } } @@ -1570,16 +1576,20 @@ int policydb_read(struct policydb *p, void *fp) ebitmap_read(&p->policycaps, fp) != 0) goto bad; + if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && + ebitmap_read(&p->permissive_map, fp) != 0) + goto bad; + info = policydb_lookup_compat(p->policyvers); if (!info) { - printk(KERN_ERR "security: unable to find policy compat info " + printk(KERN_ERR "SELinux: unable to find policy compat info " "for version %d\n", p->policyvers); goto bad; } if (le32_to_cpu(buf[2]) != info->sym_num || le32_to_cpu(buf[3]) != info->ocon_num) { - printk(KERN_ERR "security: policydb table sizes (%d,%d) do " + printk(KERN_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); @@ -1622,11 +1632,10 @@ int policydb_read(struct policydb *p, void *fp) rc = -ENOMEM; goto bad; } - if (ltr) { + if (ltr) ltr->next = tr; - } else { + else p->role_tr = tr; - } rc = next_entry(buf, fp, sizeof(u32)*3); if (rc < 0) goto bad; @@ -1653,11 +1662,10 @@ int policydb_read(struct policydb *p, void *fp) rc = -ENOMEM; goto bad; } - if (lra) { + if (lra) lra->next = ra; - } else { + else p->role_allow = ra; - } rc = next_entry(buf, fp, sizeof(u32)*2); if (rc < 0) goto bad; @@ -1691,11 +1699,10 @@ int policydb_read(struct policydb *p, void *fp) rc = -ENOMEM; goto bad; } - if (l) { + if (l) l->next = c; - } else { + else p->ocontexts[i] = c; - } l = c; rc = -EINVAL; switch (i) { @@ -1714,7 +1721,7 @@ int policydb_read(struct policydb *p, void *fp) if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); - c->u.name = kmalloc(len + 1,GFP_KERNEL); + c->u.name = kmalloc(len + 1, GFP_KERNEL); if (!c->u.name) { rc = -ENOMEM; goto bad; @@ -1742,7 +1749,7 @@ int policydb_read(struct policydb *p, void *fp) goto bad; break; case OCON_NODE: - rc = next_entry(buf, fp, sizeof(u32)* 2); + rc = next_entry(buf, fp, sizeof(u32) * 2); if (rc < 0) goto bad; c->u.node.addr = le32_to_cpu(buf[0]); @@ -1759,7 +1766,7 @@ int policydb_read(struct policydb *p, void *fp) if (c->v.behavior > SECURITY_FS_USE_NONE) goto bad; len = le32_to_cpu(buf[1]); - c->u.name = kmalloc(len + 1,GFP_KERNEL); + c->u.name = kmalloc(len + 1, GFP_KERNEL); if (!c->u.name) { rc = -ENOMEM; goto bad; @@ -1807,7 +1814,7 @@ int policydb_read(struct policydb *p, void *fp) goto bad; } - newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL); + newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL); if (!newgenfs->fstype) { rc = -ENOMEM; kfree(newgenfs); @@ -1823,7 +1830,7 @@ int policydb_read(struct policydb *p, void *fp) for (genfs_p = NULL, genfs = p->genfs; genfs; genfs_p = genfs, genfs = genfs->next) { if (strcmp(newgenfs->fstype, genfs->fstype) == 0) { - printk(KERN_ERR "security: dup genfs " + printk(KERN_ERR "SELinux: dup genfs " "fstype %s\n", newgenfs->fstype); kfree(newgenfs->fstype); kfree(newgenfs); @@ -1853,7 +1860,7 @@ int policydb_read(struct policydb *p, void *fp) goto bad; } - newc->u.name = kmalloc(len + 1,GFP_KERNEL); + newc->u.name = kmalloc(len + 1, GFP_KERNEL); if (!newc->u.name) { rc = -ENOMEM; goto bad_newc; @@ -1873,7 +1880,7 @@ int policydb_read(struct policydb *p, void *fp) if (!strcmp(newc->u.name, c->u.name) && (!c->v.sclass || !newc->v.sclass || newc->v.sclass == c->v.sclass)) { - printk(KERN_ERR "security: dup genfs " + printk(KERN_ERR "SELinux: dup genfs " "entry (%s,%s)\n", newgenfs->fstype, c->u.name); goto bad_newc; @@ -1931,7 +1938,7 @@ int policydb_read(struct policydb *p, void *fp) if (rc) goto bad; if (!mls_range_isvalid(p, &rt->target_range)) { - printk(KERN_WARNING "security: rangetrans: invalid range\n"); + printk(KERN_WARNING "SELinux: rangetrans: invalid range\n"); goto bad; } lrt = rt; @@ -1957,7 +1964,7 @@ int policydb_read(struct policydb *p, void *fp) out: return rc; bad_newc: - ocontext_destroy(newc,OCON_FSUSE); + ocontext_destroy(newc, OCON_FSUSE); bad: if (!rc) rc = -EINVAL; diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index c4ce996e202c..ba593a3da877 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -243,6 +243,8 @@ struct policydb { struct ebitmap policycaps; + struct ebitmap permissive_map; + unsigned int policyvers; unsigned int reject_unknown : 1; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 3f2bad28ee7b..2daaddbb301d 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2,7 +2,7 @@ * Implementation of the security services. * * Authors : Stephen Smalley, <sds@epoch.ncsc.mil> - * James Morris <jmorris@redhat.com> + * James Morris <jmorris@redhat.com> * * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> * @@ -11,7 +11,7 @@ * * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> * - * Added conditional policy language extensions + * Added conditional policy language extensions * * Updated: Hewlett-Packard <paul.moore@hp.com> * @@ -27,7 +27,7 @@ * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> * 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 + * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. */ #include <linux/kernel.h> @@ -40,6 +40,7 @@ #include <linux/sched.h> #include <linux/audit.h> #include <linux/mutex.h> +#include <linux/selinux.h> #include <net/netlabel.h> #include "flask.h" @@ -56,11 +57,13 @@ #include "netlabel.h" #include "xfrm.h" #include "ebitmap.h" +#include "audit.h" extern void selnl_notify_policyload(u32 seqno); unsigned int policydb_loaded_version; int selinux_policycap_netpeer; +int selinux_policycap_openperm; /* * This is declared in avc.c @@ -79,7 +82,7 @@ static DEFINE_MUTEX(load_mutex); static struct sidtab sidtab; struct policydb policydb; -int ss_initialized = 0; +int ss_initialized; /* * The largest sequence number that has been used when @@ -87,7 +90,7 @@ int ss_initialized = 0; * The sequence number only changes when a policy change * occurs. */ -static u32 latest_granting = 0; +static u32 latest_granting; /* Forward declaration. */ static int context_struct_to_string(struct context *context, char **scontext, @@ -160,10 +163,10 @@ static int constraint_expr_eval(struct context *scontext, val1 - 1); continue; case CEXPR_INCOMP: - s[++sp] = ( !ebitmap_get_bit(&r1->dominates, - val2 - 1) && - !ebitmap_get_bit(&r2->dominates, - val1 - 1) ); + s[++sp] = (!ebitmap_get_bit(&r1->dominates, + val2 - 1) && + !ebitmap_get_bit(&r2->dominates, + val1 - 1)); continue; default: break; @@ -406,20 +409,46 @@ static int context_struct_compute_av(struct context *scontext, } if (!ra) avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | - PROCESS__DYNTRANSITION); + PROCESS__DYNTRANSITION); } return 0; inval_class: - printk(KERN_ERR "%s: unrecognized class %d\n", __FUNCTION__, tclass); + printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", __func__, + tclass); return -EINVAL; } +/* + * Given a sid find if the type has the permissive flag set + */ +int security_permissive_sid(u32 sid) +{ + struct context *context; + u32 type; + int rc; + + POLICY_RDLOCK; + + context = sidtab_search(&sidtab, sid); + BUG_ON(!context); + + type = context->type; + /* + * we are intentionally using type here, not type-1, the 0th bit may + * someday indicate that we are globally setting permissive in policy. + */ + rc = ebitmap_get_bit(&policydb.permissive_map, type); + + POLICY_RDUNLOCK; + return rc; +} + static int security_validtrans_handle_fail(struct context *ocontext, - struct context *ncontext, - struct context *tcontext, - u16 tclass) + struct context *ncontext, + struct context *tcontext, + u16 tclass) { char *o = NULL, *n = NULL, *t = NULL; u32 olen, nlen, tlen; @@ -431,9 +460,9 @@ static int security_validtrans_handle_fail(struct context *ocontext, if (context_struct_to_string(tcontext, &t, &tlen) < 0) goto out; audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "security_validate_transition: denied for" - " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", - o, n, t, policydb.p_class_val_to_name[tclass-1]); + "security_validate_transition: denied for" + " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", + o, n, t, policydb.p_class_val_to_name[tclass-1]); out: kfree(o); kfree(n); @@ -445,7 +474,7 @@ out: } int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, - u16 tclass) + u16 tclass) { struct context *ocontext; struct context *ncontext; @@ -471,8 +500,8 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, tclass = SECCLASS_NETLINK_SOCKET; if (!tclass || tclass > policydb.p_classes.nprim) { - printk(KERN_ERR "security_validate_transition: " - "unrecognized class %d\n", tclass); + printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", + __func__, tclass); rc = -EINVAL; goto out; } @@ -480,24 +509,24 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, ocontext = sidtab_search(&sidtab, oldsid); if (!ocontext) { - printk(KERN_ERR "security_validate_transition: " - " unrecognized SID %d\n", oldsid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, oldsid); rc = -EINVAL; goto out; } ncontext = sidtab_search(&sidtab, newsid); if (!ncontext) { - printk(KERN_ERR "security_validate_transition: " - " unrecognized SID %d\n", newsid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, newsid); rc = -EINVAL; goto out; } tcontext = sidtab_search(&sidtab, tasksid); if (!tcontext) { - printk(KERN_ERR "security_validate_transition: " - " unrecognized SID %d\n", tasksid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, tasksid); rc = -EINVAL; goto out; } @@ -505,9 +534,9 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, constraint = tclass_datum->validatetrans; while (constraint) { if (!constraint_expr_eval(ocontext, ncontext, tcontext, - constraint->expr)) { + constraint->expr)) { rc = security_validtrans_handle_fail(ocontext, ncontext, - tcontext, tclass); + tcontext, tclass); goto out; } constraint = constraint->next; @@ -553,15 +582,15 @@ int security_compute_av(u32 ssid, scontext = sidtab_search(&sidtab, ssid); if (!scontext) { - printk(KERN_ERR "security_compute_av: unrecognized SID %d\n", - ssid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, ssid); rc = -EINVAL; goto out; } tcontext = sidtab_search(&sidtab, tsid); if (!tcontext) { - printk(KERN_ERR "security_compute_av: unrecognized SID %d\n", - tsid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, tsid); rc = -EINVAL; goto out; } @@ -595,9 +624,8 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 /* Allocate space for the context; caller must free this space. */ scontextp = kmalloc(*scontext_len, GFP_ATOMIC); - if (!scontextp) { + if (!scontextp) return -ENOMEM; - } *scontext = scontextp; /* @@ -608,8 +636,8 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 policydb.p_role_val_to_name[context->role - 1], policydb.p_type_val_to_name[context->type - 1]); scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + - 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + - 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); + 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + + 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); mls_sid_to_context(context, &scontextp); @@ -650,7 +678,7 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) char *scontextp; *scontext_len = strlen(initial_sid_to_string[sid]) + 1; - scontextp = kmalloc(*scontext_len,GFP_ATOMIC); + scontextp = kmalloc(*scontext_len, GFP_ATOMIC); if (!scontextp) { rc = -ENOMEM; goto out; @@ -659,16 +687,16 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) *scontext = scontextp; goto out; } - printk(KERN_ERR "security_sid_to_context: called before initial " - "load_policy on unknown SID %d\n", sid); + printk(KERN_ERR "SELinux: %s: called before initial " + "load_policy on unknown SID %d\n", __func__, sid); rc = -EINVAL; goto out; } POLICY_RDLOCK; context = sidtab_search(&sidtab, sid); if (!context) { - printk(KERN_ERR "security_sid_to_context: unrecognized SID " - "%d\n", sid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, sid); rc = -EINVAL; goto out_unlock; } @@ -898,15 +926,15 @@ static int security_compute_sid(u32 ssid, scontext = sidtab_search(&sidtab, ssid); if (!scontext) { - printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", - ssid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, ssid); rc = -EINVAL; goto out_unlock; } tcontext = sidtab_search(&sidtab, tsid); if (!tcontext) { - printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", - tsid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, tsid); rc = -EINVAL; goto out_unlock; } @@ -946,7 +974,7 @@ static int security_compute_sid(u32 ssid, avdatum = avtab_search(&policydb.te_avtab, &avkey); /* If no permanent rule, also check for enabled conditional rules */ - if(!avdatum) { + if (!avdatum) { node = avtab_search_node(&policydb.te_cond_avtab, &avkey); for (; node != NULL; node = avtab_search_node_next(node, specified)) { if (node->key.specified & AVTAB_ENABLED) { @@ -1096,7 +1124,7 @@ static int validate_classes(struct policydb *p) continue; if (i > p->p_classes.nprim) { printk(KERN_INFO - "security: class %s not defined in policy\n", + "SELinux: class %s not defined in policy\n", def_class); if (p->reject_unknown) return -EINVAL; @@ -1107,7 +1135,7 @@ static int validate_classes(struct policydb *p) pol_class = p->p_class_val_to_name[i-1]; if (strcmp(pol_class, def_class)) { printk(KERN_ERR - "security: class %d is incorrect, found %s but should be %s\n", + "SELinux: class %d is incorrect, found %s but should be %s\n", i, pol_class, def_class); return -EINVAL; } @@ -1125,7 +1153,7 @@ static int validate_classes(struct policydb *p) nprim = 1 << (perms->nprim - 1); if (perm_val > nprim) { printk(KERN_INFO - "security: permission %s in class %s not defined in policy\n", + "SELinux: permission %s in class %s not defined in policy\n", def_perm, pol_class); if (p->reject_unknown) return -EINVAL; @@ -1136,14 +1164,14 @@ static int validate_classes(struct policydb *p) perdatum = hashtab_search(perms->table, def_perm); if (perdatum == NULL) { printk(KERN_ERR - "security: permission %s in class %s not found in policy, bad policy\n", + "SELinux: permission %s in class %s not found in policy, bad policy\n", def_perm, pol_class); return -EINVAL; } pol_val = 1 << (perdatum->value - 1); if (pol_val != perm_val) { printk(KERN_ERR - "security: permission %s in class %s has incorrect value\n", + "SELinux: permission %s in class %s has incorrect value\n", def_perm, pol_class); return -EINVAL; } @@ -1157,7 +1185,7 @@ static int validate_classes(struct policydb *p) BUG_ON(!cladatum); if (!cladatum->comdatum) { printk(KERN_ERR - "security: class %s should have an inherits clause but does not\n", + "SELinux: class %s should have an inherits clause but does not\n", pol_class); return -EINVAL; } @@ -1172,7 +1200,7 @@ static int validate_classes(struct policydb *p) def_perm = kdefs->av_inherit[i].common_pts[j]; if (j >= perms->nprim) { printk(KERN_INFO - "security: permission %s in class %s not defined in policy\n", + "SELinux: permission %s in class %s not defined in policy\n", def_perm, pol_class); if (p->reject_unknown) return -EINVAL; @@ -1183,13 +1211,13 @@ static int validate_classes(struct policydb *p) perdatum = hashtab_search(perms->table, def_perm); if (perdatum == NULL) { printk(KERN_ERR - "security: permission %s in class %s not found in policy, bad policy\n", + "SELinux: permission %s in class %s not found in policy, bad policy\n", def_perm, pol_class); return -EINVAL; } if (perdatum->value != j + 1) { printk(KERN_ERR - "security: permission %s in class %s has incorrect value\n", + "SELinux: permission %s in class %s has incorrect value\n", def_perm, pol_class); return -EINVAL; } @@ -1219,7 +1247,7 @@ static inline int convert_context_handle_invalid_context(struct context *context u32 len; context_struct_to_string(context, &s, &len); - printk(KERN_ERR "security: context %s is invalid\n", s); + printk(KERN_ERR "SELinux: context %s is invalid\n", s); kfree(s); } return rc; @@ -1260,26 +1288,23 @@ static int convert_context(u32 key, /* Convert the user. */ usrdatum = hashtab_search(args->newp->p_users.table, - args->oldp->p_user_val_to_name[c->user - 1]); - if (!usrdatum) { + args->oldp->p_user_val_to_name[c->user - 1]); + if (!usrdatum) goto bad; - } c->user = usrdatum->value; /* Convert the role. */ role = hashtab_search(args->newp->p_roles.table, - args->oldp->p_role_val_to_name[c->role - 1]); - if (!role) { + args->oldp->p_role_val_to_name[c->role - 1]); + if (!role) goto bad; - } c->role = role->value; /* Convert the type. */ typdatum = hashtab_search(args->newp->p_types.table, - args->oldp->p_type_val_to_name[c->type - 1]); - if (!typdatum) { + args->oldp->p_type_val_to_name[c->type - 1]); + if (!typdatum) goto bad; - } c->type = typdatum->value; rc = mls_convert_context(args->oldp, args->newp, c); @@ -1299,7 +1324,7 @@ out: bad: context_struct_to_string(&oldc, &s, &len); context_destroy(&oldc); - printk(KERN_ERR "security: invalidating context %s\n", s); + printk(KERN_ERR "SELinux: invalidating context %s\n", s); kfree(s); goto out; } @@ -1308,6 +1333,8 @@ static void security_load_policycaps(void) { selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, POLICYDB_CAPABILITY_NETPEER); + selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, + POLICYDB_CAPABILITY_OPENPERM); } extern void selinux_complete_init(void); @@ -1350,7 +1377,7 @@ int security_load_policy(void *data, size_t len) /* Verify that the kernel defined classes are correct. */ if (validate_classes(&policydb)) { printk(KERN_ERR - "security: the definition of a class is incorrect\n"); + "SELinux: the definition of a class is incorrect\n"); LOAD_UNLOCK; sidtab_destroy(&sidtab); policydb_destroy(&policydb); @@ -1384,14 +1411,14 @@ int security_load_policy(void *data, size_t len) /* Verify that the kernel defined classes are correct. */ if (validate_classes(&newpolicydb)) { printk(KERN_ERR - "security: the definition of a class is incorrect\n"); + "SELinux: the definition of a class is incorrect\n"); rc = -EINVAL; goto err; } rc = security_preserve_bools(&newpolicydb); if (rc) { - printk(KERN_ERR "security: unable to preserve booleans\n"); + printk(KERN_ERR "SELinux: unable to preserve booleans\n"); goto err; } @@ -1443,17 +1470,11 @@ err: /** * security_port_sid - Obtain the SID for a port. - * @domain: communication domain aka address family - * @type: socket type * @protocol: protocol number * @port: port number * @out_sid: security identifier */ -int security_port_sid(u16 domain, - u16 type, - u8 protocol, - u16 port, - u32 *out_sid) +int security_port_sid(u8 protocol, u16 port, u32 *out_sid) { struct ocontext *c; int rc = 0; @@ -1532,8 +1553,8 @@ static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask) { int i, fail = 0; - for(i = 0; i < 4; i++) - if(addr[i] != (input[i] & mask[i])) { + for (i = 0; i < 4; i++) + if (addr[i] != (input[i] & mask[i])) { fail = 1; break; } @@ -1632,7 +1653,7 @@ out: */ int security_get_user_sids(u32 fromsid, - char *username, + char *username, u32 **sids, u32 *nel) { @@ -1742,7 +1763,7 @@ out: * transition SIDs or task SIDs. */ int security_genfs_sid(const char *fstype, - char *path, + char *path, u16 sclass, u32 *sid) { @@ -1857,7 +1878,7 @@ int security_get_bools(int *len, char ***names, int **values) goto out; } - *names = kcalloc(*len, sizeof(char*), GFP_ATOMIC); + *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); if (!*names) goto err; @@ -1869,7 +1890,7 @@ int security_get_bools(int *len, char ***names, int **values) size_t name_len; (*values)[i] = policydb.bool_val_to_struct[i]->state; name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; - (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); + (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); if (!(*names)[i]) goto err; strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); @@ -1914,11 +1935,10 @@ int security_set_bools(int len, int *values) audit_get_loginuid(current), audit_get_sessionid(current)); } - if (values[i]) { + if (values[i]) policydb.bool_val_to_struct[i]->state = 1; - } else { + else policydb.bool_val_to_struct[i]->state = 0; - } } for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { @@ -2012,16 +2032,16 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) POLICY_RDLOCK; context1 = sidtab_search(&sidtab, sid); if (!context1) { - printk(KERN_ERR "security_sid_mls_copy: unrecognized SID " - "%d\n", sid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, sid); rc = -EINVAL; goto out_unlock; } context2 = sidtab_search(&sidtab, mls_sid); if (!context2) { - printk(KERN_ERR "security_sid_mls_copy: unrecognized SID " - "%d\n", mls_sid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, mls_sid); rc = -EINVAL; goto out_unlock; } @@ -2112,17 +2132,15 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); if (!nlbl_ctx) { - printk(KERN_ERR - "security_sid_mls_cmp: unrecognized SID %d\n", - nlbl_sid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, nlbl_sid); rc = -EINVAL; goto out_slowpath; } xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); if (!xfrm_ctx) { - printk(KERN_ERR - "security_sid_mls_cmp: unrecognized SID %d\n", - xfrm_sid); + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, xfrm_sid); rc = -EINVAL; goto out_slowpath; } @@ -2202,8 +2220,8 @@ int security_get_permissions(char *class, char ***perms, int *nperms) match = hashtab_search(policydb.p_classes.table, class); if (!match) { - printk(KERN_ERR "%s: unrecognized class %s\n", - __FUNCTION__, class); + printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", + __func__, class); rc = -EINVAL; goto out; } @@ -2273,21 +2291,23 @@ struct selinux_audit_rule { struct context au_ctxt; }; -void selinux_audit_rule_free(struct selinux_audit_rule *rule) +void selinux_audit_rule_free(void *vrule) { + struct selinux_audit_rule *rule = vrule; + if (rule) { context_destroy(&rule->au_ctxt); kfree(rule); } } -int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, - struct selinux_audit_rule **rule) +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) { struct selinux_audit_rule *tmprule; struct role_datum *roledatum; struct type_datum *typedatum; struct user_datum *userdatum; + struct selinux_audit_rule **rule = (struct selinux_audit_rule **)vrule; int rc = 0; *rule = NULL; @@ -2374,17 +2394,42 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, return rc; } -int selinux_audit_rule_match(u32 sid, u32 field, u32 op, - struct selinux_audit_rule *rule, +/* Check to see if the rule contains any selinux fields */ +int selinux_audit_rule_known(struct audit_krule *rule) +{ + int i; + + for (i = 0; i < rule->field_count; i++) { + struct audit_field *f = &rule->fields[i]; + switch (f->type) { + case AUDIT_SUBJ_USER: + case AUDIT_SUBJ_ROLE: + case AUDIT_SUBJ_TYPE: + case AUDIT_SUBJ_SEN: + case AUDIT_SUBJ_CLR: + case AUDIT_OBJ_USER: + case AUDIT_OBJ_ROLE: + case AUDIT_OBJ_TYPE: + case AUDIT_OBJ_LEV_LOW: + case AUDIT_OBJ_LEV_HIGH: + return 1; + } + } + + return 0; +} + +int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, struct audit_context *actx) { struct context *ctxt; struct mls_level *level; + struct selinux_audit_rule *rule = vrule; int match = 0; if (!rule) { audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: missing rule\n"); + "selinux_audit_rule_match: missing rule\n"); return -ENOENT; } @@ -2392,7 +2437,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, if (rule->au_seqno < latest_granting) { audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: stale rule\n"); + "selinux_audit_rule_match: stale rule\n"); match = -ESTALE; goto out; } @@ -2400,8 +2445,8 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, ctxt = sidtab_search(&sidtab, sid); if (!ctxt) { audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: unrecognized SID %d\n", - sid); + "selinux_audit_rule_match: unrecognized SID %d\n", + sid); match = -ENOENT; goto out; } @@ -2447,36 +2492,36 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, case AUDIT_OBJ_LEV_LOW: case AUDIT_OBJ_LEV_HIGH: level = ((field == AUDIT_SUBJ_SEN || - field == AUDIT_OBJ_LEV_LOW) ? - &ctxt->range.level[0] : &ctxt->range.level[1]); + field == AUDIT_OBJ_LEV_LOW) ? + &ctxt->range.level[0] : &ctxt->range.level[1]); switch (op) { case AUDIT_EQUAL: match = mls_level_eq(&rule->au_ctxt.range.level[0], - level); + level); break; case AUDIT_NOT_EQUAL: match = !mls_level_eq(&rule->au_ctxt.range.level[0], - level); + level); break; case AUDIT_LESS_THAN: match = (mls_level_dom(&rule->au_ctxt.range.level[0], - level) && - !mls_level_eq(&rule->au_ctxt.range.level[0], - level)); + level) && + !mls_level_eq(&rule->au_ctxt.range.level[0], + level)); break; case AUDIT_LESS_THAN_OR_EQUAL: match = mls_level_dom(&rule->au_ctxt.range.level[0], - level); + level); break; case AUDIT_GREATER_THAN: match = (mls_level_dom(level, - &rule->au_ctxt.range.level[0]) && - !mls_level_eq(level, - &rule->au_ctxt.range.level[0])); + &rule->au_ctxt.range.level[0]) && + !mls_level_eq(level, + &rule->au_ctxt.range.level[0])); break; case AUDIT_GREATER_THAN_OR_EQUAL: match = mls_level_dom(level, - &rule->au_ctxt.range.level[0]); + &rule->au_ctxt.range.level[0]); break; } } @@ -2486,7 +2531,7 @@ out: return match; } -static int (*aurule_callback)(void) = NULL; +static int (*aurule_callback)(void) = audit_update_lsm_rules; static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, u16 class, u32 perms, u32 *retained) @@ -2503,7 +2548,7 @@ static int __init aurule_init(void) int err; err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, - SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); + SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); if (err) panic("avc_add_callback() failed, error %d\n", err); @@ -2511,11 +2556,6 @@ static int __init aurule_init(void) } __initcall(aurule_init); -void selinux_audit_set_callback(int (*callback)(void)) -{ - aurule_callback = callback; -} - #ifdef CONFIG_NETLABEL /** * security_netlbl_cache_add - Add an entry to the NetLabel cache @@ -2651,7 +2691,7 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) goto netlbl_sid_to_secattr_failure; secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], GFP_ATOMIC); - secattr->flags |= NETLBL_SECATTR_DOMAIN; + secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY; mls_export_netlbl_lvl(ctx, secattr); rc = mls_export_netlbl_cat(ctx, secattr); if (rc != 0) diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index 53a54a77f1f8..4a516ff4bcde 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -156,12 +156,10 @@ void sidtab_map_remove_on_error(struct sidtab *s, while (cur != NULL) { ret = apply(cur->sid, &cur->context, args); if (ret) { - if (last) { + if (last) last->next = cur->next; - } else { + else s->htable[i] = cur->next; - } - temp = cur; cur = cur->next; context_destroy(&temp->context); |