-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 This patch looks good to me. acked. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iEYEARECAAYFAlD+qLsACgkQrlYvE4MpobPpQACeJfnv4/N4BC+CnLP/svTUh6HL NgsAoIr8XAeq71y50bCCCvTE+4K0Wlnn =kVQz -----END PGP SIGNATURE-----
>From 979ed8b33d84ff5ad6eb461d2381df7f6d351b6d Mon Sep 17 00:00:00 2001 From: Eric Paris <eparis@xxxxxxxxxx> Date: Tue, 11 Dec 2012 17:52:41 -0500 Subject: [PATCH 70/84] libsepol: coverity fixes Signed-off-by: Eric Paris <eparis@xxxxxxxxxx> --- libsepol/src/avrule_block.c | 1 - libsepol/src/expand.c | 30 ++++++++++++++++--------- libsepol/src/genbools.c | 2 +- libsepol/src/genusers.c | 20 ++++++++++++----- libsepol/src/link.c | 54 ++++++++++++++++++++++++--------------------- libsepol/src/module.c | 39 +++++++++++++++++++++++++------- libsepol/src/policydb.c | 8 +++---- libsepol/src/write.c | 36 ++++++++++++++++-------------- 8 files changed, 120 insertions(+), 70 deletions(-) diff --git a/libsepol/src/avrule_block.c b/libsepol/src/avrule_block.c index 16c89f3..84cfaf8 100644 --- a/libsepol/src/avrule_block.c +++ b/libsepol/src/avrule_block.c @@ -61,7 +61,6 @@ avrule_decl_t *avrule_decl_create(uint32_t decl_id) for (i = 0; i < SYM_NUM; i++) { if (symtab_init(&decl->symtab[i], symtab_sizes[i])) { avrule_decl_destroy(decl); - free(decl); return NULL; } } diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index a2d209c..5231e3a 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -888,6 +888,7 @@ static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum, new_id = strdup(id); if (!new_id) { ERR(state->handle, "Out of memory!"); + free(new_role); return -1; } @@ -953,9 +954,13 @@ int mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l, l->sens = sl->sens; levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, - p->p_sens_val_to_name[l-> - sens - - 1]); + p->p_sens_val_to_name[l->sens - 1]); + if (!levdatum) { + ERR(h, "%s: Impossible situation found, nothing in p_levels.table.\n", + __func__); + errno = ENOENT; + return -1; + } for (cat = sl->cat; cat; cat = cat->next) { if (cat->low > cat->high) { ERR(h, "Category range is not valid %s.%s", @@ -1039,6 +1044,7 @@ static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum, new_id = strdup(id); if (!new_id) { ERR(state->handle, "Out of memory!"); + free(new_user); return -1; } ret = hashtab_insert(state->out->p_users.table, @@ -2078,6 +2084,8 @@ static int cond_node_copy(expand_state_t * state, cond_node_t * cn) } if (cond_node_map_bools(state, tmp)) { + cond_node_destroy(tmp); + free(tmp); ERR(state->handle, "Error mapping booleans"); return -1; } @@ -2273,9 +2281,15 @@ static int genfs_copy(expand_state_t * state) memset(newgenfs, 0, sizeof(genfs_t)); newgenfs->fstype = strdup(genfs->fstype); if (!newgenfs->fstype) { + free(newgenfs); ERR(state->handle, "Out of memory!"); return -1; } + if (!end) + state->out->genfs = newgenfs; + else + end->next = newgenfs; + end = newgenfs; l = NULL; for (c = genfs->head; c; c = c->next) { @@ -2288,6 +2302,7 @@ static int genfs_copy(expand_state_t * state) newc->u.name = strdup(c->u.name); if (!newc->u.name) { ERR(state->handle, "Out of memory!"); + free(newc); return -1; } newc->v.sclass = c->v.sclass; @@ -2298,12 +2313,6 @@ static int genfs_copy(expand_state_t * state) newgenfs->head = newc; l = newc; } - if (!end) { - state->out->genfs = newgenfs; - } else { - end->next = newgenfs; - } - end = newgenfs; } return 0; } @@ -3094,7 +3103,8 @@ int expand_module(sepol_handle_t * handle, } cond_optimize_lists(state.out->cond_list); - evaluate_conds(state.out); + if (evaluate_conds(state.out)) + goto cleanup; /* copy ocontexts */ if (ocontext_copy(&state, out->target_platform)) diff --git a/libsepol/src/genbools.c b/libsepol/src/genbools.c index 612ff9a..6a06ec9 100644 --- a/libsepol/src/genbools.c +++ b/libsepol/src/genbools.c @@ -33,7 +33,7 @@ static char *strtrim(char *dest, char *source, int size) static int process_boolean(char *buffer, char *name, int namesize, int *val) { char name1[BUFSIZ]; - char *ptr; + char *ptr = NULL; char *tok = strtok_r(buffer, "=", &ptr); if (tok) { strncpy(name1, tok, BUFSIZ - 1); diff --git a/libsepol/src/genusers.c b/libsepol/src/genusers.c index 37528e2..7826b71 100644 --- a/libsepol/src/genusers.c +++ b/libsepol/src/genusers.c @@ -92,22 +92,32 @@ static int load_users(struct policydb *policydb, const char *path) } else { char *id = strdup(q); + if (!id) { + ERR(NULL, "out of memory"); + free(buffer); + fclose(fp); + return -1; + } + /* Adding a new user definition. */ - usrdatum = - (user_datum_t *) malloc(sizeof(user_datum_t)); - if (!id || !usrdatum) { + usrdatum = malloc(sizeof(user_datum_t)); + if (!usrdatum) { ERR(NULL, "out of memory"); free(buffer); + free(id); fclose(fp); return -1; } - memset(usrdatum, 0, sizeof(user_datum_t)); + + user_datum_init(usrdatum); usrdatum->s.value = ++policydb->p_users.nprim; - ebitmap_init(&usrdatum->roles.roles); if (hashtab_insert(policydb->p_users.table, id, (hashtab_datum_t) usrdatum)) { ERR(NULL, "out of memory"); free(buffer); + free(id); + user_datum_destroy(usrdatum); + free(usrdatum); fclose(fp); return -1; } diff --git a/libsepol/src/link.c b/libsepol/src/link.c index 01d3231..defab47 100644 --- a/libsepol/src/link.c +++ b/libsepol/src/link.c @@ -676,13 +676,17 @@ static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum, "%s: Modules may not declare new sensitivities.", state->cur_mod_name); return SEPOL_ENOTSUP; - } - if (scope->scope == SCOPE_REQ) { + } else if (scope->scope == SCOPE_REQ) { /* unmet requirement */ ERR(state->handle, "%s: Sensitivity %s not declared by base.", state->cur_mod_name, id); return SEPOL_ENOTSUP; + } else { + ERR(state->handle, + "%s: has an unknown scope: %d\n", + state->cur_mod_name, scope->scope); + return SEPOL_ENOTSUP; } } @@ -704,8 +708,7 @@ static int cat_copy_callback(hashtab_key_t key, hashtab_datum_t datum, base_cat = hashtab_search(state->base->p_cats.table, id); if (!base_cat) { - scope = - hashtab_search(state->cur->policy->p_cat_scope.table, id); + scope = hashtab_search(state->cur->policy->p_cat_scope.table, id); if (!scope) return SEPOL_ERR; if (scope->scope == SCOPE_DECL) { @@ -714,13 +717,18 @@ static int cat_copy_callback(hashtab_key_t key, hashtab_datum_t datum, "%s: Modules may not declare new categories.", state->cur_mod_name); return SEPOL_ENOTSUP; - } - if (scope->scope == SCOPE_REQ) { + } else if (scope->scope == SCOPE_REQ) { /* unmet requirement */ ERR(state->handle, "%s: Category %s not declared by base.", state->cur_mod_name, id); return SEPOL_ENOTSUP; + } else { + /* unknown scope? malformed policy? */ + ERR(state->handle, + "%s: has an unknown scope: %d\n", + state->cur_mod_name, scope->scope); + return SEPOL_ENOTSUP; } } @@ -2001,6 +2009,7 @@ static int is_decl_requires_met(link_state_t * state, struct find_perm_arg fparg; class_datum_t *cladatum; uint32_t perm_value = j + 1; + int rc; scope_datum_t *scope; if (!ebitmap_node_get_bit(node, j)) { @@ -2022,11 +2031,13 @@ static int is_decl_requires_met(link_state_t * state, fparg.valuep = perm_value; fparg.key = NULL; - hashtab_map(cladatum->permissions.table, find_perm, + (void)hashtab_map(cladatum->permissions.table, find_perm, &fparg); - if (fparg.key == NULL && cladatum->comdatum != NULL) - hashtab_map(cladatum->comdatum->permissions. - table, find_perm, &fparg); + if (fparg.key == NULL && cladatum->comdatum != NULL) { + rc = hashtab_map(cladatum->comdatum->permissions.table, + find_perm, &fparg); + assert(rc == 1); + } perm_id = fparg.key; assert(perm_id != NULL); @@ -2050,6 +2061,7 @@ static int debug_requirements(link_state_t * state, policydb_t * p) int ret; avrule_block_t *cur; missing_requirement_t req; + memset(&req, 0, sizeof(req)); for (cur = p->global; cur != NULL; cur = cur->next) { if (cur->enabled != NULL) @@ -2062,34 +2074,27 @@ static int debug_requirements(link_state_t * state, policydb_t * p) char *mod_name = cur->branch_list->module_name ? cur->branch_list->module_name : "BASE"; if (req.symbol_type == SYM_CLASSES) { - struct find_perm_arg fparg; class_datum_t *cladatum; - cladatum = - p->class_val_to_struct[req.symbol_value - - 1]; + cladatum = p->class_val_to_struct[req.symbol_value - 1]; fparg.valuep = req.perm_value; fparg.key = NULL; - hashtab_map(cladatum->permissions.table, - find_perm, &fparg); + (void)hashtab_map(cladatum->permissions.table, + find_perm, &fparg); if (cur->flags & AVRULE_OPTIONAL) { ERR(state->handle, "%s[%d]'s optional requirements were not met: class %s, permission %s", mod_name, cur->branch_list->decl_id, - p->p_class_val_to_name[req. - symbol_value - - 1], + p->p_class_val_to_name[req.symbol_value - 1], fparg.key); } else { ERR(state->handle, "%s[%d]'s global requirements were not met: class %s, permission %s", mod_name, cur->branch_list->decl_id, - p->p_class_val_to_name[req. - symbol_value - - 1], + p->p_class_val_to_name[req.symbol_value - 1], fparg.key); } } else { @@ -2137,7 +2142,7 @@ static void print_missing_requirements(link_state_t * state, fparg.valuep = req->perm_value; fparg.key = NULL; - hashtab_map(cladatum->permissions.table, find_perm, &fparg); + (void)hashtab_map(cladatum->permissions.table, find_perm, &fparg); ERR(state->handle, "%s's global requirements were not met: class %s, permission %s", @@ -2148,8 +2153,7 @@ static void print_missing_requirements(link_state_t * state, "%s's global requirements were not met: %s %s", mod_name, symtab_names[req->symbol_type], - p->sym_val_to_name[req->symbol_type][req->symbol_value - - 1]); + p->sym_val_to_name[req->symbol_type][req->symbol_value - 1]); } } diff --git a/libsepol/src/module.c b/libsepol/src/module.c index b5b807e..1665ede 100644 --- a/libsepol/src/module.c +++ b/libsepol/src/module.c @@ -59,21 +59,34 @@ static int policy_file_seek(struct policy_file *fp, size_t offset) } } -static size_t policy_file_length(struct policy_file *fp) +static int policy_file_length(struct policy_file *fp, size_t *out) { long prev_offset, end_offset; + int rc; switch (fp->type) { case PF_USE_STDIO: prev_offset = ftell(fp->fp); - fseek(fp->fp, 0L, SEEK_END); + if (prev_offset < 0) + return prev_offset; + rc = fseek(fp->fp, 0L, SEEK_END); + if (rc < 0) + return rc; end_offset = ftell(fp->fp); - fseek(fp->fp, prev_offset, SEEK_SET); - return end_offset; + if (end_offset < 0) + return end_offset; + rc = fseek(fp->fp, prev_offset, SEEK_SET); + if (rc < 0) + return rc; + *out = end_offset; + break; case PF_USE_MEMORY: - return fp->size; + *out = fp->size; + break;; default: - return 0; + *out = 0; + break; } + return 0; } static int module_package_init(sepol_module_package_t * p) @@ -103,10 +116,17 @@ static int set_char(char **field, char *data, size_t len) int sepol_module_package_create(sepol_module_package_t ** p) { + int rc; + *p = calloc(1, sizeof(sepol_module_package_t)); if (!(*p)) return -1; - return module_package_init(*p); + + rc = module_package_init(*p); + if (rc < 0) + free(*p); + + return rc; } hidden_def(sepol_module_package_create) @@ -413,7 +433,10 @@ static int module_package_read_offsets(sepol_module_package_t * mod, } } - off[nsec] = policy_file_length(file); + rc = policy_file_length(file, &off[nsec]); + if (rc < 0) + goto err; + if (nsec && off[nsec] < off[nsec-1]) { ERR(file->handle, "offset greater than file size (at %u, " "offset %zu -> %zu", nsec, off[nsec - 1], diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index ff292f6..f325f87 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -1074,7 +1074,7 @@ static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p if (key) free(key); comdatum = (common_datum_t *) datum; - hashtab_map(comdatum->permissions.table, perm_destroy, 0); + (void)hashtab_map(comdatum->permissions.table, perm_destroy, 0); hashtab_destroy(comdatum->permissions.table); free(datum); return 0; @@ -1093,7 +1093,7 @@ static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p if (cladatum == NULL) { return 0; } - hashtab_map(cladatum->permissions.table, perm_destroy, 0); + (void)hashtab_map(cladatum->permissions.table, perm_destroy, 0); hashtab_destroy(cladatum->permissions.table); constraint = cladatum->constraints; while (constraint) { @@ -1261,7 +1261,7 @@ void policydb_destroy(policydb_t * p) free(p->decl_val_to_struct); for (i = 0; i < SYM_NUM; i++) { - hashtab_map(p->scope[i].table, scope_destroy, 0); + (void)hashtab_map(p->scope[i].table, scope_destroy, 0); hashtab_destroy(p->scope[i].table); } avrule_block_list_destroy(p->global); @@ -1351,7 +1351,7 @@ void symtabs_destroy(symtab_t * symtab) { int i; for (i = 0; i < SYM_NUM; i++) { - hashtab_map(symtab[i].table, destroy_f[i], 0); + (void)hashtab_map(symtab[i].table, destroy_f[i], 0); hashtab_destroy(symtab[i].table); } } diff --git a/libsepol/src/write.c b/libsepol/src/write.c index 22e6143..9f5201b 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c @@ -1795,34 +1795,38 @@ static int scope_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) uint32_t static_buf[32], *dyn_buf = NULL, *buf; size_t key_len = strlen(key); unsigned int items = 2 + scope->decl_ids_len, i; + int rc; + buf = static_buf; if (items >= (sizeof(static_buf) / 4)) { /* too many things required, so dynamically create a * buffer. this would have been easier with C99's * dynamic arrays... */ - if ((dyn_buf = malloc(items * sizeof(*dyn_buf))) == NULL) { - return POLICYDB_ERROR; - } + rc = POLICYDB_ERROR; + dyn_buf = malloc(items * sizeof(*dyn_buf)); + if (!dyn_buf) + goto err; buf = dyn_buf; - } else { - buf = static_buf; } buf[0] = cpu_to_le32(key_len); + + rc = POLICYDB_ERROR; if (put_entry(buf, sizeof(*buf), 1, fp) != 1 || - put_entry(key, 1, key_len, fp) != key_len) { - return POLICYDB_ERROR; - } + put_entry(key, 1, key_len, fp) != key_len) + goto err; buf[0] = cpu_to_le32(scope->scope); buf[1] = cpu_to_le32(scope->decl_ids_len); - for (i = 0; i < scope->decl_ids_len; i++) { + + for (i = 0; i < scope->decl_ids_len; i++) buf[2 + i] = cpu_to_le32(scope->decl_ids[i]); - } - if (put_entry(buf, sizeof(*buf), items, fp) != items) { - free(dyn_buf); - return POLICYDB_ERROR; - } + + rc = POLICYDB_ERROR; + if (put_entry(buf, sizeof(*buf), items, fp) != items) + goto err; + rc = POLICYDB_SUCCESS; +err: free(dyn_buf); - return POLICYDB_SUCCESS; + return rc; } static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)), @@ -2006,7 +2010,7 @@ int policydb_write(policydb_t * p, struct policy_file *fp) ((p->policy_type == POLICY_KERN) || (p->policy_type != POLICY_KERN && p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) - hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]); + (void)hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]); buf[1] = cpu_to_le32(buf[1]); items = put_entry(buf, sizeof(uint32_t), 2, fp); -- 1.8.1