00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "find_file_types.h"
00028
00029 #include <qpol/genfscon_query.h>
00030
00031 #include <stdio.h>
00032 #include <string.h>
00033 #include <unistd.h>
00034 #include <errno.h>
00035
00036 static const char *const mod_name = "find_file_types";
00037
00038 int find_file_types_register(sechk_lib_t * lib)
00039 {
00040 sechk_module_t *mod = NULL;
00041 sechk_fn_t *fn_struct = NULL;
00042 sechk_name_value_t *nv = NULL;
00043
00044 if (!lib) {
00045 ERR(NULL, "%s", "No library");
00046 errno = EINVAL;
00047 return -1;
00048 }
00049
00050 mod = sechk_lib_get_module(mod_name, lib);
00051 if (!mod) {
00052 ERR(NULL, "%s", "Module unknown");
00053 errno = EINVAL;
00054 return -1;
00055 }
00056 mod->parent_lib = lib;
00057
00058
00059
00060 mod->brief_description = "utility module";
00061 mod->detailed_description =
00062 "--------------------------------------------------------------------------------\n"
00063 "This module finds all types in the policy treated as a file type. A type is \n"
00064 "considered a file type if any of the following is true:\n"
00065 "\n"
00066 " 1) it has an attribute associated with file types\n"
00067 " 2) it is the source of a rule to allow filesystem associate permission\n"
00068 " 3) it is the default type of a type transition rule with an object class\n" " other than process\n"
00069 " 4) it is specified in a context in the file_contexts file\n";
00070 mod->opt_description = "Module requirements:\n" " attribute names\n"
00071 " file_contexts\n"
00072 "Module dependencies:\n" " none\n" "Module options:\n" " file_type_attribute can be modified in a profile\n";
00073 mod->severity = SECHK_SEV_NONE;
00074
00075 nv = sechk_name_value_new(SECHK_REQ_POLICY_CAP, SECHK_REQ_CAP_ATTRIB_NAMES);
00076 apol_vector_append(mod->requirements, (void *)nv);
00077 nv = sechk_name_value_new(SECHK_REQ_FILE_CONTEXTS, NULL);
00078 apol_vector_append(mod->requirements, (void *)nv);
00079
00080
00081 nv = sechk_name_value_new("file_type_attribute", "file_type");
00082 apol_vector_append(mod->options, (void *)nv);
00083
00084
00085 fn_struct = sechk_fn_new();
00086 if (!fn_struct) {
00087 ERR(NULL, "%s", strerror(ENOMEM));
00088 errno = ENOMEM;
00089 return -1;
00090 }
00091 fn_struct->name = strdup(SECHK_MOD_FN_INIT);
00092 if (!fn_struct->name) {
00093 ERR(NULL, "%s", strerror(ENOMEM));
00094 errno = ENOMEM;
00095 return -1;
00096 }
00097 fn_struct->fn = find_file_types_init;
00098 apol_vector_append(mod->functions, (void *)fn_struct);
00099
00100 fn_struct = sechk_fn_new();
00101 if (!fn_struct) {
00102 ERR(NULL, "%s", strerror(ENOMEM));
00103 errno = ENOMEM;
00104 return -1;
00105 }
00106 fn_struct->name = strdup(SECHK_MOD_FN_RUN);
00107 if (!fn_struct->name) {
00108 ERR(NULL, "%s", strerror(ENOMEM));
00109 errno = ENOMEM;
00110 return -1;
00111 }
00112 fn_struct->fn = find_file_types_run;
00113 apol_vector_append(mod->functions, (void *)fn_struct);
00114
00115 mod->data_free = find_file_types_data_free;
00116
00117 fn_struct = sechk_fn_new();
00118 if (!fn_struct) {
00119 ERR(NULL, "%s", strerror(ENOMEM));
00120 errno = ENOMEM;
00121 return -1;
00122 }
00123 fn_struct->name = strdup(SECHK_MOD_FN_PRINT);
00124 if (!fn_struct->name) {
00125 ERR(NULL, "%s", strerror(ENOMEM));
00126 errno = ENOMEM;
00127 return -1;
00128 }
00129 fn_struct->fn = find_file_types_print;
00130 apol_vector_append(mod->functions, (void *)fn_struct);
00131
00132 fn_struct = sechk_fn_new();
00133 if (!fn_struct) {
00134 ERR(NULL, "%s", strerror(ENOMEM));
00135 errno = ENOMEM;
00136 return -1;
00137 }
00138 fn_struct->name = strdup("get_list");
00139 if (!fn_struct->name) {
00140 ERR(NULL, "%s", strerror(ENOMEM));
00141 errno = ENOMEM;
00142 return -1;
00143 }
00144 fn_struct->fn = find_file_types_get_list;
00145 apol_vector_append(mod->functions, (void *)fn_struct);
00146
00147 return 0;
00148 }
00149
00150 int find_file_types_init(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00151 {
00152 sechk_name_value_t *opt = NULL;
00153 find_file_types_data_t *datum = NULL;
00154 apol_vector_t *attr_vector = NULL;
00155 apol_attr_query_t *attr_query = apol_attr_query_create();
00156 qpol_type_t *attr = NULL;
00157 qpol_policy_t *q = apol_policy_get_qpol(policy);
00158 size_t i = 0, j = 0;
00159
00160 if (!mod || !policy) {
00161 ERR(policy, "%s", "Invalid parameters");
00162 errno = EINVAL;
00163 return -1;
00164 }
00165 if (strcmp(mod_name, mod->name)) {
00166 ERR(policy, "Wrong module (%s)", mod->name);
00167 errno = EINVAL;
00168 return -1;
00169 }
00170
00171 datum = find_file_types_data_new();
00172 if (!datum) {
00173 ERR(policy, "%s", strerror(ENOMEM));
00174 errno = ENOMEM;
00175 return -1;
00176 }
00177 if (!(datum->file_type_attribs = apol_vector_create(NULL))) {
00178 ERR(policy, "%s", strerror(ENOMEM));
00179 errno = ENOMEM;
00180 return -1;
00181 }
00182 mod->data = datum;
00183
00184 for (i = 0; i < apol_vector_get_size(mod->options); i++) {
00185 opt = apol_vector_get_element(mod->options, i);
00186 if (!strcmp(opt->name, "file_type_attribute")) {
00187 apol_attr_query_set_attr(policy, attr_query, opt->value);
00188 apol_attr_get_by_query(policy, attr_query, &attr_vector);
00189 for (j = 0; j < apol_vector_get_size(attr_vector); j++) {
00190 const char *file_attrib;
00191 attr = apol_vector_get_element(attr_vector, j);
00192 qpol_type_get_name(q, attr, &file_attrib);
00193 if (apol_vector_append(datum->file_type_attribs, (void *)file_attrib) < 0) {
00194 ERR(policy, "%s", strerror(ENOMEM));
00195 errno = ENOMEM;
00196 return -1;
00197 }
00198 }
00199 apol_vector_destroy(&attr_vector);
00200 }
00201 }
00202 apol_attr_query_destroy(&attr_query);
00203 return 0;
00204 }
00205
00206 int find_file_types_run(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00207 {
00208 find_file_types_data_t *datum;
00209 sechk_item_t *item = NULL;
00210 sechk_proof_t *proof = NULL;
00211 sechk_result_t *res = NULL;
00212 const char *type_name = NULL;
00213 apol_avrule_query_t *avrule_query = NULL;
00214 apol_terule_query_t *terule_query = NULL;
00215 apol_vector_t *avrule_vector = NULL;
00216 apol_vector_t *terule_vector = NULL;
00217 qpol_policy_t *q = apol_policy_get_qpol(policy);
00218 size_t i, j, x;
00219 char *buff = NULL;
00220 int error = 0;
00221
00222
00223 size_t num_fc_entries = 0;
00224 apol_vector_t *type_vector = NULL;
00225 apol_vector_t *fc_entry_vector = NULL;
00226
00227 if (!mod || !policy) {
00228 ERR(policy, "%s", "Invalid parameters");
00229 errno = EINVAL;
00230 return -1;
00231 }
00232 if (strcmp(mod_name, mod->name)) {
00233 ERR(policy, "Wrong module (%s)", mod->name);
00234 errno = EINVAL;
00235 return -1;
00236 }
00237
00238
00239 if (mod->result)
00240 return 0;
00241
00242 res = sechk_result_new();
00243 if (!res) {
00244 ERR(policy, "%s", strerror(ENOMEM));
00245 errno = ENOMEM;
00246 return -1;
00247 }
00248
00249 datum = (find_file_types_data_t *) mod->data;
00250 res->item_type = SECHK_ITEM_TYPE;
00251 res->test_name = strdup(mod_name);
00252 if (!res->test_name) {
00253 error = errno;
00254 ERR(policy, "%s", strerror(ENOMEM));
00255 goto find_file_types_run_fail;
00256 }
00257 if (!(res->items = apol_vector_create(sechk_item_free))) {
00258 error = errno;
00259 ERR(policy, "%s", strerror(ENOMEM));
00260 goto find_file_types_run_fail;
00261 }
00262 if (mod->parent_lib->fc_entries) {
00263 if (mod->parent_lib->fc_path) {
00264 fc_entry_vector = mod->parent_lib->fc_entries;
00265 num_fc_entries = apol_vector_get_size(fc_entry_vector);
00266 } else {
00267 error = ENOENT;
00268 ERR(policy, "%s", "Unable to find file contexts file");
00269 goto find_file_types_run_fail;
00270 }
00271 }
00272
00273
00274 if (apol_type_get_by_query(policy, NULL, &type_vector) < 0) {
00275 error = errno;
00276 ERR(policy, "%s", "Unable to retrieve types");
00277 return -1;
00278 }
00279
00280 for (i = 0; i < apol_vector_get_size(type_vector); i++) {
00281 qpol_iterator_t *file_attr_iter;
00282
00283 const qpol_type_t *type = apol_vector_get_element(type_vector, i);
00284 qpol_type_get_name(q, type, &type_name);
00285
00286 if (qpol_type_get_attr_iter(q, type, &file_attr_iter) < 0) {
00287 error = errno;
00288 ERR(policy, "Could not get attributes for %s\n", type_name);
00289 goto find_file_types_run_fail;
00290 }
00291
00292 for (; !qpol_iterator_end(file_attr_iter); qpol_iterator_next(file_attr_iter)) {
00293 const char *attr_name;
00294 const qpol_type_t *attr;
00295 size_t nfta;
00296
00297 qpol_iterator_get_item(file_attr_iter, (void **)&attr);
00298 qpol_type_get_name(q, attr, &attr_name);
00299 for (nfta = 0; nfta < apol_vector_get_size(datum->file_type_attribs); nfta++) {
00300 const char *file_type_attrib;
00301
00302 file_type_attrib = apol_vector_get_element(datum->file_type_attribs, nfta);
00303 if (!strcmp(attr_name, file_type_attrib)) {
00304 proof = sechk_proof_new(NULL);
00305 if (!proof) {
00306 error = errno;
00307 ERR(policy, "%s", strerror(ENOMEM));
00308 goto find_file_types_run_fail;
00309 }
00310 proof->type = SECHK_ITEM_ATTRIB;
00311 proof->elem = (void *)attr;
00312 asprintf(&proof->text, "has attribute %s", attr_name);
00313 if (!item) {
00314 item = sechk_item_new(NULL);
00315 if (!item) {
00316 error = errno;
00317 ERR(policy, "%s", strerror(ENOMEM));
00318 goto find_file_types_run_fail;
00319 }
00320 item->test_result = 1;
00321 }
00322 if (!item->proof) {
00323 if (!(item->proof = apol_vector_create(sechk_proof_free))) {
00324 error = errno;
00325 ERR(policy, "%s", strerror(ENOMEM));
00326 goto find_file_types_run_fail;
00327 }
00328 }
00329 if (apol_vector_append(item->proof, (void *)proof) < 0) {
00330 error = errno;
00331 ERR(policy, "%s", strerror(ENOMEM));
00332 goto find_file_types_run_fail;
00333 }
00334 }
00335 }
00336 }
00337 qpol_iterator_destroy(&file_attr_iter);
00338
00339
00340 if (!(avrule_query = apol_avrule_query_create())) {
00341 error = errno;
00342 ERR(policy, "%s", "Could not retrieve AV rules");
00343 goto find_file_types_run_fail;
00344 }
00345 apol_avrule_query_set_source(policy, avrule_query, type_name, 0);
00346 apol_avrule_query_append_class(policy, avrule_query, "filesystem");
00347 apol_avrule_query_append_perm(policy, avrule_query, "associate");
00348 apol_avrule_get_by_query(policy, avrule_query, &avrule_vector);
00349 for (x = 0; x < apol_vector_get_size(avrule_vector); x++) {
00350 qpol_avrule_t *avrule;
00351 avrule = apol_vector_get_element(avrule_vector, x);
00352 if (avrule) {
00353 proof = sechk_proof_new(NULL);
00354 if (!proof) {
00355 error = errno;
00356 ERR(policy, "%s", strerror(ENOMEM));
00357 goto find_file_types_run_fail;
00358 }
00359 proof->type = SECHK_ITEM_AVRULE;
00360 proof->elem = avrule;
00361 proof->text = apol_avrule_render(policy, avrule);
00362 if (!item) {
00363 item = sechk_item_new(NULL);
00364 if (!item) {
00365 error = errno;
00366 ERR(policy, "%s", strerror(ENOMEM));
00367 goto find_file_types_run_fail;
00368 }
00369 item->test_result = 1;
00370 }
00371 if (!item->proof) {
00372 if (!(item->proof = apol_vector_create(sechk_proof_free))) {
00373 error = errno;
00374 ERR(policy, "%s", strerror(ENOMEM));
00375 goto find_file_types_run_fail;
00376 }
00377 }
00378 item->test_result = 1;
00379 if (apol_vector_append(item->proof, (void *)proof) < 0) {
00380 error = errno;
00381 ERR(policy, "%s", strerror(ENOMEM));
00382 goto find_file_types_run_fail;
00383 }
00384 }
00385 }
00386 apol_vector_destroy(&avrule_vector);
00387 apol_avrule_query_destroy(&avrule_query);
00388
00389
00390 if (!(terule_query = apol_terule_query_create())) {
00391 error = errno;
00392 ERR(policy, "%s", "Could not retrieve TE rules");
00393 goto find_file_types_run_fail;
00394 }
00395 apol_terule_query_set_default(policy, terule_query, type_name);
00396 apol_terule_get_by_query(policy, terule_query, &terule_vector);
00397 for (x = 0; x < apol_vector_get_size(terule_vector); x++) {
00398 const qpol_terule_t *terule;
00399 const qpol_class_t *objclass;
00400 const char *class_name;
00401
00402 terule = apol_vector_get_element(terule_vector, x);
00403 qpol_terule_get_object_class(q, terule, &objclass);
00404 qpol_class_get_name(q, objclass, &class_name);
00405 if (strcmp(class_name, "process")) {
00406 proof = sechk_proof_new(NULL);
00407 if (!proof) {
00408 error = errno;
00409 ERR(policy, "%s", strerror(ENOMEM));
00410 goto find_file_types_run_fail;
00411 }
00412 proof->type = SECHK_ITEM_TERULE;
00413 proof->elem = (void *)terule;
00414 proof->text = apol_terule_render(policy, terule);
00415 if (!item) {
00416 item = sechk_item_new(NULL);
00417 if (!item) {
00418 error = errno;
00419 ERR(policy, "%s", strerror(ENOMEM));
00420 goto find_file_types_run_fail;
00421 }
00422 item->test_result = 1;
00423 }
00424 if (!item->proof) {
00425 if (!(item->proof = apol_vector_create(sechk_proof_free))) {
00426 error = errno;
00427 ERR(policy, "%s", strerror(ENOMEM));
00428 goto find_file_types_run_fail;
00429 }
00430 }
00431 item->test_result = 1;
00432 if (apol_vector_append(item->proof, (void *)proof) < 0) {
00433 error = errno;
00434 ERR(policy, "%s", strerror(ENOMEM));
00435 goto find_file_types_run_fail;
00436 }
00437 }
00438 }
00439 apol_vector_destroy(&terule_vector);
00440 apol_terule_query_destroy(&terule_query);
00441
00442
00443 if (fc_entry_vector) {
00444 buff = NULL;
00445 for (j = 0; j < num_fc_entries; j++) {
00446 sefs_entry_t *fc_entry;
00447 const char *fc_type_name = NULL;
00448 fc_entry = apol_vector_get_element(fc_entry_vector, j);
00449 const apol_context_t *context = sefs_entry_get_context(fc_entry);
00450 if (!context)
00451 continue;
00452 fc_type_name = apol_context_get_type(context);
00453 if (!strcmp(type_name, fc_type_name)) {
00454 buff = sefs_entry_to_string(fc_entry);
00455 proof = sechk_proof_new(NULL);
00456 if (!proof) {
00457 error = errno;
00458 ERR(policy, "%s", strerror(ENOMEM));
00459 goto find_file_types_run_fail;
00460 }
00461 proof->type = SECHK_ITEM_FCENT;
00462 proof->elem = fc_entry;
00463 proof->text = buff;
00464 buff = NULL;
00465 if (!item) {
00466 item = sechk_item_new(NULL);
00467 if (!item) {
00468 error = errno;
00469 ERR(policy, "%s", strerror(ENOMEM));
00470 goto find_file_types_run_fail;
00471 }
00472 item->test_result = 1;
00473 }
00474 if (!item->proof) {
00475 if (!(item->proof = apol_vector_create(sechk_proof_free))) {
00476 error = errno;
00477 ERR(policy, "%s", strerror(ENOMEM));
00478 goto find_file_types_run_fail;
00479 }
00480 }
00481 if (apol_vector_append(item->proof, (void *)proof) < 0) {
00482 error = errno;
00483 ERR(policy, "%s", strerror(ENOMEM));
00484 goto find_file_types_run_fail;
00485 }
00486 }
00487 }
00488 }
00489
00490 if (item) {
00491 item->item = (void *)type;
00492 if (apol_vector_append(res->items, (void *)item) < 0) {
00493 error = errno;
00494 ERR(policy, "%s", strerror(ENOMEM));
00495 goto find_file_types_run_fail;
00496 }
00497 }
00498 item = NULL;
00499 type = NULL;
00500 type_name = NULL;
00501 }
00502 apol_vector_destroy(&type_vector);
00503
00504
00505 mod->result = res;
00506
00507 return 0;
00508
00509 find_file_types_run_fail:
00510 sechk_proof_free(proof);
00511 sechk_item_free(item);
00512 free(buff);
00513 apol_vector_destroy(&type_vector);
00514 sechk_result_destroy(&res);
00515 errno = error;
00516 return -1;
00517 }
00518
00519 void find_file_types_data_free(void *data)
00520 {
00521 find_file_types_data_t *datum = (find_file_types_data_t *) data;
00522
00523 if (datum) {
00524 apol_vector_destroy(&datum->file_type_attribs);
00525 }
00526 free(data);
00527 }
00528
00529 int find_file_types_print(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00530 {
00531 find_file_types_data_t *datum = NULL;
00532 unsigned char outformat = 0x00;
00533 sechk_item_t *item = NULL;
00534 sechk_proof_t *proof = NULL;
00535 size_t i = 0, j = 0, k = 0, l = 0, num_items = 0;
00536 const qpol_type_t *type;
00537 qpol_policy_t *q = apol_policy_get_qpol(policy);
00538 const char *type_name;
00539
00540 if (!mod || !policy) {
00541 ERR(policy, "%s", "Invalid parameters");
00542 errno = EINVAL;
00543 return -1;
00544 }
00545 if (strcmp(mod_name, mod->name)) {
00546 ERR(policy, "Wrong module (%s)", mod->name);
00547 errno = EINVAL;
00548 return -1;
00549 }
00550
00551 datum = (find_file_types_data_t *) mod->data;
00552 outformat = mod->outputformat;
00553
00554 if (!mod->result) {
00555 ERR(policy, "%s", "Module has not been run");
00556 errno = EINVAL;
00557 return -1;
00558 }
00559
00560 if (!outformat || (outformat & SECHK_OUT_QUIET))
00561 return 0;
00562 if (outformat & SECHK_OUT_STATS) {
00563 num_items = apol_vector_get_size(mod->result->items);
00564 printf("Found %zd file types.\n", num_items);
00565 }
00566 if (outformat & SECHK_OUT_PROOF) {
00567 printf("\nThe following types are file types.\n\n");
00568 }
00569 if (outformat & SECHK_OUT_LIST) {
00570 printf("\n");
00571 for (i = 0; i < apol_vector_get_size(mod->result->items); i++) {
00572 j++;
00573 item = apol_vector_get_element(mod->result->items, i);
00574 type = item->item;
00575 qpol_type_get_name(q, type, &type_name);
00576 j %= 4;
00577 printf("%s%s", type_name, (char *)((j && i != num_items - 1) ? ", " : "\n"));
00578 }
00579 printf("\n");
00580 }
00581
00582 if (outformat & SECHK_OUT_PROOF) {
00583 printf("\n");
00584 for (k = 0; k < apol_vector_get_size(mod->result->items); k++) {
00585 item = apol_vector_get_element(mod->result->items, k);
00586 if (item) {
00587 type = item->item;
00588 qpol_type_get_name(q, type, &type_name);
00589 printf("%s\n", (char *)type_name);
00590 for (l = 0; l < apol_vector_get_size(item->proof); l++) {
00591 proof = apol_vector_get_element(item->proof, l);
00592 if (proof)
00593 printf("\t%s\n", proof->text);
00594 }
00595 }
00596 }
00597 printf("\n");
00598 }
00599
00600 return 0;
00601 }
00602
00603 int find_file_types_get_list(sechk_module_t * mod, apol_policy_t * policy __attribute__ ((unused)), void *arg
00604 __attribute__ ((unused)))
00605 {
00606 apol_vector_t **v = arg;
00607
00608 if (!mod || !arg) {
00609 ERR(NULL, "%s", strerror(EINVAL));
00610 errno = EINVAL;
00611 return -1;
00612 }
00613 if (strcmp(mod_name, mod->name)) {
00614 ERR(NULL, "Wrong module (%s)", mod->name);
00615 errno = EINVAL;
00616 return -1;
00617 }
00618 if (!mod->result) {
00619 ERR(NULL, "%s", "Module has not been run");
00620 errno = EINVAL;
00621 return -1;
00622 }
00623
00624 v = &mod->result->items;
00625
00626 return 0;
00627 }
00628
00629 find_file_types_data_t *find_file_types_data_new(void)
00630 {
00631 find_file_types_data_t *datum = NULL;
00632
00633 datum = (find_file_types_data_t *) calloc(1, sizeof(find_file_types_data_t));
00634
00635 return datum;
00636 }