static int check_line(genhomedircon_settings_t * s, Ustr *line) { sepol_context_t *ctx_record = NULL; const char *ctx_str; int result; ctx_str = extract_context(line); if (!ctx_str) return STATUS_ERR; result = sepol_context_from_string(s->h_semanage->sepolh, ctx_str, &ctx_record); if (result == STATUS_SUCCESS && ctx_record != NULL) { sepol_msg_set_callback(s->h_semanage->sepolh, NULL, NULL); result = sepol_context_check(s->h_semanage->sepolh, s->policydb, ctx_record); sepol_msg_set_callback(s->h_semanage->sepolh, semanage_msg_relay_handler, s->h_semanage); sepol_context_free(ctx_record); } return result; }
semanage_handle_t *semanage_handle_create(void) { semanage_handle_t *sh = NULL; const char *conf_name = NULL; /* Allocate handle */ if ((sh = calloc(1, sizeof(semanage_handle_t))) == NULL) goto err; if ((conf_name = semanage_conf_path()) == NULL) goto err; if ((sh->conf = semanage_conf_parse(conf_name)) == NULL) goto err; /* Link to sepol handle */ sh->sepolh = sepol_handle_create(); if (!sh->sepolh) goto err; sepol_msg_set_callback(sh->sepolh, semanage_msg_relay_handler, sh); /* By default do not rebuild the policy on commit * If any changes are made, this flag is ignored */ sh->do_rebuild = 0; /* By default always reload policy after commit if SELinux is enabled. */ sh->do_reload = (is_selinux_enabled() > 0); /* By default always check the file contexts file. */ sh->do_check_contexts = 1; /* By default do not create store */ sh->create_store = 0; /* Set timeout: some default value for now, later use config */ sh->timeout = SEMANAGE_COMMIT_READ_WAIT; /* Set callback */ sh->msg_callback = semanage_msg_default_handler; sh->msg_callback_arg = NULL; return sh; err: semanage_handle_destroy(sh); return NULL; }
// /sys/fs/selinux/load requires the entire policy to be written in a single // write(2) call. // See: http://marc.info/?l=selinux&m=141882521027239&w=2 bool selinux_write_policy(const std::string &path, policydb_t *pdb) { void *data; size_t len; sepol_handle_t *handle; int fd; // Don't print warnings to stderr handle = sepol_handle_create(); sepol_msg_set_callback(handle, nullptr, nullptr); auto destroy_handle = finally([&] { sepol_handle_destroy(handle); }); if (policydb_to_image(handle, pdb, &data, &len) < 0) { LOGE("Failed to write policydb to memory"); return false; } auto free_data = finally([&] { free(data); }); fd = open(path.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0644); if (fd < 0) { LOGE("Failed to open %s: %s", path.c_str(), strerror(errno)); return false; } auto close_fd = finally([&] { close(fd); }); if (write(fd, data, len) < 0) { LOGE("Failed to write to %s: %s", path.c_str(), strerror(errno)); return false; } return true; }