#include "sd-messages.h"
+#include "errno-util.h"
#include "initrd-util.h"
#include "log.h"
#include "macro.h"
#endif
int mac_selinux_setup(bool *loaded_policy) {
+ assert(loaded_policy);
#if HAVE_SELINUX
- int enforce = 0;
- usec_t before_load, after_load;
- char *con;
int r;
- bool initialized;
-
- assert(loaded_policy);
- /* Turn off all of SELinux' own logging, we want to do that */
+ /* Turn off all of SELinux' own logging, we want to do that ourselves */
selinux_set_callback(SELINUX_CB_LOG, (const union selinux_callback) { .func_log = null_log });
/* Don't load policy in the initrd if we don't appear to have it. For the real root, we check below
* if we've already loaded policy, and return gracefully. */
- if (in_initrd() && access(selinux_path(), F_OK) < 0)
+ if (in_initrd() && access(selinux_path(), F_OK) < 0) {
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Unable to check if %s exists, assuming it does not: %m", selinux_path());
+
return 0;
+ }
- /* Already initialized by somebody else? */
- r = getcon_raw(&con);
- /* getcon_raw can return 0, and still give us a NULL pointer if /proc/self/attr/current is
+ bool initialized = false;
+
+ /* Already initialized by somebody else?
+ *
+ * Note: getcon_raw() can return 0, and still give us a NULL pointer if /proc/self/attr/current is
* empty. SELinux guarantees this won't happen, but that file isn't specific to SELinux, and may be
* provided by some other arbitrary LSM with different semantics. */
- if (r == 0 && con) {
+ _cleanup_freecon_ char *con = NULL;
+ if (getcon_raw(&con) < 0)
+ log_debug_errno(errno, "getcon_raw() failed, assuming SELinux is not initialized: %m");
+ else if (con) {
initialized = !streq(con, "kernel");
- freecon(con);
- } else
- initialized = false;
+ log_debug("SELinux already initialized: %s", yes_no(initialized));
+ }
- /* Make sure we have no fds open while loading the policy and
- * transitioning */
+ /* Make sure we have no fds open while loading the policy and transitioning */
log_close();
/* Now load the policy */
- before_load = now(CLOCK_MONOTONIC);
- r = selinux_init_load_policy(&enforce);
- if (r == 0) {
- _cleanup_freecon_ char *label = NULL;
-
+ usec_t before_load = now(CLOCK_MONOTONIC);
+ int enforce = 0;
+ if (selinux_init_load_policy(&enforce) == 0) { /* NB: Apparently doesn't set useful errno! */
mac_selinux_retest();
/* Transition to the new context */
+ _cleanup_freecon_ char *label = NULL;
r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
- if (r < 0 || !label) {
+ if (r < 0) {
log_open();
- log_error("Failed to compute init label, ignoring.");
+ log_warning_errno(r, "Failed to compute init label, ignoring: %m");
} else {
- r = setcon_raw(label);
-
+ r = RET_NERRNO(setcon_raw(label));
log_open();
if (r < 0)
- log_error("Failed to transition into init label '%s', ignoring.", label);
+ log_warning_errno(r, "Failed to transition into init label '%s', ignoring: %m", label);
+ else
+ log_debug("Successfully switched to calculated init label '%s'.", label);
}
- after_load = now(CLOCK_MONOTONIC);
-
+ usec_t after_load = now(CLOCK_MONOTONIC);
log_info("Successfully loaded SELinux policy in %s.",
FORMAT_TIMESPAN(after_load - before_load, 0));
*loaded_policy = true;
-
} else {
log_open();
LOG_MESSAGE("Failed to load SELinux policy :%m"),
LOG_MESSAGE_ID(SD_MESSAGE_SELINUX_FAILED_STR));
- log_warning("Failed to load new SELinux policy. Continuing with old policy.");
+ log_notice("Failed to load new SELinux policy. Continuing with old policy.");
} else
log_debug("Unable to load SELinux policy. Ignoring.");
}