From 1afbf9b401a37e8167c4efd92b913790c190bf51 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 7 Nov 2007 01:11:56 +0100 Subject: [PATCH] --- yaml --- r: 73243 b: refs/heads/master c: 7c45d1913f0a1d597eb4bc3b2c962bc2967da9ea h: refs/heads/master i: 73241: e5830a3bcabe74e541be9665ea2f1c44776706a7 73239: 91c49d4f0b8f5bc2f5ce9816cde937d92a03d531 v: v3 --- [refs] | 2 +- trunk/arch/frv/mm/init.c | 2 +- trunk/drivers/firewire/fw-sbp2.c | 11 +++-- trunk/security/selinux/ss/avtab.c | 32 ++---------- trunk/security/selinux/ss/avtab.h | 5 +- trunk/security/selinux/ss/conditional.c | 3 +- trunk/security/selinux/ss/ebitmap.c | 2 +- trunk/security/selinux/ss/mls.c | 66 +++++++++++-------------- trunk/security/selinux/ss/mls.h | 2 - trunk/security/selinux/ss/policydb.c | 45 +---------------- trunk/security/selinux/ss/policydb.h | 3 -- trunk/security/selinux/xfrm.c | 13 +++-- 12 files changed, 54 insertions(+), 132 deletions(-) diff --git a/[refs] b/[refs] index 298bb2cf9f29..725bc957d32d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 98d74e08b1194acea2626da22376a2aacabcf67e +refs/heads/master: 7c45d1913f0a1d597eb4bc3b2c962bc2967da9ea diff --git a/trunk/arch/frv/mm/init.c b/trunk/arch/frv/mm/init.c index b841ecfd5d5a..4103c2c487f3 100644 --- a/trunk/arch/frv/mm/init.c +++ b/trunk/arch/frv/mm/init.c @@ -197,7 +197,7 @@ void __init mem_init(void) /* * free the memory that was only required for initialisation */ -void free_initmem(void) +void __init free_initmem(void) { #if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL) unsigned long start, end, addr; diff --git a/trunk/drivers/firewire/fw-sbp2.c b/trunk/drivers/firewire/fw-sbp2.c index 5596df65c8ed..624ff3e082f6 100644 --- a/trunk/drivers/firewire/fw-sbp2.c +++ b/trunk/drivers/firewire/fw-sbp2.c @@ -650,13 +650,14 @@ static void sbp2_login(struct work_struct *work) if (sbp2_send_management_orb(lu, node_id, generation, SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) { if (lu->retries++ < 5) { - queue_delayed_work(sbp2_wq, &lu->work, - DIV_ROUND_UP(HZ, 5)); + if (queue_delayed_work(sbp2_wq, &lu->work, + DIV_ROUND_UP(HZ, 5))) + kref_get(&lu->tgt->kref); } else { fw_error("failed to login to %s LUN %04x\n", unit->device.bus_id, lu->lun); - kref_put(&lu->tgt->kref, sbp2_release_target); } + kref_put(&lu->tgt->kref, sbp2_release_target); return; } @@ -914,7 +915,9 @@ static void sbp2_reconnect(struct work_struct *work) lu->retries = 0; PREPARE_DELAYED_WORK(&lu->work, sbp2_login); } - queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5)); + if (queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5))) + kref_get(&lu->tgt->kref); + kref_put(&lu->tgt->kref, sbp2_release_target); return; } diff --git a/trunk/security/selinux/ss/avtab.c b/trunk/security/selinux/ss/avtab.c index 9e70a160d7da..7551af1f7899 100644 --- a/trunk/security/selinux/ss/avtab.c +++ b/trunk/security/selinux/ss/avtab.c @@ -325,7 +325,7 @@ static uint16_t spec_order[] = { AVTAB_MEMBER }; -int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, +int avtab_read_item(void *fp, u32 vers, struct avtab *a, int (*insertf)(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *p), void *p) @@ -333,11 +333,10 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, __le16 buf16[4]; u16 enabled; __le32 buf32[7]; - u32 items, items2, val, vers = pol->policyvers; + u32 items, items2, val; struct avtab_key key; struct avtab_datum datum; int i, rc; - unsigned set; memset(&key, 0, sizeof(struct avtab_key)); memset(&datum, 0, sizeof(struct avtab_datum)); @@ -421,35 +420,12 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, key.target_class = le16_to_cpu(buf16[items++]); key.specified = le16_to_cpu(buf16[items++]); - 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"); - return -1; - } - - set = 0; - for (i = 0; i < ARRAY_SIZE(spec_order); i++) { - if (key.specified & spec_order[i]) - set++; - } - if (!set || set > 1) { - printk(KERN_WARNING - "security: avtab: more than one specifier\n"); - return -1; - } - rc = next_entry(buf32, fp, sizeof(u32)); if (rc < 0) { printk("security: 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"); - return -1; - } return insertf(a, &key, &datum, p); } @@ -459,7 +435,7 @@ static int avtab_insertf(struct avtab *a, 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, void *fp, u32 vers) { int rc; __le32 buf[1]; @@ -483,7 +459,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(fp,vers, a, avtab_insertf, NULL); if (rc) { if (rc == -ENOMEM) printk(KERN_ERR "security: avtab: out of memory\n"); diff --git a/trunk/security/selinux/ss/avtab.h b/trunk/security/selinux/ss/avtab.h index 8da6a8428086..d8edf8ca56d1 100644 --- a/trunk/security/selinux/ss/avtab.h +++ b/trunk/security/selinux/ss/avtab.h @@ -64,13 +64,12 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k); void avtab_destroy(struct avtab *h); void avtab_hash_eval(struct avtab *h, char *tag); -struct policydb; -int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, +int avtab_read_item(void *fp, uint32_t vers, struct avtab *a, int (*insert)(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *p), void *p); -int avtab_read(struct avtab *a, void *fp, struct policydb *pol); +int avtab_read(struct avtab *a, void *fp, u32 vers); struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datum *datum); diff --git a/trunk/security/selinux/ss/conditional.c b/trunk/security/selinux/ss/conditional.c index 50ad85d4b77c..45b93a827c80 100644 --- a/trunk/security/selinux/ss/conditional.c +++ b/trunk/security/selinux/ss/conditional.c @@ -362,8 +362,7 @@ static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list * data.head = NULL; data.tail = NULL; for (i = 0; i < len; i++) { - rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf, - &data); + rc = avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, cond_insertf, &data); if (rc) return rc; diff --git a/trunk/security/selinux/ss/ebitmap.c b/trunk/security/selinux/ss/ebitmap.c index 920b5e36a1af..c1a6b22d48d9 100644 --- a/trunk/security/selinux/ss/ebitmap.c +++ b/trunk/security/selinux/ss/ebitmap.c @@ -129,8 +129,8 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap, cmap_sft = delta % NETLBL_CATMAP_MAPSIZE; c_iter->bitmap[cmap_idx] |= e_iter->maps[cmap_idx] << cmap_sft; + e_iter = e_iter->next; } - e_iter = e_iter->next; } return 0; diff --git a/trunk/security/selinux/ss/mls.c b/trunk/security/selinux/ss/mls.c index fb5d70a6628d..9a11deaaa9e7 100644 --- a/trunk/security/selinux/ss/mls.c +++ b/trunk/security/selinux/ss/mls.c @@ -157,55 +157,49 @@ void mls_sid_to_context(struct context *context, return; } -int mls_level_isvalid(struct policydb *p, struct mls_level *l) -{ - struct level_datum *levdatum; - struct ebitmap_node *node; - int i; - - if (!l->sens || l->sens > p->p_levels.nprim) - return 0; - levdatum = hashtab_search(p->p_levels.table, - p->p_sens_val_to_name[l->sens - 1]); - if (!levdatum) - return 0; - - ebitmap_for_each_positive_bit(&l->cat, node, i) { - if (i > p->p_cats.nprim) - return 0; - if (!ebitmap_get_bit(&levdatum->level->cat, i)) { - /* - * Category may not be associated with - * sensitivity. - */ - return 0; - } - } - - return 1; -} - -int mls_range_isvalid(struct policydb *p, struct mls_range *r) -{ - return (mls_level_isvalid(p, &r->level[0]) && - mls_level_isvalid(p, &r->level[1]) && - mls_level_dom(&r->level[1], &r->level[0])); -} - /* * Return 1 if the MLS fields in the security context * structure `c' are valid. Return 0 otherwise. */ int mls_context_isvalid(struct policydb *p, struct context *c) { + struct level_datum *levdatum; struct user_datum *usrdatum; + struct ebitmap_node *node; + int i, l; if (!selinux_mls_enabled) return 1; - if (!mls_range_isvalid(p, &c->range)) + /* + * MLS range validity checks: high must dominate low, low level must + * be valid (category set <-> sensitivity check), and high level must + * be valid (category set <-> sensitivity check) + */ + if (!mls_level_dom(&c->range.level[1], &c->range.level[0])) + /* High does not dominate low. */ return 0; + for (l = 0; l < 2; l++) { + if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim) + return 0; + levdatum = hashtab_search(p->p_levels.table, + p->p_sens_val_to_name[c->range.level[l].sens - 1]); + if (!levdatum) + return 0; + + ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) { + if (i > p->p_cats.nprim) + return 0; + if (!ebitmap_get_bit(&levdatum->level->cat, i)) + /* + * Category may not be associated with + * sensitivity in low level. + */ + return 0; + } + } + if (c->role == OBJECT_R_VAL) return 1; diff --git a/trunk/security/selinux/ss/mls.h b/trunk/security/selinux/ss/mls.h index ab53663d9f5f..096d1b4ef7fb 100644 --- a/trunk/security/selinux/ss/mls.h +++ b/trunk/security/selinux/ss/mls.h @@ -27,8 +27,6 @@ int mls_compute_context_len(struct context *context); void mls_sid_to_context(struct context *context, char **scontext); 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(char oldc, char **scontext, diff --git a/trunk/security/selinux/ss/policydb.c b/trunk/security/selinux/ss/policydb.c index b582aae3c62c..539828b229b2 100644 --- a/trunk/security/selinux/ss/policydb.c +++ b/trunk/security/selinux/ss/policydb.c @@ -713,27 +713,6 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) return rc; } -int policydb_class_isvalid(struct policydb *p, unsigned int class) -{ - if (!class || class > p->p_classes.nprim) - return 0; - return 1; -} - -int policydb_role_isvalid(struct policydb *p, unsigned int role) -{ - if (!role || role > p->p_roles.nprim) - return 0; - return 1; -} - -int policydb_type_isvalid(struct policydb *p, unsigned int type) -{ - if (!type || type > p->p_types.nprim) - return 0; - return 1; -} - /* * Return 1 if the fields in the security context * structure `c' are valid. Return 0 otherwise. @@ -1281,7 +1260,6 @@ static int mls_read_level(struct mls_level *lp, void *fp) "categories\n"); goto bad; } - return 0; bad: @@ -1585,7 +1563,7 @@ int policydb_read(struct policydb *p, void *fp) p->symtab[i].nprim = nprim; } - rc = avtab_read(&p->te_avtab, fp, p); + rc = avtab_read(&p->te_avtab, fp, p->policyvers); if (rc) goto bad; @@ -1617,12 +1595,6 @@ int policydb_read(struct policydb *p, void *fp) tr->role = le32_to_cpu(buf[0]); tr->type = le32_to_cpu(buf[1]); tr->new_role = le32_to_cpu(buf[2]); - if (!policydb_role_isvalid(p, tr->role) || - !policydb_type_isvalid(p, tr->type) || - !policydb_role_isvalid(p, tr->new_role)) { - rc = -EINVAL; - goto bad; - } ltr = tr; } @@ -1647,11 +1619,6 @@ int policydb_read(struct policydb *p, void *fp) goto bad; ra->role = le32_to_cpu(buf[0]); ra->new_role = le32_to_cpu(buf[1]); - if (!policydb_role_isvalid(p, ra->role) || - !policydb_role_isvalid(p, ra->new_role)) { - rc = -EINVAL; - goto bad; - } lra = ra; } @@ -1905,19 +1872,9 @@ int policydb_read(struct policydb *p, void *fp) rt->target_class = le32_to_cpu(buf[0]); } else rt->target_class = SECCLASS_PROCESS; - if (!policydb_type_isvalid(p, rt->source_type) || - !policydb_type_isvalid(p, rt->target_type) || - !policydb_class_isvalid(p, rt->target_class)) { - rc = -EINVAL; - goto bad; - } rc = mls_read_range_helper(&rt->target_range, fp); if (rc) goto bad; - if (!mls_range_isvalid(p, &rt->target_range)) { - printk(KERN_WARNING "security: rangetrans: invalid range\n"); - goto bad; - } lrt = rt; } } diff --git a/trunk/security/selinux/ss/policydb.h b/trunk/security/selinux/ss/policydb.h index ed6fc687c66f..844d310f4f1b 100644 --- a/trunk/security/selinux/ss/policydb.h +++ b/trunk/security/selinux/ss/policydb.h @@ -251,9 +251,6 @@ struct policydb { 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); #define PERM_SYMTAB_SIZE 32 diff --git a/trunk/security/selinux/xfrm.c b/trunk/security/selinux/xfrm.c index e07603969033..36a191e7004e 100644 --- a/trunk/security/selinux/xfrm.c +++ b/trunk/security/selinux/xfrm.c @@ -211,27 +211,26 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX) return -EINVAL; - str_len = uctx->ctx_len; - if (str_len >= PAGE_SIZE) + if (uctx->ctx_len >= PAGE_SIZE) return -ENOMEM; *ctxp = ctx = kmalloc(sizeof(*ctx) + - str_len + 1, + uctx->ctx_len + 1, GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->ctx_doi = uctx->ctx_doi; - ctx->ctx_len = str_len; + ctx->ctx_len = uctx->ctx_len; ctx->ctx_alg = uctx->ctx_alg; memcpy(ctx->ctx_str, uctx+1, - str_len); - ctx->ctx_str[str_len] = 0; + ctx->ctx_len); + ctx->ctx_str[ctx->ctx_len] = 0; rc = security_context_to_sid(ctx->ctx_str, - str_len, + ctx->ctx_len, &ctx->ctx_sid); if (rc)