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