Branch data Line data Source code
1 : : /* 2 : : * dpkg - main program for package management 3 : : * selinux.c - SELinux support 4 : : * 5 : : * Copyright © 2007-2015 Guillem Jover <guillem@debian.org> 6 : : * 7 : : * This is free software; you can redistribute it and/or modify 8 : : * it under the terms of the GNU General Public License as published by 9 : : * the Free Software Foundation; either version 2 of the License, or 10 : : * (at your option) any later version. 11 : : * 12 : : * This is distributed in the hope that it will be useful, 13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : : * GNU General Public License for more details. 16 : : * 17 : : * You should have received a copy of the GNU General Public License 18 : : * along with this program. If not, see <https://www.gnu.org/licenses/>. 19 : : */ 20 : : 21 : : #include <config.h> 22 : : #include <compat.h> 23 : : 24 : : #include <sys/types.h> 25 : : #include <sys/stat.h> 26 : : 27 : : #include <errno.h> 28 : : #include <unistd.h> 29 : : 30 : : #include <dpkg/i18n.h> 31 : : #include <dpkg/dpkg.h> 32 : : #include <dpkg/dpkg-db.h> 33 : : 34 : : #ifdef WITH_LIBSELINUX 35 : : #include <selinux/selinux.h> 36 : : #include <selinux/avc.h> 37 : : #include <selinux/label.h> 38 : : #endif 39 : : 40 : : #include "force.h" 41 : : #include "security-mac.h" 42 : : 43 : : #ifdef WITH_LIBSELINUX 44 : : static struct selabel_handle *sehandle; 45 : : #endif 46 : : 47 : : #ifdef WITH_LIBSELINUX 48 : : static int DPKG_ATTR_PRINTF(2) 49 : 0 : log_callback(int type, const char *fmt, ...) 50 : : { 51 : : va_list ap; 52 : : char *msg; 53 : : 54 [ # # ]: 0 : switch (type) { 55 : 0 : case SELINUX_ERROR: 56 : : case SELINUX_WARNING: 57 : : case SELINUX_AVC: 58 : 0 : break; 59 : 0 : default: 60 : 0 : return 0; 61 : : } 62 : : 63 : 0 : va_start(ap, fmt); 64 : 0 : m_vasprintf(&msg, fmt, ap); 65 : 0 : va_end(ap); 66 : : 67 : 0 : warning("selinux: %s", msg); 68 : 0 : free(msg); 69 : : 70 : 0 : return 0; 71 : : } 72 : : #endif 73 : : 74 : : void 75 : 0 : dpkg_selabel_load(void) 76 : : { 77 : : #ifdef WITH_LIBSELINUX 78 : : static int selinux_enabled = -1; 79 : : 80 [ # # ]: 0 : if (selinux_enabled < 0) { 81 : : int rc; 82 : : 83 : : /* Set selinux_enabled if it is not already set (singleton). */ 84 [ # # # # ]: 0 : selinux_enabled = (in_force(FORCE_SECURITY_MAC) && 85 : 0 : is_selinux_enabled() > 0); 86 [ # # ]: 0 : if (!selinux_enabled) 87 : 0 : return; 88 : : 89 : : /* Open the SELinux status notification channel, with fallback 90 : : * enabled for older kernels. */ 91 : 0 : rc = selinux_status_open(1); 92 [ # # ]: 0 : if (rc < 0) 93 : 0 : ohshit(_("cannot open security status notification channel")); 94 : : 95 : 0 : selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) { 96 : : .func_log = log_callback, 97 : : }); 98 [ # # # # ]: 0 : } else if (selinux_enabled && selinux_status_updated()) { 99 : : /* The SELinux policy got updated in the kernel, usually after 100 : : * upgrading the package shipping it, we need to reload. */ 101 : 0 : selabel_close(sehandle); 102 : : } else { 103 : : /* SELinux is either disabled or it does not need a reload. */ 104 : 0 : return; 105 : : } 106 : : 107 : 0 : sehandle = selabel_open(SELABEL_CTX_FILE, NULL, 0); 108 [ # # # # ]: 0 : if (sehandle == NULL && security_getenforce() == 1) 109 : 0 : ohshite(_("cannot get security labeling handle")); 110 : : #endif 111 : : } 112 : : 113 : : void 114 : 0 : dpkg_selabel_set_context(const char *matchpath, const char *path, mode_t mode) 115 : : { 116 : : #ifdef WITH_LIBSELINUX 117 : 0 : char *scontext = NULL; 118 : : int ret; 119 : : 120 : : /* If SELinux is not enabled just do nothing. */ 121 [ # # ]: 0 : if (sehandle == NULL) 122 : 0 : return; 123 : : 124 : : /* 125 : : * We use the _raw function variants here so that no translation 126 : : * happens from computer to human readable forms, to avoid issues 127 : : * when mcstransd has disappeared during the unpack process. 128 : : */ 129 : : 130 : : /* Do nothing if we can't figure out what the context is, or if it has 131 : : * no context; in which case the default context shall be applied. */ 132 : 0 : ret = selabel_lookup_raw(sehandle, &scontext, matchpath, mode & S_IFMT); 133 [ # # # # : 0 : if (ret == -1 || (ret == 0 && scontext == NULL)) # # ] 134 : 0 : return; 135 : : 136 : 0 : ret = lsetfilecon_raw(path, scontext); 137 [ # # # # ]: 0 : if (ret < 0 && errno != ENOTSUP) 138 : 0 : ohshite(_("cannot set security context for file object '%s'"), 139 : : path); 140 : : 141 : 0 : freecon(scontext); 142 : : #endif /* WITH_LIBSELINUX */ 143 : : } 144 : : 145 : : void 146 : 0 : dpkg_selabel_close(void) 147 : : { 148 : : #ifdef WITH_LIBSELINUX 149 [ # # ]: 0 : if (sehandle == NULL) 150 : 0 : return; 151 : : 152 : 0 : selinux_status_close(); 153 : 0 : selabel_close(sehandle); 154 : 0 : sehandle = NULL; 155 : : #endif 156 : : }