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