X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fcore%2Fselinux-access.c;h=c8b1a8588b1c999187cbbee22252f47eeb20e87f;hb=ca78ad1de987b800978622a22ac6c5caf628a037;hp=8856927c88f62664bc4f34eb3ccda60a4dd8a3f5;hpb=92939fc4c0261dccd4b755186aba84a9b1412bed;p=thirdparty%2Fsystemd.git
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c
index 8856927c88f..c8b1a8588b1 100644
--- a/src/core/selinux-access.c
+++ b/src/core/selinux-access.c
@@ -1,33 +1,14 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Dan Walsh
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see .
-***/
+/* SPDX-License-Identifier: LGPL-2.1+ */
#include "selinux-access.h"
-#ifdef HAVE_SELINUX
+#if HAVE_SELINUX
#include
#include
#include
#include
-#ifdef HAVE_AUDIT
+#if HAVE_AUDIT
#include
#endif
@@ -36,6 +17,7 @@
#include "alloc-util.h"
#include "audit-fd.h"
#include "bus-util.h"
+#include "format-util.h"
#include "log.h"
#include "path-util.h"
#include "selinux-util.h"
@@ -112,8 +94,9 @@ static int callback_type_to_priority(int type) {
*/
_printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
va_list ap;
+ const char *fmt2;
-#ifdef HAVE_AUDIT
+#if HAVE_AUDIT
int fd;
fd = get_audit_fd();
@@ -127,59 +110,63 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
va_end(ap);
if (r >= 0) {
- audit_log_user_avc_message(fd, AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
+ if (type == SELINUX_AVC)
+ audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
+ else if (type == SELINUX_ERROR)
+ audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_SELINUX_ERR, buf, NULL, NULL, NULL, 0);
+
return 0;
}
}
#endif
+ fmt2 = strjoina("selinux: ", fmt);
+
va_start(ap, fmt);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
log_internalv(LOG_AUTH | callback_type_to_priority(type),
- 0, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
+ 0, __FILE__, __LINE__, __FUNCTION__,
+ fmt2, ap);
+#pragma GCC diagnostic pop
va_end(ap);
return 0;
}
-/*
- Function must be called once to initialize the SELinux AVC environment.
- Sets up callbacks.
- If you want to cleanup memory you should need to call selinux_access_finish.
-*/
-static int access_init(void) {
- int r = 0;
-
- if (avc_open(NULL, 0))
- return log_error_errno(errno, "avc_open() failed: %m");
+static int access_init(sd_bus_error *error) {
- selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback);
- selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback);
+ if (!mac_selinux_use())
+ return 0;
- if (security_getenforce() < 0){
- r = -errno;
- avc_destroy();
- }
+ if (initialized)
+ return 1;
- return r;
-}
+ if (avc_open(NULL, 0) != 0) {
+ int enforce, saved_errno = errno;
-static int mac_selinux_access_init(sd_bus_error *error) {
- int r;
+ enforce = security_getenforce();
+ log_full_errno(enforce != 0 ? LOG_ERR : LOG_WARNING, saved_errno, "Failed to open the SELinux AVC: %m");
- if (initialized)
- return 0;
+ /* If enforcement isn't on, then let's suppress this
+ * error, and just don't do any AVC checks. The
+ * warning we printed is hence all the admin will
+ * see. */
+ if (enforce == 0)
+ return 0;
- if (!mac_selinux_use())
- return 0;
+ /* Return an access denied error, if we couldn't load
+ * the AVC but enforcing mode was on, or we couldn't
+ * determine whether it is one. */
+ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to open the SELinux AVC: %s", strerror(saved_errno));
+ }
- r = access_init();
- if (r < 0)
- return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to initialize SELinux.");
+ selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback);
+ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback);
initialized = true;
- return 0;
+ return 1;
}
-#endif
/*
This function communicates with the kernel to check whether or not it should
@@ -193,12 +180,11 @@ int mac_selinux_generic_access_check(
const char *permission,
sd_bus_error *error) {
-#ifdef HAVE_SELINUX
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+ _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
const char *tclass = NULL, *scon = NULL;
struct audit_info audit_info = {};
_cleanup_free_ char *cl = NULL;
- security_context_t fcon = NULL;
+ char *fcon = NULL;
char **cmdline = NULL;
int r = 0;
@@ -206,11 +192,8 @@ int mac_selinux_generic_access_check(
assert(permission);
assert(error);
- if (!mac_selinux_use())
- return 0;
-
- r = mac_selinux_access_init(error);
- if (r < 0)
+ r = access_init(error);
+ if (r <= 0)
return r;
r = sd_bus_query_sender_creds(
@@ -277,7 +260,17 @@ finish:
}
return r;
+}
+
#else
+
+int mac_selinux_generic_access_check(
+ sd_bus_message *message,
+ const char *path,
+ const char *permission,
+ sd_bus_error *error) {
+
return 0;
-#endif
}
+
+#endif