From 4ebc669d5dc59771284b2d61eb4cce53e6a7069e Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Tue, 25 Sep 2012 10:56:54 -0400 Subject: Update to libsepol 2.1.8. Change-Id: I7d848ee312d4c706162a822d2031f37a5557ed5f Signed-off-by: Stephen Smalley --- ChangeLog | 19 +++++ VERSION | 2 +- include/sepol/policydb/polcaps.h | 2 + include/sepol/policydb/policydb.h | 19 ++++- src/expand.c | 154 ++++++++++++++++++++++---------------- src/link.c | 33 ++++++++ src/polcaps.c | 2 + src/policydb.c | 35 ++++++++- src/private.h | 2 +- src/write.c | 12 +++ 10 files changed, 209 insertions(+), 71 deletions(-) diff --git a/ChangeLog b/ChangeLog index f835678..75bf7b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2.1.8 2011-09-13 + * fix neverallow checking on attributes + * Move context_copy() after switch block in ocontext_copy_*(). + * check for missing initial SID labeling statement. + * Add always_check_network policy capability + * role_fix_callback skips out-of-scope roles during expansion. + +2.1.7 2011-06-28 + * reserve policycapability for redhat testing of ptrace child + * cosmetic changes to make the source easier to read + * prepend instead of append to filename_trans list + * Android/MacOS X build support + +2.1.6 2011-04-23 + * allocate enough space to hold filename in trans rules + +2.1.5 2011-03-28 + * checkpolicy: implement new default labeling behaviors + 2.1.4 2011-10-03 * regenerate .pc on VERSION change * Move ebitmap_* functions from mcstrans to libsepol diff --git a/VERSION b/VERSION index 7d2ed7c..ebf14b4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.4 +2.1.8 diff --git a/include/sepol/policydb/polcaps.h b/include/sepol/policydb/polcaps.h index 40c0a48..f90a48d 100644 --- a/include/sepol/policydb/polcaps.h +++ b/include/sepol/policydb/polcaps.h @@ -5,6 +5,8 @@ enum { POLICYDB_CAPABILITY_NETPEER, POLICYDB_CAPABILITY_OPENPERM, + POLICYDB_CAPABILITY_REDHAT1, /* reserved for RH testing of ptrace_child */ + POLICYDB_CAPABILITY_ALWAYSNETWORK, __POLICYDB_CAPABILITY_MAX }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) diff --git a/include/sepol/policydb/policydb.h b/include/sepol/policydb/policydb.h index 1848a7b..f53a499 100644 --- a/include/sepol/policydb/policydb.h +++ b/include/sepol/policydb/policydb.h @@ -111,6 +111,19 @@ typedef struct class_datum { symtab_t permissions; /* class-specific permission symbol table */ constraint_node_t *constraints; /* constraints on class permissions */ constraint_node_t *validatetrans; /* special transition rules */ +/* Options how a new object user and role should be decided */ +#define DEFAULT_SOURCE 1 +#define DEFAULT_TARGET 2 + char default_user; + char default_role; +/* 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 + char default_range; } class_datum_t; /* Role attributes */ @@ -667,10 +680,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define POLICYDB_VERSION_BOUNDARY 24 #define POLICYDB_VERSION_FILENAME_TRANS 25 #define POLICYDB_VERSION_ROLETRANS 26 +#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_NEW_OBJECT_DEFAULTS /* Module versions and specific changes*/ #define MOD_POLICYDB_VERSION_BASE 4 @@ -686,9 +700,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define MOD_POLICYDB_VERSION_ROLETRANS 12 #define MOD_POLICYDB_VERSION_ROLEATTRIB 13 #define MOD_POLICYDB_VERSION_TUNABLE_SEP 14 +#define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 15 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_TUNABLE_SEP +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS #define POLICYDB_CONFIG_MLS 1 diff --git a/src/expand.c b/src/expand.c index 493e478..2003eb6 100644 --- a/src/expand.c +++ b/src/expand.c @@ -358,6 +358,35 @@ static int constraint_node_clone(constraint_node_t ** dst, return -1; } +static int class_copy_default_new_object(expand_state_t *state, + class_datum_t *olddatum, + class_datum_t *newdatum) +{ + if (olddatum->default_user) { + if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { + ERR(state->handle, "Found conflicting default user definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_user = olddatum->default_user; + + } + if (olddatum->default_role) { + if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { + ERR(state->handle, "Found conflicting default role definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_role = olddatum->default_role; + } + if (olddatum->default_range) { + if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { + ERR(state->handle, "Found conflicting default range definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_range = olddatum->default_range; + } + return 0; +} + static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) { @@ -393,6 +422,12 @@ static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, new_class->s.value = class->s.value; state->out->p_classes.nprim++; + ret = class_copy_default_new_object(state, class, new_class); + if (ret) { + free(new_class); + return ret; + } + new_id = strdup(id); if (!new_id) { ERR(state->handle, "Out of memory!"); @@ -688,6 +723,11 @@ static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, return 0; } + if (!is_id_enabled(id, state->base, SYM_ROLES)) { + /* identifier's scope is not enabled */ + return 0; + } + if (role->flavor != ROLE_ATTRIB) return 0; @@ -1317,16 +1357,11 @@ static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules) static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules) { unsigned int i, j; - filename_trans_t *new_trans, *tail, *cur_trans; + filename_trans_t *new_trans, *cur_trans; filename_trans_rule_t *cur_rule; ebitmap_t stypes, ttypes; ebitmap_node_t *snode, *tnode; - /* start at the end of the list */ - tail = state->out->filename_trans; - while (tail && tail->next) - tail = tail->next; - cur_rule = rules; while (cur_rule) { uint32_t mapped_otype; @@ -1387,11 +1422,8 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r return -1; } memset(new_trans, 0, sizeof(*new_trans)); - if (tail) - tail->next = new_trans; - else - state->out->filename_trans = new_trans; - tail = new_trans; + new_trans->next = state->out->filename_trans; + state->out->filename_trans = new_trans; new_trans->name = strdup(cur_rule->name); if (!new_trans->name) { @@ -1791,58 +1823,36 @@ static int expand_rule_helper(sepol_handle_t * handle, continue; if (source_rule->flags & RULE_SELF) { if (source_rule->specified & AVRULE_AV) { - if ((retval = - expand_avrule_helper(handle, - source_rule-> - specified, cond, i, i, - source_rule->perms, - dest_avtab, - enabled)) != - EXPAND_RULE_SUCCESS) { + retval = expand_avrule_helper(handle, source_rule->specified, + cond, i, i, source_rule->perms, + dest_avtab, enabled); + if (retval != EXPAND_RULE_SUCCESS) return retval; - } } else { - if ((retval = - expand_terule_helper(handle, p, - typemap, - source_rule-> - specified, cond, - other, i, i, - source_rule->perms, - dest_avtab, - enabled)) != - EXPAND_RULE_SUCCESS) { + retval = expand_terule_helper(handle, p, typemap, + source_rule->specified, cond, + other, i, i, source_rule->perms, + dest_avtab, enabled); + if (retval != EXPAND_RULE_SUCCESS) return retval; - } } } ebitmap_for_each_bit(ttypes, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; if (source_rule->specified & AVRULE_AV) { - if ((retval = - expand_avrule_helper(handle, - source_rule-> - specified, cond, i, j, - source_rule->perms, - dest_avtab, - enabled)) != - EXPAND_RULE_SUCCESS) { + retval = expand_avrule_helper(handle, source_rule->specified, + cond, i, j, source_rule->perms, + dest_avtab, enabled); + if (retval != EXPAND_RULE_SUCCESS) return retval; - } } else { - if ((retval = - expand_terule_helper(handle, p, - typemap, - source_rule-> - specified, cond, - other, i, j, - source_rule->perms, - dest_avtab, - enabled)) != - EXPAND_RULE_SUCCESS) { + retval = expand_terule_helper(handle, p, typemap, + source_rule->specified, cond, + other, i, j, source_rule->perms, + dest_avtab, enabled); + if (retval != EXPAND_RULE_SUCCESS) return retval; - } } } } @@ -2027,13 +2037,14 @@ static int ocontext_copy_xen(expand_state_t *state) else state->out->ocontexts[i] = n; l = n; - if (context_copy(&n->context[0], &c->context[0], - state)) { - ERR(state->handle, "Out of memory!"); - return -1; - } switch (i) { case OCON_XEN_ISID: + if (c->context[0].user == 0) { + ERR(state->handle, + "Missing context for %s initial sid", + c->u.name); + return -1; + } n->sid[0] = c->sid[0]; break; case OCON_XEN_PIRQ: @@ -2056,6 +2067,11 @@ static int ocontext_copy_xen(expand_state_t *state) ERR(state->handle, "Unknown ocontext"); return -1; } + if (context_copy(&n->context[0], &c->context[0], + state)) { + ERR(state->handle, "Out of memory!"); + return -1; + } } } return 0; @@ -2080,12 +2096,14 @@ static int ocontext_copy_selinux(expand_state_t *state) else state->out->ocontexts[i] = n; l = n; - if (context_copy(&n->context[0], &c->context[0], state)) { - ERR(state->handle, "Out of memory!"); - return -1; - } switch (i) { case OCON_ISID: + if (c->context[0].user == 0) { + ERR(state->handle, + "Missing context for %s initial sid", + c->u.name); + return -1; + } n->sid[0] = c->sid[0]; break; case OCON_FS: /* FALLTHROUGH */ @@ -2129,6 +2147,10 @@ static int ocontext_copy_selinux(expand_state_t *state) ERR(state->handle, "Unknown ocontext"); return -1; } + if (context_copy(&n->context[0], &c->context[0], state)) { + ERR(state->handle, "Out of memory!"); + return -1; + } } } return 0; @@ -3101,12 +3123,12 @@ static int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args) newkey.target_class = k->target_class; newkey.specified = k->specified; - if (stype && ttype) { + if (stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { /* Both are individual types, no expansion required. */ return expand_avtab_insert(expa, k, d); } - if (stype) { + if (stype->flavor != TYPE_ATTRIB) { /* Source is an individual type, target is an attribute. */ newkey.source_type = k->source_type; ebitmap_for_each_bit(tattr, tnode, j) { @@ -3120,7 +3142,7 @@ static int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args) return 0; } - if (ttype) { + if (ttype->flavor != TYPE_ATTRIB) { /* Target is an individual type, source is an attribute. */ newkey.target_type = k->target_type; ebitmap_for_each_bit(sattr, snode, i) { @@ -3231,12 +3253,12 @@ int expand_cond_av_node(policydb_t * p, newkey.target_class = k->target_class; newkey.specified = k->specified; - if (stype && ttype) { + if (stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { /* Both are individual types, no expansion required. */ return expand_cond_insert(newl, expa, k, d); } - if (stype) { + if (stype->flavor != TYPE_ATTRIB) { /* Source is an individual type, target is an attribute. */ newkey.source_type = k->source_type; ebitmap_for_each_bit(tattr, tnode, j) { @@ -3250,7 +3272,7 @@ int expand_cond_av_node(policydb_t * p, return 0; } - if (ttype) { + if (ttype->flavor != TYPE_ATTRIB) { /* Target is an individual type, source is an attribute. */ newkey.target_type = k->target_type; ebitmap_for_each_bit(sattr, snode, i) { diff --git a/src/link.c b/src/link.c index ee9675b..01d3231 100644 --- a/src/link.c +++ b/src/link.c @@ -205,6 +205,34 @@ static int permission_copy_callback(hashtab_key_t key, hashtab_datum_t datum, return ret; } +static int class_copy_default_new_object(link_state_t *state, + class_datum_t *olddatum, + class_datum_t *newdatum) +{ + if (olddatum->default_user) { + if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { + ERR(state->handle, "Found conflicting default user definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_user = olddatum->default_user; + } + if (olddatum->default_role) { + if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { + ERR(state->handle, "Found conflicting default role definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_role = olddatum->default_role; + } + if (olddatum->default_range) { + if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { + ERR(state->handle, "Found conflicting default range definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_range = olddatum->default_range; + } + return 0; +} + static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) { @@ -287,6 +315,11 @@ static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, state->dest_class = new_class; state->dest_class_name = (char *)key; + /* copy default new object rules */ + ret = class_copy_default_new_object(state, cladatum, new_class); + if (ret) + return ret; + ret = hashtab_map(cladatum->permissions.table, permission_copy_callback, state); diff --git a/src/polcaps.c b/src/polcaps.c index 71970b1..43a71a7 100644 --- a/src/polcaps.c +++ b/src/polcaps.c @@ -8,6 +8,8 @@ static const char *polcap_names[] = { "network_peer_controls", /* POLICYDB_CAPABILITY_NETPEER */ "open_perms", /* POLICYDB_CAPABILITY_OPENPERM */ + "redhat1", /* POLICYDB_CAPABILITY_REDHAT1, aka ptrace_child */ + "always_check_network", /* POLICYDB_CAPABILITY_ALWAYSNETWORK */ NULL }; diff --git a/src/policydb.c b/src/policydb.c index 136b450..ff292f6 100644 --- a/src/policydb.c +++ b/src/policydb.c @@ -150,6 +150,13 @@ static struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_NODE6 + 1, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, { .type = POLICY_BASE, .version = MOD_POLICYDB_VERSION_BASE, @@ -227,6 +234,13 @@ static struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_NODE6 + 1, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, { .type = POLICY_MOD, .version = MOD_POLICYDB_VERSION_BASE, @@ -304,6 +318,13 @@ static struct policydb_compat_info policydb_compat[] = { .ocon_num = 0, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, }; #if 0 @@ -2064,6 +2085,18 @@ static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) goto bad; } + if ((p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || + (p->policy_type == POLICY_BASE && + p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { + rc = next_entry(buf, fp, sizeof(uint32_t) * 3); + if (rc < 0) + goto bad; + cladatum->default_user = le32_to_cpu(buf[0]); + cladatum->default_role = le32_to_cpu(buf[1]); + cladatum->default_range = le32_to_cpu(buf[2]); + } + if (hashtab_insert(h, key, cladatum)) goto bad; @@ -2347,7 +2380,7 @@ int filename_trans_read(filename_trans_t **t, struct policy_file *fp) return -1; len = le32_to_cpu(buf[0]); - name = calloc(len, sizeof(*name)); + name = calloc(len + 1, sizeof(*name)); if (!name) return -1; diff --git a/src/private.h b/src/private.h index a2188d4..8a6d4bb 100644 --- a/src/private.h +++ b/src/private.h @@ -18,7 +18,7 @@ #ifdef DARWIN #define __BYTE_ORDER BYTE_ORDER -#define __LITTLE_ENDIAN LITTLE_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN #endif #if __BYTE_ORDER == __LITTLE_ENDIAN diff --git a/src/write.c b/src/write.c index e34ab52..22e6143 100644 --- a/src/write.c +++ b/src/write.c @@ -976,6 +976,18 @@ static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) return POLICYDB_ERROR; } + if ((p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || + (p->policy_type == POLICY_BASE && + p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { + buf[0] = cpu_to_le32(cladatum->default_user); + buf[1] = cpu_to_le32(cladatum->default_role); + buf[2] = cpu_to_le32(cladatum->default_range); + items = put_entry(buf, sizeof(uint32_t), 3, fp); + if (items != 3) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; } -- cgit v1.2.3