]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/selinux-setup.c
tree-wide: drop 'This file is part of systemd' blurb
[thirdparty/systemd.git] / src / core / selinux-setup.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright 2010 Lennart Poettering
4 ***/
5
6 #include <errno.h>
7 #include <stdio.h>
8 #include <unistd.h>
9
10 #if HAVE_SELINUX
11 #include <selinux/selinux.h>
12 #endif
13
14 #include "log.h"
15 #include "macro.h"
16 #include "selinux-setup.h"
17 #include "selinux-util.h"
18 #include "string-util.h"
19 #include "util.h"
20
21 #if HAVE_SELINUX
22 _printf_(2,3)
23 static int null_log(int type, const char *fmt, ...) {
24 return 0;
25 }
26 #endif
27
28 int mac_selinux_setup(bool *loaded_policy) {
29
30 #if HAVE_SELINUX
31 int enforce = 0;
32 usec_t before_load, after_load;
33 char *con;
34 int r;
35 static const union selinux_callback cb = {
36 .func_log = null_log,
37 };
38
39 bool initialized = false;
40
41 assert(loaded_policy);
42
43 /* Turn off all of SELinux' own logging, we want to do that */
44 selinux_set_callback(SELINUX_CB_LOG, cb);
45
46 /* Don't load policy in the initrd if we don't appear to have
47 * it. For the real root, we check below if we've already
48 * loaded policy, and return gracefully.
49 */
50 if (in_initrd() && access(selinux_path(), F_OK) < 0)
51 return 0;
52
53 /* Already initialized by somebody else? */
54 r = getcon_raw(&con);
55 if (r == 0) {
56 initialized = !streq(con, "kernel");
57 freecon(con);
58 }
59
60 /* Make sure we have no fds open while loading the policy and
61 * transitioning */
62 log_close();
63
64 /* Now load the policy */
65 before_load = now(CLOCK_MONOTONIC);
66 r = selinux_init_load_policy(&enforce);
67 if (r == 0) {
68 _cleanup_(mac_selinux_freep) char *label = NULL;
69 char timespan[FORMAT_TIMESPAN_MAX];
70
71 mac_selinux_retest();
72
73 /* Transition to the new context */
74 r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
75 if (r < 0 || !label) {
76 log_open();
77 log_error("Failed to compute init label, ignoring.");
78 } else {
79 r = setcon_raw(label);
80
81 log_open();
82 if (r < 0)
83 log_error("Failed to transition into init label '%s', ignoring.", label);
84 }
85
86 after_load = now(CLOCK_MONOTONIC);
87
88 log_info("Successfully loaded SELinux policy in %s.",
89 format_timespan(timespan, sizeof(timespan), after_load - before_load, 0));
90
91 *loaded_policy = true;
92
93 } else {
94 log_open();
95
96 if (enforce > 0) {
97 if (!initialized) {
98 log_emergency("Failed to load SELinux policy.");
99 return -EIO;
100 }
101
102 log_warning("Failed to load new SELinux policy. Continuing with old policy.");
103 } else
104 log_debug("Unable to load SELinux policy. Ignoring.");
105 }
106 #endif
107
108 return 0;
109 }