static rpmRC sepolGo(void) { semanage_handle_t *sh; int existingPolicy; char *policytype = NULL; rpmRC rc = RPMRC_FAIL; static int performed = 0; if (performed) { return RPMRC_OK; } performed = 1; if (rpmChrootIn()) { goto exit; } if (selinux_getpolicytype(&policytype) < 0) { goto exit; } sepolPreparePolicies(policiesHead, policytype); /* determine if this is the first time installing policy */ sh = semanage_handle_create(); existingPolicy = (semanage_is_managed(sh) == 1); semanage_handle_destroy(sh); /* now load the policies */ rc = sepolLoadPolicies(policiesHead); /* re-init selinux and re-read the files contexts, since things may have changed */ selinux_reset_config(); if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) { if (rpmtsSELabelInit(ts, selinux_file_context_path()) == RPMRC_OK) { /* if this was the first time installing policy, every package before * policy was installed will be mislabeled (e.g. semodule). So, relabel * the entire filesystem if this is the case */ if (!existingPolicy) { if (sepolRelabelFiles() != RPMRC_OK) { rpmlog(RPMLOG_WARNING, _("Failed to relabel filesystem. Files may be mislabeled\n")); } } } else { rpmlog(RPMLOG_WARNING, _("Failed to reload file contexts. Files may be mislabeled\n")); } } exit: if (rpmChrootOut()) { rc = RPMRC_FAIL; } _free(policytype); return rc; }
rpmRC rpmtsSELabelInit(rpmts ts, int open_status) { #if WITH_SELINUX const char * path = selinux_file_context_path(); if (ts == NULL || path == NULL) { return RPMRC_FAIL; } if (open_status) { selinux_status_close(); if (selinux_status_open(0) < 0) { return RPMRC_FAIL; } } else if (!selinux_status_updated() && ts->selabelHandle) { return RPMRC_OK; } struct selinux_opt opts[] = { { .type = SELABEL_OPT_PATH, .value = path} };
rpmsx rpmsxNew(const char * fn, unsigned int flags) { rpmsx sx = rpmsxGetPool(_rpmsxPool); sx->fn = NULL; sx->flags = flags; #if defined(WITH_SELINUX) if (fn == NULL) fn = selinux_file_context_path(); if (sx->flags) set_matchpathcon_flags(sx->flags); { int rc; sx->fn = rpmGetPath(fn, NULL); rc = matchpathcon_init(sx->fn); /* If matchpathcon_init fails, turn off SELinux functionality. */ if (rc < 0) sx->fn = _free(sx->fn); } #endif return rpmsxLink(sx); }
static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet) { rpm_tid_t tid = (rpm_tid_t) time(NULL); int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) ? O_RDONLY : (O_RDWR|O_CREAT); if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS) (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers)); if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS) (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers)); if (rpmtsFlags(ts) & (RPMTRANS_FLAG_JUSTDB | RPMTRANS_FLAG_TEST)) (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers | RPMTRANS_FLAG_NOCOLLECTIONS)); /* if SELinux isn't enabled, init fails or test run, don't bother... */ if (!is_selinux_enabled() || (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS)); } if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) { rpmtsSELabelInit(ts, selinux_file_context_path()); } /* * Make sure the database is open RDWR for package install/erase. * Note that we initialize chroot state here even if it's just "/" as * this ensures we can successfully perform open(".") which is * required to reliably restore cwd after Lua scripts. */ if (rpmtsOpenDB(ts, dbmode) || rpmChrootSet(rpmtsRootDir(ts))) return -1; ts->ignoreSet = ignoreSet; (void) rpmtsSetTid(ts, tid); /* Get available space on mounted file systems. */ (void) rpmtsInitDSI(ts); return 0; }
static rpmRC sehandle_init(int open_status) { const char * path = selinux_file_context_path(); struct selinux_opt opts[] = { { .type = SELABEL_OPT_PATH, .value = path } };
static int init(struct selabel_handle *rec, struct selinux_opt *opts, unsigned n) { struct saved_data *data = (struct saved_data *)rec->data; const char *path = NULL; const char *prefix = NULL; FILE *fp; FILE *localfp = NULL; FILE *homedirfp = NULL; char local_path[PATH_MAX + 1]; char homedir_path[PATH_MAX + 1]; char *line_buf = NULL; size_t line_len = 0; unsigned int lineno, pass, i, j, maxnspec; spec_t *spec_copy = NULL; int status = -1, baseonly = 0; struct stat sb; /* Process arguments */ while (n--) switch(opts[n].type) { case SELABEL_OPT_PATH: path = opts[n].value; break; case SELABEL_OPT_SUBSET: prefix = opts[n].value; break; case SELABEL_OPT_BASEONLY: baseonly = !!opts[n].value; break; } /* Open the specification file. */ if (!path) path = selinux_file_context_path(); if ((fp = fopen(path, "r")) == NULL) return -1; __fsetlocking(fp, FSETLOCKING_BYCALLER); if (fstat(fileno(fp), &sb) < 0) return -1; if (!S_ISREG(sb.st_mode)) { errno = EINVAL; return -1; } if (!baseonly) { snprintf(homedir_path, sizeof(homedir_path), "%s.homedirs", path); homedirfp = fopen(homedir_path, "r"); if (homedirfp != NULL) __fsetlocking(homedirfp, FSETLOCKING_BYCALLER); snprintf(local_path, sizeof(local_path), "%s.local", path); localfp = fopen(local_path, "r"); if (localfp != NULL) __fsetlocking(localfp, FSETLOCKING_BYCALLER); } /* * Perform two passes over the specification file. * The first pass counts the number of specifications and * performs simple validation of the input. At the end * of the first pass, the spec array is allocated. * The second pass performs detailed validation of the input * and fills in the spec array. */ maxnspec = UINT_MAX / sizeof(spec_t); for (pass = 0; pass < 2; pass++) { lineno = 0; data->nspec = 0; data->ncomp = 0; while (getline(&line_buf, &line_len, fp) > 0 && data->nspec < maxnspec) { if (process_line(rec, path, prefix, line_buf, pass, ++lineno) != 0) goto finish; } if (pass == 1) { status = nodups_specs(data, path); if (status) goto finish; } lineno = 0; if (homedirfp) while (getline(&line_buf, &line_len, homedirfp) > 0 && data->nspec < maxnspec) { if (process_line (rec, homedir_path, prefix, line_buf, pass, ++lineno) != 0) goto finish; } lineno = 0; if (localfp) while (getline(&line_buf, &line_len, localfp) > 0 && data->nspec < maxnspec) { if (process_line (rec, local_path, prefix, line_buf, pass, ++lineno) != 0) goto finish; } if (pass == 0) { if (data->nspec == 0) { status = 0; goto finish; } if (NULL == (data->spec_arr = malloc(sizeof(spec_t) * data->nspec))) goto finish; memset(data->spec_arr, 0, sizeof(spec_t)*data->nspec); maxnspec = data->nspec; rewind(fp); if (homedirfp) rewind(homedirfp); if (localfp) rewind(localfp); } } free(line_buf); /* Move exact pathname specifications to the end. */ spec_copy = malloc(sizeof(spec_t) * data->nspec); if (!spec_copy) goto finish; j = 0; for (i = 0; i < data->nspec; i++) if (data->spec_arr[i].hasMetaChars) memcpy(&spec_copy[j++], &data->spec_arr[i], sizeof(spec_t)); for (i = 0; i < data->nspec; i++) if (!data->spec_arr[i].hasMetaChars) memcpy(&spec_copy[j++], &data->spec_arr[i], sizeof(spec_t)); free(data->spec_arr); data->spec_arr = spec_copy; status = 0; finish: fclose(fp); if (data->spec_arr != spec_copy) free(data->spec_arr); if (homedirfp) fclose(homedirfp); if (localfp) fclose(localfp); return status; }
static int init(struct selabel_handle *rec, const struct selinux_opt *opts, unsigned n) { struct saved_data *data = (struct saved_data *)rec->data; const char *path = NULL; const char *prefix = NULL; char subs_file[PATH_MAX + 1]; int status = -1, baseonly = 0; /* Process arguments */ while (n--) switch(opts[n].type) { case SELABEL_OPT_PATH: path = opts[n].value; break; case SELABEL_OPT_SUBSET: prefix = opts[n].value; break; case SELABEL_OPT_BASEONLY: baseonly = !!opts[n].value; break; } /* Process local and distribution substitution files */ if (!path) { rec->dist_subs = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->dist_subs); rec->subs = selabel_subs_init(selinux_file_context_subs_path(), rec->subs); path = selinux_file_context_path(); } else { snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", path); rec->dist_subs = selabel_subs_init(subs_file, rec->dist_subs); snprintf(subs_file, sizeof(subs_file), "%s.subs", path); rec->subs = selabel_subs_init(subs_file, rec->subs); } rec->spec_file = strdup(path); /* * The do detailed validation of the input and fill the spec array */ status = process_file(path, NULL, rec, prefix); if (status) goto finish; if (rec->validating) { status = nodups_specs(data, path); if (status) goto finish; } if (!baseonly) { status = process_file(path, "homedirs", rec, prefix); if (status && errno != ENOENT) goto finish; status = process_file(path, "local", rec, prefix); if (status && errno != ENOENT) goto finish; } status = sort_specs(data); finish: if (status) free(data->spec_arr); return status; }
static JSBool rpmsx_getprop(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmsxClass, NULL); jsint tiny = JSVAL_TO_INT(id); #if defined(WITH_SELINUX) security_context_t con = NULL; #endif /* XXX the class has ptr == NULL, instances have ptr != NULL. */ if (ptr == NULL) return JS_TRUE; switch (tiny) { case _DEBUG: *vp = INT_TO_JSVAL(_debug); break; #if defined(WITH_SELINUX) case _CURRENT: *vp = _GET_CON(!getcon(&con)); break; case _PID: *vp = _GET_CON(!getpidcon(getpid(), &con)); break; case _PPID: *vp = _GET_CON(!getpidcon(getppid(), &con)); break; case _PREV: *vp = _GET_CON(!getprevcon(&con)); break; case _EXEC: *vp = _GET_CON(!getexeccon(&con)); break; case _FSCREATE: *vp = _GET_CON(!getfscreatecon(&con)); break; case _KEYCREATE: *vp = _GET_CON(!getkeycreatecon(&con)); break; case _SOCKCREATE: *vp = _GET_CON(!getsockcreatecon(&con)); break; case _ENFORCE: *vp = INT_TO_JSVAL(security_getenforce()); break; case _DENY: *vp = INT_TO_JSVAL(security_deny_unknown()); break; case _POLICYVERS: *vp = INT_TO_JSVAL(security_policyvers()); break; case _ENABLED: *vp = INT_TO_JSVAL(is_selinux_enabled()); break; case _MLSENABLED: *vp = INT_TO_JSVAL(is_selinux_mls_enabled()); break; #ifdef NOTYET case _BOOLS: *vp = ; break; #endif case _ROOT: *vp = _GET_STR(selinux_policy_root()); break; case _BINARY: *vp = _GET_STR(selinux_binary_policy_path()); break; case _FAILSAFE: *vp = _GET_STR(selinux_failsafe_context_path());break; case _REMOVABLE: *vp = _GET_STR(selinux_removable_context_path());break; case _DEFAULT: *vp = _GET_STR(selinux_default_context_path()); break; case _USER: *vp = _GET_STR(selinux_user_contexts_path()); break; case _FCON: *vp = _GET_STR(selinux_file_context_path()); break; case _FCONHOME: *vp = _GET_STR(selinux_file_context_homedir_path());break; case _FCONLOCAL: *vp = _GET_STR(selinux_file_context_local_path());break; case _FCONSUBS: *vp = _GET_STR(selinux_file_context_subs_path());break; case _HOMEDIR: *vp = _GET_STR(selinux_homedir_context_path()); break; case _MEDIA: *vp = _GET_STR(selinux_media_context_path()); break; case _VIRTDOMAIN: *vp = _GET_STR(selinux_virtual_domain_context_path());break; case _VIRTIMAGE: *vp = _GET_STR(selinux_virtual_image_context_path());break; case _X: *vp = _GET_STR(selinux_x_context_path()); break; case _CONTEXTS: *vp = _GET_STR(selinux_contexts_path()); break; case _SECURETTY: *vp = _GET_STR(selinux_securetty_types_path()); break; case _BOOLEANS: *vp = _GET_STR(selinux_booleans_path()); break; case _CUSTOMTYPES: *vp = _GET_STR(selinux_customizable_types_path());break; case _USERS: *vp = _GET_STR(selinux_users_path()); break; case _USERSCONF: *vp = _GET_STR(selinux_usersconf_path()); break; case _XLATIONS: *vp = _GET_STR(selinux_translations_path()); break; case _COLORS: *vp = _GET_STR(selinux_colors_path()); break; case _NETFILTER: *vp = _GET_STR(selinux_netfilter_context_path());break; case _PATH: *vp = _GET_STR(selinux_path()); break; #endif default: break; } #if defined(WITH_SELINUX) if (con) { freecon(con); con = NULL; } #endif return JS_TRUE; }