docs: Reword virDomainGetEmulatorPinInfo description
[libvirt.git] / tests / securityselinuxhelper.c
blobe5ded964851826b4a2b42bec13d94bc43f0a8ac0
1 /*
2 * Copyright (C) 2011-2013, 2016 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
20 #include <config.h>
22 /* This file is only compiled on Linux, and only if xattr support was
23 * detected. */
25 #include "virmock.h"
26 #include <linux/magic.h>
27 #include <selinux/selinux.h>
28 #include <selinux/label.h>
29 #include <sys/vfs.h>
30 #include <unistd.h>
31 #include <sys/xattr.h>
33 #ifndef NFS_SUPER_MAGIC
34 # define NFS_SUPER_MAGIC 0x6969
35 #endif
37 #define VIR_FROM_THIS VIR_FROM_NONE
39 #include "viralloc.h"
41 static int (*real_statfs)(const char *path, struct statfs *buf);
42 static int (*real_security_get_boolean_active)(const char *name);
43 static int (*real_is_selinux_enabled)(void);
45 static const char *(*real_selinux_virtual_domain_context_path)(void);
46 static const char *(*real_selinux_virtual_image_context_path)(void);
48 static const char *(*real_selinux_lxc_contexts_path)(void);
50 static struct selabel_handle *(*real_selabel_open)(unsigned int backend,
51 const struct selinux_opt *opts,
52 unsigned nopts);
53 static void (*real_selabel_close)(struct selabel_handle *handle);
54 static int (*real_selabel_lookup_raw)(struct selabel_handle *handle,
55 char **con,
56 const char *key,
57 int type);
59 static void init_syms(void)
61 if (real_statfs)
62 return;
64 VIR_MOCK_REAL_INIT(statfs);
65 VIR_MOCK_REAL_INIT(security_get_boolean_active);
66 VIR_MOCK_REAL_INIT(is_selinux_enabled);
68 VIR_MOCK_REAL_INIT(selinux_virtual_domain_context_path);
69 VIR_MOCK_REAL_INIT(selinux_virtual_image_context_path);
71 VIR_MOCK_REAL_INIT(selinux_lxc_contexts_path);
73 VIR_MOCK_REAL_INIT(selabel_open);
74 VIR_MOCK_REAL_INIT(selabel_close);
75 VIR_MOCK_REAL_INIT(selabel_lookup_raw);
80 * The kernel policy will not allow us to arbitrarily change
81 * test process context. This helper is used as an LD_PRELOAD
82 * so that the libvirt code /thinks/ it is changing/reading
83 * the process context, whereas in fact we're faking it all.
84 * Furthermore, we fake out that we are using an nfs subdirectory,
85 * where we control whether selinux is enforcing and whether
86 * the virt_use_nfs bool is set.
89 int getcon_raw(char **context)
91 if (!is_selinux_enabled()) {
92 errno = EINVAL;
93 return -1;
95 if (getenv("FAKE_SELINUX_CONTEXT") == NULL) {
96 *context = NULL;
97 errno = EINVAL;
98 return -1;
100 *context = g_strdup(getenv("FAKE_SELINUX_CONTEXT"));
101 return 0;
104 int getcon(char **context)
106 return getcon_raw(context);
109 int getpidcon_raw(pid_t pid, char **context)
111 if (!is_selinux_enabled()) {
112 errno = EINVAL;
113 return -1;
115 if (pid != getpid()) {
116 *context = NULL;
117 errno = ESRCH;
118 return -1;
120 if (getenv("FAKE_SELINUX_CONTEXT") == NULL) {
121 *context = NULL;
122 errno = EINVAL;
123 return -1;
125 *context = g_strdup(getenv("FAKE_SELINUX_CONTEXT"));
126 return 0;
129 int getpidcon(pid_t pid, char **context)
131 return getpidcon_raw(pid, context);
134 int setfilecon_raw(const char *path, const char *con)
136 const char *constr = con;
137 if (STRPREFIX(path, abs_builddir "/securityselinuxlabeldata/nfs/")) {
138 errno = EOPNOTSUPP;
139 return -1;
141 return setxattr(path, "user.libvirt.selinux",
142 constr, strlen(constr), 0);
145 int setfilecon(const char *path, const char *con)
147 return setfilecon_raw(path, con);
150 int getfilecon_raw(const char *path, char **con)
152 char *constr = NULL;
153 ssize_t len = getxattr(path, "user.libvirt.selinux",
154 NULL, 0);
155 if (STRPREFIX(path, abs_builddir "/securityselinuxlabeldata/nfs/")) {
156 errno = EOPNOTSUPP;
157 return -1;
159 if (len < 0)
160 return -1;
161 if (!(constr = malloc(len+1)))
162 return -1;
163 memset(constr, 0, len);
164 if (getxattr(path, "user.libvirt.selinux", constr, len) < 0) {
165 free(constr);
166 return -1;
168 *con = constr;
169 constr[len] = '\0';
170 return 0;
174 int getfilecon(const char *path, char **con)
176 return getfilecon_raw(path, con);
180 int statfs(const char *path, struct statfs *buf)
182 int ret;
184 init_syms();
186 ret = real_statfs(path, buf);
187 if (!ret && STREQ(path, abs_builddir "/securityselinuxlabeldata/nfs"))
188 buf->f_type = NFS_SUPER_MAGIC;
189 return ret;
192 int is_selinux_enabled(void)
194 return getenv("FAKE_SELINUX_DISABLED") == NULL;
197 int security_getenforce(void)
199 if (!is_selinux_enabled()) {
200 errno = ENOENT;
201 return -1;
204 /* For the purpose of our test, we are enforcing. */
205 return 1;
209 int security_get_boolean_active(const char *name)
211 if (!is_selinux_enabled()) {
212 errno = ENOENT;
213 return -1;
216 /* For the purpose of our test, nfs is not permitted. */
217 if (STREQ(name, "virt_use_nfs"))
218 return 0;
220 init_syms();
221 return real_security_get_boolean_active(name);
224 const char *selinux_virtual_domain_context_path(void)
226 init_syms();
228 if (real_is_selinux_enabled())
229 return real_selinux_virtual_domain_context_path();
231 return abs_srcdir "/securityselinuxhelperdata/virtual_domain_context";
234 const char *selinux_virtual_image_context_path(void)
236 init_syms();
238 if (real_is_selinux_enabled())
239 return real_selinux_virtual_image_context_path();
241 return abs_srcdir "/securityselinuxhelperdata/virtual_image_context";
244 const char *selinux_lxc_contexts_path(void)
246 init_syms();
248 if (real_is_selinux_enabled())
249 return real_selinux_lxc_contexts_path();
251 return abs_srcdir "/securityselinuxhelperdata/lxc_contexts";
254 struct selabel_handle *
255 selabel_open(unsigned int backend,
256 const struct selinux_opt *opts,
257 unsigned nopts)
259 char *fake_handle;
261 init_syms();
263 if (real_is_selinux_enabled())
264 return real_selabel_open(backend, opts, nopts);
266 /* struct selabel_handle is opaque; fake it */
267 fake_handle = g_new0(char, 1);
268 return (struct selabel_handle *)fake_handle;
271 void selabel_close(struct selabel_handle *handle)
273 init_syms();
275 if (real_is_selinux_enabled())
276 return real_selabel_close(handle);
278 VIR_FREE(handle);
281 int selabel_lookup_raw(struct selabel_handle *handle,
282 char **con,
283 const char *key,
284 int type)
286 init_syms();
288 if (real_is_selinux_enabled())
289 return real_selabel_lookup_raw(handle, con, key, type);
291 /* Unimplemented */
292 errno = ENOENT;
293 return -1;