github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/cmd/snap-confine/selinux-support.c (about) 1 /* 2 * Copyright (C) 2018 Canonical Ltd 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 3 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * 16 */ 17 #include "selinux-support.h" 18 #include "config.h" 19 20 #include <selinux/context.h> 21 #include <selinux/selinux.h> 22 23 #include "../libsnap-confine-private/cleanup-funcs.h" 24 #include "../libsnap-confine-private/string-utils.h" 25 #include "../libsnap-confine-private/utils.h" 26 27 static void sc_freecon(char **ctx) { 28 if (ctx != NULL && *ctx != NULL) { 29 freecon(*ctx); 30 *ctx = NULL; 31 } 32 } 33 34 static void sc_context_free(context_t *ctx) { 35 if (ctx != NULL && *ctx != NULL) { 36 context_free(*ctx); 37 *ctx = NULL; 38 } 39 } 40 41 /** 42 * Set security context for the snap. 43 * 44 * Sets up SELinux context transition to unconfined_service_t. 45 **/ 46 int sc_selinux_set_snap_execcon(void) { 47 if (is_selinux_enabled() < 1) { 48 debug("SELinux not enabled"); 49 return 0; 50 } 51 52 char *ctx_str SC_CLEANUP(sc_freecon) = NULL; 53 if (getcon(&ctx_str) < 0) { 54 die("cannot obtain current SELinux process context"); 55 } 56 debug("current SELinux process context: %s", ctx_str); 57 58 context_t ctx SC_CLEANUP(sc_context_free) = context_new(ctx_str); 59 if (ctx == NULL) { 60 die("cannot create SELinux context from context string %s", ctx_str); 61 } 62 63 /* freed by context_free(ctx) */ 64 const char *ctx_type = context_type_get(ctx); 65 66 if (ctx_type == NULL) { 67 die("cannot obtain type from SELinux context string %s", ctx_str); 68 } 69 70 if (sc_streq(ctx_type, "snappy_confine_t")) { 71 /* We are running under a targeted policy which ended up transitioning 72 * to snappy_confine_t domain, at this point we are right before 73 * executing snap-exec. However we do not have a full SELinux support 74 * for services running in snaps, only the snapd bits and helpers are 75 * covered by the policy. 76 * 77 * At this point transition to the unconfined_service_t domain (allowed 78 * by snap_confine_t policy) upon the next exec() call. 79 */ 80 if (context_type_set(ctx, "unconfined_service_t") != 0) { 81 die("cannot update SELinux context %s type to unconfined_service_t", ctx_str); 82 } 83 84 /* freed by context_free(ctx) */ 85 char *new_ctx_str = context_str(ctx); 86 if (new_ctx_str == NULL) { 87 die("cannot obtain updated SELinux context string"); 88 } 89 if (setexeccon(new_ctx_str) < 0) { 90 die("cannot set SELinux exec context to %s", new_ctx_str); 91 } 92 debug("SELinux context after next exec: %s", new_ctx_str); 93 } 94 95 return 0; 96 }