]> git.proxmox.com Git - systemd.git/blob - src/core/selinux-setup.c
Merge tag 'upstream/229'
[systemd.git] / src / core / selinux-setup.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <stdio.h>
22 #include <unistd.h>
23
24 #ifdef HAVE_SELINUX
25 #include <selinux/selinux.h>
26 #endif
27
28 #include "log.h"
29 #include "macro.h"
30 #include "selinux-setup.h"
31 #include "selinux-util.h"
32 #include "string-util.h"
33 #include "util.h"
34
35 #ifdef HAVE_SELINUX
36 _printf_(2,3)
37 static int null_log(int type, const char *fmt, ...) {
38 return 0;
39 }
40 #endif
41
42 int mac_selinux_setup(bool *loaded_policy) {
43
44 #ifdef HAVE_SELINUX
45 int enforce = 0;
46 usec_t before_load, after_load;
47 security_context_t con;
48 int r;
49 union selinux_callback cb;
50 bool initialized = false;
51
52 assert(loaded_policy);
53
54 /* Turn off all of SELinux' own logging, we want to do that */
55 cb.func_log = null_log;
56 selinux_set_callback(SELINUX_CB_LOG, cb);
57
58 /* Don't load policy in the initrd if we don't appear to have
59 * it. For the real root, we check below if we've already
60 * loaded policy, and return gracefully.
61 */
62 if (in_initrd() && access(selinux_path(), F_OK) < 0)
63 return 0;
64
65 /* Already initialized by somebody else? */
66 r = getcon_raw(&con);
67 if (r == 0) {
68 initialized = !streq(con, "kernel");
69 freecon(con);
70 }
71
72 /* Make sure we have no fds open while loading the policy and
73 * transitioning */
74 log_close();
75
76 /* Now load the policy */
77 before_load = now(CLOCK_MONOTONIC);
78 r = selinux_init_load_policy(&enforce);
79 if (r == 0) {
80 _cleanup_(mac_selinux_freep) char *label = NULL;
81 char timespan[FORMAT_TIMESPAN_MAX];
82
83 mac_selinux_retest();
84
85 /* Transition to the new context */
86 r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
87 if (r < 0 || !label) {
88 log_open();
89 log_error("Failed to compute init label, ignoring.");
90 } else {
91 r = setcon(label);
92
93 log_open();
94 if (r < 0)
95 log_error("Failed to transition into init label '%s', ignoring.", label);
96 }
97
98 after_load = now(CLOCK_MONOTONIC);
99
100 log_info("Successfully loaded SELinux policy in %s.",
101 format_timespan(timespan, sizeof(timespan), after_load - before_load, 0));
102
103 *loaded_policy = true;
104
105 } else {
106 log_open();
107
108 if (enforce > 0) {
109 if (!initialized) {
110 log_emergency("Failed to load SELinux policy.");
111 return -EIO;
112 }
113
114 log_warning("Failed to load new SELinux policy. Continuing with old policy.");
115 } else
116 log_debug("Unable to load SELinux policy. Ignoring.");
117 }
118 #endif
119
120 return 0;
121 }