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/>.
22 /* This file is only compiled on Linux, and only if xattr support was
26 #include <linux/magic.h>
27 #include <selinux/selinux.h>
28 #include <selinux/label.h>
31 #include <sys/xattr.h>
33 #ifndef NFS_SUPER_MAGIC
34 # define NFS_SUPER_MAGIC 0x6969
37 #define VIR_FROM_THIS VIR_FROM_NONE
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
,
53 static void (*real_selabel_close
)(struct selabel_handle
*handle
);
54 static int (*real_selabel_lookup_raw
)(struct selabel_handle
*handle
,
59 static void init_syms(void)
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()) {
95 if (getenv("FAKE_SELINUX_CONTEXT") == NULL
) {
100 *context
= g_strdup(getenv("FAKE_SELINUX_CONTEXT"));
104 int getcon(char **context
)
106 return getcon_raw(context
);
109 int getpidcon_raw(pid_t pid
, char **context
)
111 if (!is_selinux_enabled()) {
115 if (pid
!= getpid()) {
120 if (getenv("FAKE_SELINUX_CONTEXT") == NULL
) {
125 *context
= g_strdup(getenv("FAKE_SELINUX_CONTEXT"));
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/")) {
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
)
153 ssize_t len
= getxattr(path
, "user.libvirt.selinux",
155 if (STRPREFIX(path
, abs_builddir
"/securityselinuxlabeldata/nfs/")) {
161 if (!(constr
= malloc(len
+1)))
163 memset(constr
, 0, len
);
164 if (getxattr(path
, "user.libvirt.selinux", constr
, len
) < 0) {
174 int getfilecon(const char *path
, char **con
)
176 return getfilecon_raw(path
, con
);
180 int statfs(const char *path
, struct statfs
*buf
)
186 ret
= real_statfs(path
, buf
);
187 if (!ret
&& STREQ(path
, abs_builddir
"/securityselinuxlabeldata/nfs"))
188 buf
->f_type
= NFS_SUPER_MAGIC
;
192 int is_selinux_enabled(void)
194 return getenv("FAKE_SELINUX_DISABLED") == NULL
;
197 int security_getenforce(void)
199 if (!is_selinux_enabled()) {
204 /* For the purpose of our test, we are enforcing. */
209 int security_get_boolean_active(const char *name
)
211 if (!is_selinux_enabled()) {
216 /* For the purpose of our test, nfs is not permitted. */
217 if (STREQ(name
, "virt_use_nfs"))
221 return real_security_get_boolean_active(name
);
224 const char *selinux_virtual_domain_context_path(void)
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)
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)
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
,
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
)
275 if (real_is_selinux_enabled())
276 return real_selabel_close(handle
);
281 int selabel_lookup_raw(struct selabel_handle
*handle
,
288 if (real_is_selinux_enabled())
289 return real_selabel_lookup_raw(handle
, con
, key
, type
);