diff options
Diffstat (limited to 'src/core/selinux-access.c')
-rw-r--r-- | src/core/selinux-access.c | 101 |
1 files changed, 46 insertions, 55 deletions
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index 40ca0c6166..3f3c5bf9fc 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -23,22 +23,25 @@ #ifdef HAVE_SELINUX -#include <stdio.h> #include <errno.h> -#include <selinux/selinux.h> #include <selinux/avc.h> +#include <selinux/selinux.h> +#include <stdio.h> #ifdef HAVE_AUDIT #include <libaudit.h> #endif #include "sd-bus.h" + +#include "alloc-util.h" +#include "audit-fd.h" #include "bus-util.h" -#include "util.h" #include "log.h" +#include "path-util.h" #include "selinux-util.h" -#include "audit-fd.h" +#include "stdio-util.h" #include "strv.h" -#include "path-util.h" +#include "util.h" static bool initialized = false; @@ -131,62 +134,44 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) { #endif va_start(ap, fmt); - log_internalv(LOG_AUTH | callback_type_to_priority(type), - 0, __FILE__, __LINE__, __FUNCTION__, fmt, ap); + log_internalv(LOG_AUTH | callback_type_to_priority(type), 0, __FILE__, __LINE__, __FUNCTION__, fmt, ap); 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 (security_getenforce() < 0){ - r = -errno; - avc_destroy(); - } - - return r; -} - -static int mac_selinux_access_init(sd_bus_error *error) { - int r; + if (!mac_selinux_use()) + return 0; if (initialized) - return 0; + return 1; - if (!mac_selinux_use()) - return 0; + if (avc_open(NULL, 0) != 0) { + int enforce, saved_errno = errno; - r = access_init(); - if (r < 0) - return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to initialize SELinux."); + enforce = security_getenforce(); + log_full_errno(enforce != 0 ? LOG_ERR : LOG_WARNING, saved_errno, "Failed to open the SELinux AVC: %m"); - initialized = true; - return 0; -} -#endif + /* 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; -void mac_selinux_access_free(void) { + /* 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)); + } -#ifdef HAVE_SELINUX - if (!initialized) - return; + selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback); + selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback); - avc_destroy(); - initialized = false; -#endif + initialized = true; + return 1; } /* @@ -201,8 +186,7 @@ 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; @@ -214,11 +198,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( @@ -285,7 +266,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 |