2 * Copyright (C) 2011-2013 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/>.
25 #include <selinux/selinux.h>
26 #include <selinux/context.h>
29 #include "testutils.h"
34 #include "security/security_manager.h"
35 #include "virstring.h"
37 #define VIR_FROM_THIS VIR_FROM_NONE
39 VIR_LOG_INIT("tests.securityselinuxtest");
41 struct testSELinuxGenLabelData
{
42 virSecurityManagerPtr mgr
;
48 const char *baselabel
;
52 const char *imagerole
;
54 const char *imagetype
;
62 static virDomainDefPtr
63 testBuildDomainDef(bool dynamic
,
65 const char *baselabel
)
68 virSecurityLabelDefPtr secdef
= NULL
;
70 if (!(def
= virDomainDefNew()))
73 def
->virtType
= VIR_DOMAIN_VIRT_KVM
;
74 if (VIR_ALLOC_N(def
->seclabels
, 1) < 0)
77 if (VIR_ALLOC(secdef
) < 0)
80 if (VIR_STRDUP(secdef
->model
, "selinux") < 0)
83 secdef
->type
= dynamic
? VIR_DOMAIN_SECLABEL_DYNAMIC
: VIR_DOMAIN_SECLABEL_STATIC
;
85 VIR_STRDUP(secdef
->label
, label
) < 0)
89 VIR_STRDUP(secdef
->baselabel
, baselabel
) < 0)
92 def
->seclabels
[0] = secdef
;
97 virDomainDefFree(def
);
98 virSecurityLabelDefFree(secdef
);
104 testSELinuxCheckCon(context_t con
,
109 int sensMax ATTRIBUTE_UNUSED
,
119 if (STRNEQ(context_user_get(con
), user
)) {
120 fprintf(stderr
, "Expect user %s got %s\n",
121 user
, context_user_get(con
));
124 if (STRNEQ(context_role_get(con
), role
)) {
125 fprintf(stderr
, "Expect role %s got %s\n",
126 role
, context_role_get(con
));
129 if (STRNEQ(context_type_get(con
), type
)) {
130 fprintf(stderr
, "Expect type %s got %s\n",
131 type
, context_type_get(con
));
135 range
= context_range_get(con
);
136 if (range
[0] != 's') {
137 fprintf(stderr
, "Malformed range %s, cannot find sensitivity\n",
141 if (virStrToLong_i(range
+ 1, &tmp
, 10, &gotSens
) < 0 ||
143 fprintf(stderr
, "Malformed range %s, cannot parse sensitivity\n",
148 fprintf(stderr
, "Malformed range %s, too many sensitivity values\n",
154 fprintf(stderr
, "Malformed range %s, cannot find first category\n",
159 if (virStrToLong_i(tmp
, &tmp
, 10, &gotCatOne
) < 0) {
160 fprintf(stderr
, "Malformed range %s, cannot parse category one\n",
164 if (tmp
&& *tmp
== ',')
166 if (tmp
&& *tmp
== 'c') {
168 if (virStrToLong_i(tmp
, &tmp
, 10, &gotCatTwo
) < 0) {
169 fprintf(stderr
, "Malformed range %s, cannot parse category two\n",
174 fprintf(stderr
, "Malformed range %s, junk after second category\n",
178 if (gotCatOne
== gotCatTwo
) {
179 fprintf(stderr
, "Saw category pair %d,%d where cats were equal\n",
180 gotCatOne
, gotCatTwo
);
184 gotCatTwo
= gotCatOne
;
187 if (gotSens
!= sensMin
) {
188 fprintf(stderr
, "Sensitivity %d is not equal to min %d\n",
192 if (gotCatOne
< catMin
||
193 gotCatOne
> catMax
) {
194 fprintf(stderr
, "Category one %d is out of range %d-%d\n",
195 gotCatTwo
, catMin
, catMax
);
198 if (gotCatTwo
< catMin
||
199 gotCatTwo
> catMax
) {
200 fprintf(stderr
, "Category two %d is out of range %d-%d\n",
201 gotCatTwo
, catMin
, catMax
);
205 if (gotCatOne
> gotCatTwo
) {
206 fprintf(stderr
, "Category one %d is greater than category two %d\n",
207 gotCatOne
, gotCatTwo
);
215 testSELinuxGenLabel(const void *opaque
)
217 const struct testSELinuxGenLabelData
*data
= opaque
;
220 context_t con
= NULL
;
221 context_t imgcon
= NULL
;
223 if (setcon_raw((security_context_t
)data
->pidcon
) < 0) {
224 perror("Cannot set process security context");
228 if (!(def
= testBuildDomainDef(data
->dynamic
,
233 if (virSecurityManagerGenLabel(data
->mgr
, def
) < 0) {
234 fprintf(stderr
, "Cannot generate label: %s\n", virGetLastErrorMessage());
238 VIR_DEBUG("label=%s imagelabel=%s",
239 def
->seclabels
[0]->label
, def
->seclabels
[0]->imagelabel
);
241 if (!(con
= context_new(def
->seclabels
[0]->label
)))
243 if (!(imgcon
= context_new(def
->seclabels
[0]->imagelabel
)))
246 if (!testSELinuxCheckCon(con
,
247 data
->user
, data
->role
, data
->type
,
248 data
->sensMin
, data
->sensMax
,
249 data
->catMin
, data
->catMax
))
252 if (!testSELinuxCheckCon(imgcon
,
253 data
->user
, data
->imagerole
, data
->imagetype
,
254 data
->sensMin
, data
->sensMax
,
255 data
->catMin
, data
->catMax
))
262 context_free(imgcon
);
263 virDomainDefFree(def
);
273 virSecurityManagerPtr mgr
;
275 if (!(mgr
= virSecurityManagerNew("selinux", "QEMU",
276 VIR_SECURITY_MANAGER_DEFAULT_CONFINED
|
277 VIR_SECURITY_MANAGER_PRIVILEGED
))) {
278 fprintf(stderr
, "Unable to initialize security driver: %s\n",
279 virGetLastErrorMessage());
283 #define DO_TEST_GEN_LABEL(desc, pidcon, \
284 dynamic, label, baselabel, \
285 user, role, imageRole, \
287 sensMin, sensMax, catMin, catMax) \
289 struct testSELinuxGenLabelData data = { \
290 mgr, pidcon, dynamic, label, baselabel, \
291 user, role, imageRole, type, imageType, \
292 sensMin, sensMax, catMin, catMax \
294 if (virTestRun("GenLabel " # desc, testSELinuxGenLabel, &data) < 0) \
298 DO_TEST_GEN_LABEL("dynamic unconfined, s0, c0.c1023",
299 "unconfined_u:unconfined_r:unconfined_t:s0",
301 "unconfined_u", "unconfined_r", "object_r",
302 "svirt_t", "svirt_image_t",
304 DO_TEST_GEN_LABEL("dynamic unconfined, s0, c0.c1023",
305 "unconfined_u:unconfined_r:unconfined_t:s0-s0",
307 "unconfined_u", "unconfined_r", "object_r",
308 "svirt_t", "svirt_image_t",
310 DO_TEST_GEN_LABEL("dynamic unconfined, s0, c0.c1023",
311 "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023",
313 "unconfined_u", "unconfined_r", "object_r",
314 "svirt_t", "svirt_image_t",
316 DO_TEST_GEN_LABEL("dynamic virtd, s0, c0.c1023",
317 "system_u:system_r:virtd_t:s0-s0:c0.c1023",
319 "system_u", "system_r", "object_r",
320 "svirt_t", "svirt_image_t",
322 DO_TEST_GEN_LABEL("dynamic virtd, s0, c0.c10",
323 "system_u:system_r:virtd_t:s0-s0:c0.c10",
325 "system_u", "system_r", "object_r",
326 "svirt_t", "svirt_image_t",
328 DO_TEST_GEN_LABEL("dynamic virtd, s2-s3, c0.c1023",
329 "system_u:system_r:virtd_t:s2-s3:c0.c1023",
331 "system_u", "system_r", "object_r",
332 "svirt_t", "svirt_image_t",
334 DO_TEST_GEN_LABEL("dynamic virtd, missing range",
335 "system_u:system_r:virtd_t",
337 "system_u", "system_r", "object_r",
338 "svirt_t", "svirt_image_t",
342 return (ret
== 0) ? EXIT_SUCCESS
: EXIT_FAILURE
;
345 VIR_TEST_MAIN_PRELOAD(mymain
, abs_builddir
"/.libs/libsecurityselinuxhelper.so")