2
* Copyright (C) 2008-2011 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.
10
* James Morris <jmorris@namei.org>
11
* Dan Walsh <dwalsh@redhat.com>
13
* SELinux security driver.
16
#include <selinux/selinux.h>
17
#include <selinux/context.h>
18
#include <sys/types.h>
21
#if HAVE_SELINUX_LABEL_H
22
# include <selinux/label.h>
25
#include "security_driver.h"
26
#include "security_selinux.h"
27
#include "virterror_internal.h"
33
#include "storage_file.h"
36
#define VIR_FROM_THIS VIR_FROM_SECURITY
38
static char default_domain_context[1024];
39
static char default_content_context[1024];
40
static char default_image_context[1024];
41
#define SECURITY_SELINUX_VOID_DOI "0"
42
#define SECURITY_SELINUX_NAME "selinux"
45
The data struct of used mcs should be replaced with a better data structure in the future
52
static struct MCS *mcsList = NULL;
55
mcsAdd(const char *mcs)
59
for (ptr = mcsList; ptr; ptr = ptr->next) {
60
if (STREQ(ptr->mcs, mcs))
63
if (VIR_ALLOC(ptr) < 0)
65
ptr->mcs = strdup(mcs);
72
mcsRemove(const char *mcs)
74
struct MCS *prevptr = NULL;
75
struct MCS *ptr = NULL;
77
for (ptr = mcsList; ptr; ptr = ptr->next) {
78
if (STREQ(ptr->mcs, mcs)) {
80
prevptr->next = ptr->next;
94
SELinuxGenNewContext(const char *oldcontext, const char *mcs)
96
char *newcontext = NULL;
97
char *scontext = strdup(oldcontext);
99
if (!scontext) goto err;
100
con = context_new(scontext);
102
context_range_set(con, mcs);
103
newcontext = strdup(context_str(con));
111
SELinuxInitialize(void)
116
fd = open(selinux_virtual_domain_context_path(), O_RDONLY);
118
virReportSystemError(errno,
119
_("cannot open SELinux virtual domain context file '%s'"),
120
selinux_virtual_domain_context_path());
124
if (saferead(fd, default_domain_context, sizeof(default_domain_context)) < 0) {
125
virReportSystemError(errno,
126
_("cannot read SELinux virtual domain context file %s"),
127
selinux_virtual_domain_context_path());
133
ptr = strchrnul(default_domain_context, '\n');
136
if ((fd = open(selinux_virtual_image_context_path(), O_RDONLY)) < 0) {
137
virReportSystemError(errno,
138
_("cannot open SELinux virtual image context file %s"),
139
selinux_virtual_image_context_path());
143
if (saferead(fd, default_image_context, sizeof(default_image_context)) < 0) {
144
virReportSystemError(errno,
145
_("cannot read SELinux virtual image context file %s"),
146
selinux_virtual_image_context_path());
152
ptr = strchrnul(default_image_context, '\n');
155
strcpy(default_content_context, ptr+1);
156
ptr = strchrnul(default_content_context, '\n');
164
SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
169
char *scontext = NULL;
172
context_t ctx = NULL;
174
if ((vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) &&
175
!vm->def->seclabel.baselabel &&
176
vm->def->seclabel.model) {
177
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
178
"%s", _("security model already defined for VM"));
182
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
183
vm->def->seclabel.label) {
184
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
185
"%s", _("security label already defined for VM"));
189
if (vm->def->seclabel.imagelabel) {
190
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
191
"%s", _("security image label already defined for VM"));
195
if (vm->def->seclabel.model &&
196
STRNEQ(vm->def->seclabel.model, SECURITY_SELINUX_NAME)) {
197
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
198
_("security label model %s is not supported with selinux"),
199
vm->def->seclabel.model);
203
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC) {
204
if (!(ctx = context_new(vm->def->seclabel.label)) ) {
205
virReportSystemError(errno,
206
_("unable to allocate socket security context '%s'"),
207
vm->def->seclabel.label);
211
const char *range = context_range_get(ctx);
213
!(mcs = strdup(range))) {
219
c1 = virRandom(1024);
220
c2 = virRandom(1024);
223
if (virAsprintf(&mcs, "s0:c%d", c1) < 0) {
233
if (virAsprintf(&mcs, "s0:c%d,c%d", c1, c2) < 0) {
238
} while (mcsAdd(mcs) == -1);
240
vm->def->seclabel.label =
241
SELinuxGenNewContext(vm->def->seclabel.baselabel ?
242
vm->def->seclabel.baselabel :
243
default_domain_context, mcs);
244
if (! vm->def->seclabel.label) {
245
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
246
_("cannot generate selinux context for %s"), mcs);
250
vm->def->seclabel.imagelabel = SELinuxGenNewContext(default_image_context, mcs);
251
if (!vm->def->seclabel.imagelabel) {
252
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
253
_("cannot generate selinux context for %s"), mcs);
257
if (!vm->def->seclabel.model &&
258
!(vm->def->seclabel.model = strdup(SECURITY_SELINUX_NAME))) {
267
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC)
268
VIR_FREE(vm->def->seclabel.label);
269
VIR_FREE(vm->def->seclabel.imagelabel);
270
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
271
!vm->def->seclabel.baselabel)
272
VIR_FREE(vm->def->seclabel.model);
280
VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s",
281
NULLSTR(vm->def->seclabel.model),
282
NULLSTR(vm->def->seclabel.label),
283
NULLSTR(vm->def->seclabel.imagelabel),
284
NULLSTR(vm->def->seclabel.baselabel));
290
SELinuxReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
293
security_context_t pctx;
294
context_t ctx = NULL;
297
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
300
if (getpidcon(vm->pid, &pctx) == -1) {
301
virReportSystemError(errno,
302
_("unable to get PID %d security context"), vm->pid);
306
ctx = context_new(pctx);
311
mcs = context_range_get(ctx);
329
SELinuxSecurityDriverProbe(void)
331
return is_selinux_enabled() ? SECURITY_DRIVER_ENABLE : SECURITY_DRIVER_DISABLE;
335
SELinuxSecurityDriverOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
337
return SELinuxInitialize();
341
SELinuxSecurityDriverClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
347
static const char *SELinuxSecurityGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
349
return SECURITY_SELINUX_NAME;
352
static const char *SELinuxSecurityGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
355
* Where will the DOI come from? SELinux configuration, or qemu
356
* configuration? For the moment, we'll just set it to "0".
358
return SECURITY_SELINUX_VOID_DOI;
362
SELinuxGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
364
virSecurityLabelPtr sec)
366
security_context_t ctx;
368
if (getpidcon(vm->pid, &ctx) == -1) {
369
virReportSystemError(errno,
370
_("unable to get PID %d security context"),
375
if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
376
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
377
_("security label exceeds "
378
"maximum length: %d"),
379
VIR_SECURITY_LABEL_BUFLEN - 1);
384
strcpy(sec->label, (char *) ctx);
387
sec->enforcing = security_getenforce();
388
if (sec->enforcing == -1) {
389
virReportSystemError(errno, "%s",
390
_("error calling security_getenforce()"));
398
SELinuxSetFilecon(const char *path, char *tcon)
400
security_context_t econ;
402
VIR_INFO("Setting SELinux context on '%s' to '%s'", path, tcon);
404
if (setfilecon(path, tcon) < 0) {
405
int setfilecon_errno = errno;
407
if (getfilecon(path, &econ) >= 0) {
408
if (STREQ(tcon, econ)) {
410
/* It's alright, there's nothing to change anyway. */
416
/* if the error complaint is related to an image hosted on
417
* an nfs mount, or a usbfs/sysfs filesystem not supporting
418
* labelling, then just ignore it & hope for the best.
419
* The user hopefully set one of the necessary SELinux
420
* virt_use_{nfs,usb,pci} boolean tunables to allow it...
422
if (setfilecon_errno != EOPNOTSUPP && setfilecon_errno != ENOTSUP) {
423
virReportSystemError(setfilecon_errno,
424
_("unable to set security context '%s' on '%s'"),
426
if (security_getenforce() == 1)
430
if ((virStorageFileIsSharedFSType(path,
431
VIR_STORAGE_FILE_SHFS_NFS) == 1) &&
432
security_get_boolean_active("virt_use_nfs") != 1) {
433
msg = _("Setting security context '%s' on '%s' not supported. "
434
"Consider setting virt_use_nfs");
435
if (security_getenforce() == 1)
436
VIR_WARN(msg, tcon, path);
438
VIR_INFO(msg, tcon, path);
440
VIR_INFO("Setting security context '%s' on '%s' not supported",
449
SELinuxFSetFilecon(int fd, char *tcon)
451
security_context_t econ;
453
VIR_INFO("Setting SELinux context on fd %d to '%s'", fd, tcon);
455
if (fsetfilecon(fd, tcon) < 0) {
456
int fsetfilecon_errno = errno;
458
if (fgetfilecon(fd, &econ) >= 0) {
459
if (STREQ(tcon, econ)) {
461
/* It's alright, there's nothing to change anyway. */
467
/* if the error complaint is related to an image hosted on
468
* an nfs mount, or a usbfs/sysfs filesystem not supporting
469
* labelling, then just ignore it & hope for the best.
470
* The user hopefully set one of the necessary SELinux
471
* virt_use_{nfs,usb,pci} boolean tunables to allow it...
473
if (fsetfilecon_errno != EOPNOTSUPP) {
474
virReportSystemError(fsetfilecon_errno,
475
_("unable to set security context '%s' on fd %d"),
477
if (security_getenforce() == 1)
480
VIR_INFO("Setting security context '%s' on fd %d not supported",
487
/* Set fcon to the appropriate label for path and mode, or return -1. */
489
getContext(const char *newpath, mode_t mode, security_context_t *fcon)
491
#if HAVE_SELINUX_LABEL_H
492
struct selabel_handle *handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
498
ret = selabel_lookup(handle, fcon, newpath, mode);
499
selabel_close(handle);
502
return matchpathcon(newpath, mode, fcon);
507
/* This method shouldn't raise errors, since they'll overwrite
508
* errors that the caller(s) are already dealing with */
510
SELinuxRestoreSecurityFileLabel(const char *path)
513
security_context_t fcon = NULL;
515
char *newpath = NULL;
518
VIR_INFO("Restoring SELinux context on '%s'", path);
520
if (virFileResolveLink(path, &newpath) < 0) {
521
VIR_WARN("cannot resolve symlink %s: %s", path,
522
virStrerror(errno, ebuf, sizeof(ebuf)));
526
if (stat(newpath, &buf) != 0) {
527
VIR_WARN("cannot stat %s: %s", newpath,
528
virStrerror(errno, ebuf, sizeof(ebuf)));
532
if (getContext(newpath, buf.st_mode, &fcon) < 0) {
533
VIR_WARN("cannot lookup default selinux label for %s", newpath);
535
rc = SELinuxSetFilecon(newpath, fcon);
545
SELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
547
virDomainDiskDefPtr disk,
550
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
552
if (secdef->norelabel)
555
/* Don't restore labels on readoly/shared disks, because
556
* other VMs may still be accessing these
557
* Alternatively we could iterate over all running
558
* domains and try to figure out if it is in use, but
559
* this would not work for clustered filesystems, since
560
* we can't see running VMs using the file on other nodes
561
* Safest bet is thus to skip the restore step.
563
if (disk->readonly || disk->shared)
566
if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
569
/* If we have a shared FS & doing migrated, we must not
570
* change ownership, because that kills access on the
571
* destination host which is sub-optimal for the guest
572
* VM's I/O attempts :-)
575
int rc = virStorageFileIsSharedFS(disk->src);
579
VIR_DEBUG("Skipping image label restore on %s because FS is shared",
585
return SELinuxRestoreSecurityFileLabel(disk->src);
590
SELinuxRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
592
virDomainDiskDefPtr disk)
594
return SELinuxRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
599
SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
604
const virSecurityLabelDefPtr secdef = opaque;
609
ret = SELinuxSetFilecon(path, default_image_context);
610
} else if (disk->readonly) {
611
ret = SELinuxSetFilecon(path, default_content_context);
612
} else if (secdef->imagelabel) {
613
ret = SELinuxSetFilecon(path, secdef->imagelabel);
618
ret = SELinuxSetFilecon(path, default_content_context);
621
virStorageFileIsSharedFSType(path,
622
VIR_STORAGE_FILE_SHFS_NFS) == 1)
628
SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
630
virDomainDiskDefPtr disk)
633
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
634
bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
636
if (secdef->norelabel)
639
return virDomainDiskDefForeachPath(disk,
640
allowDiskFormatProbing,
642
SELinuxSetSecurityFileLabel,
648
SELinuxSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
649
const char *file, void *opaque)
651
virDomainObjPtr vm = opaque;
652
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
654
return SELinuxSetFilecon(file, secdef->imagelabel);
658
SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
659
const char *file, void *opaque)
661
virDomainObjPtr vm = opaque;
662
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
664
return SELinuxSetFilecon(file, secdef->imagelabel);
668
SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
670
virDomainHostdevDefPtr dev)
673
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
676
if (secdef->norelabel)
679
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
682
switch (dev->source.subsys.type) {
683
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
684
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
685
dev->source.subsys.u.usb.device);
690
ret = usbDeviceFileIterate(usb, SELinuxSetSecurityUSBLabel, vm);
695
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
696
pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
697
dev->source.subsys.u.pci.bus,
698
dev->source.subsys.u.pci.slot,
699
dev->source.subsys.u.pci.function);
704
ret = pciDeviceFileIterate(pci, SELinuxSetSecurityPCILabel, vm);
721
SELinuxRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
723
void *opaque ATTRIBUTE_UNUSED)
725
return SELinuxRestoreSecurityFileLabel(file);
729
SELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
731
void *opaque ATTRIBUTE_UNUSED)
733
return SELinuxRestoreSecurityFileLabel(file);
737
SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
739
virDomainHostdevDefPtr dev)
742
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
745
if (secdef->norelabel)
748
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
751
switch (dev->source.subsys.type) {
752
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
753
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
754
dev->source.subsys.u.usb.device);
759
ret = usbDeviceFileIterate(usb, SELinuxRestoreSecurityUSBLabel, NULL);
765
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
766
pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
767
dev->source.subsys.u.pci.bus,
768
dev->source.subsys.u.pci.slot,
769
dev->source.subsys.u.pci.function);
774
ret = pciDeviceFileIterate(pci, SELinuxRestoreSecurityPCILabel, NULL);
791
SELinuxSetSecurityChardevLabel(virDomainObjPtr vm,
792
virDomainChrSourceDefPtr dev)
795
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
796
char *in = NULL, *out = NULL;
799
if (secdef->norelabel)
803
case VIR_DOMAIN_CHR_TYPE_DEV:
804
case VIR_DOMAIN_CHR_TYPE_FILE:
805
ret = SELinuxSetFilecon(dev->data.file.path, secdef->imagelabel);
808
case VIR_DOMAIN_CHR_TYPE_PIPE:
809
if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
810
(virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
814
if (virFileExists(in) && virFileExists(out)) {
815
if ((SELinuxSetFilecon(in, secdef->imagelabel) < 0) ||
816
(SELinuxSetFilecon(out, secdef->imagelabel) < 0)) {
819
} else if (SELinuxSetFilecon(dev->data.file.path, secdef->imagelabel) < 0) {
837
SELinuxRestoreSecurityChardevLabel(virDomainObjPtr vm,
838
virDomainChrSourceDefPtr dev)
841
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
842
char *in = NULL, *out = NULL;
845
if (secdef->norelabel)
849
case VIR_DOMAIN_CHR_TYPE_DEV:
850
case VIR_DOMAIN_CHR_TYPE_FILE:
851
if (SELinuxRestoreSecurityFileLabel(dev->data.file.path) < 0)
855
case VIR_DOMAIN_CHR_TYPE_PIPE:
856
if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
857
(virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
861
if (virFileExists(in) && virFileExists(out)) {
862
if ((SELinuxRestoreSecurityFileLabel(out) < 0) ||
863
(SELinuxRestoreSecurityFileLabel(in) < 0)) {
866
} else if (SELinuxRestoreSecurityFileLabel(dev->data.file.path) < 0) {
885
SELinuxRestoreSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
886
virDomainChrDefPtr dev,
889
virDomainObjPtr vm = opaque;
891
/* This is taken care of by processing of def->serials */
892
if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
893
dev->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
896
return SELinuxRestoreSecurityChardevLabel(vm, &dev->source);
901
SELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
902
virDomainSmartcardDefPtr dev,
905
virDomainObjPtr vm = opaque;
906
const char *database;
909
case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
912
case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
913
database = dev->data.cert.database;
915
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
916
return SELinuxRestoreSecurityFileLabel(database);
918
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
919
return SELinuxRestoreSecurityChardevLabel(vm, &dev->data.passthru);
922
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
923
_("unknown smartcard type %d"),
933
SELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
935
int migrated ATTRIBUTE_UNUSED)
937
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
941
VIR_DEBUG("Restoring security label on %s", vm->def->name);
943
if (secdef->norelabel)
946
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
947
if (SELinuxRestoreSecurityHostdevLabel(mgr,
949
vm->def->hostdevs[i]) < 0)
952
for (i = 0 ; i < vm->def->ndisks ; i++) {
953
if (SELinuxRestoreSecurityImageLabelInt(mgr,
960
if (virDomainChrDefForeach(vm->def,
962
SELinuxRestoreSecurityChardevCallback,
966
if (virDomainSmartcardDefForeach(vm->def,
968
SELinuxRestoreSecuritySmartcardCallback,
972
if (vm->def->os.kernel &&
973
SELinuxRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
976
if (vm->def->os.initrd &&
977
SELinuxRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
984
SELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
987
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
989
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
990
if (secdef->label != NULL) {
991
context_t con = context_new(secdef->label);
993
mcsRemove(context_range_get(con));
997
VIR_FREE(secdef->label);
998
if (!secdef->baselabel)
999
VIR_FREE(secdef->model);
1001
VIR_FREE(secdef->imagelabel);
1008
SELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1010
const char *savefile)
1012
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
1014
if (secdef->norelabel)
1017
return SELinuxSetFilecon(savefile, secdef->imagelabel);
1022
SELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1024
const char *savefile)
1026
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
1028
if (secdef->norelabel)
1031
return SELinuxRestoreSecurityFileLabel(savefile);
1036
SELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1037
virDomainDefPtr def)
1039
const virSecurityLabelDefPtr secdef = &def->seclabel;
1040
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
1041
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
1042
_("security label driver mismatch: "
1043
"'%s' model configured for domain, but "
1044
"hypervisor driver is '%s'."),
1045
secdef->model, virSecurityManagerGetModel(mgr));
1049
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
1050
if (security_check_context(secdef->label) != 0) {
1051
virSecurityReportError(VIR_ERR_XML_ERROR,
1052
_("Invalid security label %s"), secdef->label);
1060
SELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr,
1063
/* TODO: verify DOI */
1064
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
1066
if (vm->def->seclabel.label == NULL)
1069
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
1070
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
1071
_("security label driver mismatch: "
1072
"'%s' model configured for domain, but "
1073
"hypervisor driver is '%s'."),
1074
secdef->model, virSecurityManagerGetModel(mgr));
1075
if (security_getenforce() == 1)
1079
if (setexeccon(secdef->label) == -1) {
1080
virReportSystemError(errno,
1081
_("unable to set security context '%s'"),
1083
if (security_getenforce() == 1)
1091
SELinuxSetSecurityDaemonSocketLabel(virSecurityManagerPtr mgr,
1094
/* TODO: verify DOI */
1095
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
1096
context_t execcon = NULL;
1097
context_t proccon = NULL;
1098
security_context_t scon = NULL;
1101
if (vm->def->seclabel.label == NULL)
1104
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
1105
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
1106
_("security label driver mismatch: "
1107
"'%s' model configured for domain, but "
1108
"hypervisor driver is '%s'."),
1109
secdef->model, virSecurityManagerGetModel(mgr));
1113
if ( !(execcon = context_new(secdef->label)) ) {
1114
virReportSystemError(errno,
1115
_("unable to allocate socket security context '%s'"),
1120
if (getcon(&scon) == -1) {
1121
virReportSystemError(errno,
1122
_("unable to get current process context '%s'"),
1127
if ( !(proccon = context_new(scon)) ) {
1128
virReportSystemError(errno,
1129
_("unable to set socket security context '%s'"),
1134
if (context_range_set(proccon, context_range_get(execcon)) == -1) {
1135
virReportSystemError(errno,
1136
_("unable to set socket security context range '%s'"),
1141
VIR_DEBUG("Setting VM %s socket context %s",
1142
vm->def->name, context_str(proccon));
1143
if (setsockcreatecon(context_str(proccon)) == -1) {
1144
virReportSystemError(errno,
1145
_("unable to set socket security context '%s'"),
1146
context_str(proccon));
1153
if (security_getenforce() != 1)
1155
if (execcon) context_free(execcon);
1156
if (proccon) context_free(proccon);
1162
SELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
1165
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
1168
if (secdef->label == NULL)
1171
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
1172
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
1173
_("security label driver mismatch: "
1174
"'%s' model configured for domain, but "
1175
"hypervisor driver is '%s'."),
1176
secdef->model, virSecurityManagerGetModel(mgr));
1180
VIR_DEBUG("Setting VM %s socket context %s",
1181
vm->def->name, secdef->label);
1182
if (setsockcreatecon(secdef->label) == -1) {
1183
virReportSystemError(errno,
1184
_("unable to set socket security context '%s'"),
1192
if (security_getenforce() != 1)
1199
SELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr,
1202
/* TODO: verify DOI */
1203
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
1205
if (vm->def->seclabel.label == NULL)
1208
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
1209
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
1210
_("security label driver mismatch: "
1211
"'%s' model configured for domain, but "
1212
"hypervisor driver is '%s'."),
1213
secdef->model, virSecurityManagerGetModel(mgr));
1214
if (security_getenforce() == 1)
1218
if (setsockcreatecon(NULL) == -1) {
1219
virReportSystemError(errno,
1220
_("unable to clear socket security context '%s'"),
1222
if (security_getenforce() == 1)
1230
SELinuxSetSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
1231
virDomainChrDefPtr dev,
1234
virDomainObjPtr vm = opaque;
1236
/* This is taken care of by processing of def->serials */
1237
if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
1238
dev->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
1241
return SELinuxSetSecurityChardevLabel(vm, &dev->source);
1246
SELinuxSetSecuritySmartcardCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
1247
virDomainSmartcardDefPtr dev,
1250
virDomainObjPtr vm = opaque;
1251
const char *database;
1253
switch (dev->type) {
1254
case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
1257
case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
1258
database = dev->data.cert.database;
1260
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
1261
return SELinuxSetFilecon(database, default_content_context);
1263
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
1264
return SELinuxSetSecurityChardevLabel(vm, &dev->data.passthru);
1267
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
1268
_("unknown smartcard type %d"),
1278
SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
1280
const char *stdin_path)
1282
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
1285
if (secdef->norelabel)
1288
for (i = 0 ; i < vm->def->ndisks ; i++) {
1289
/* XXX fixme - we need to recursively label the entire tree :-( */
1290
if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR) {
1291
VIR_WARN("Unable to relabel directory tree %s for disk %s",
1292
vm->def->disks[i]->src, vm->def->disks[i]->dst);
1295
if (SELinuxSetSecurityImageLabel(mgr,
1296
vm, vm->def->disks[i]) < 0)
1299
/* XXX fixme process vm->def->fss if relabel == true */
1301
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
1302
if (SELinuxSetSecurityHostdevLabel(mgr,
1304
vm->def->hostdevs[i]) < 0)
1308
if (virDomainChrDefForeach(vm->def,
1310
SELinuxSetSecurityChardevCallback,
1314
if (virDomainSmartcardDefForeach(vm->def,
1316
SELinuxSetSecuritySmartcardCallback,
1320
if (vm->def->os.kernel &&
1321
SELinuxSetFilecon(vm->def->os.kernel, default_content_context) < 0)
1324
if (vm->def->os.initrd &&
1325
SELinuxSetFilecon(vm->def->os.initrd, default_content_context) < 0)
1329
if (SELinuxSetFilecon(stdin_path, default_content_context) < 0 &&
1330
virStorageFileIsSharedFSType(stdin_path,
1331
VIR_STORAGE_FILE_SHFS_NFS) != 1)
1339
SELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1343
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
1345
if (secdef->imagelabel == NULL)
1348
return SELinuxFSetFilecon(fd, secdef->imagelabel);
1351
virSecurityDriver virSecurityDriverSELinux = {
1353
SECURITY_SELINUX_NAME,
1354
SELinuxSecurityDriverProbe,
1355
SELinuxSecurityDriverOpen,
1356
SELinuxSecurityDriverClose,
1358
SELinuxSecurityGetModel,
1359
SELinuxSecurityGetDOI,
1361
SELinuxSecurityVerify,
1363
SELinuxSetSecurityImageLabel,
1364
SELinuxRestoreSecurityImageLabel,
1366
SELinuxSetSecurityDaemonSocketLabel,
1367
SELinuxSetSecuritySocketLabel,
1368
SELinuxClearSecuritySocketLabel,
1370
SELinuxGenSecurityLabel,
1371
SELinuxReserveSecurityLabel,
1372
SELinuxReleaseSecurityLabel,
1374
SELinuxGetSecurityProcessLabel,
1375
SELinuxSetSecurityProcessLabel,
1377
SELinuxSetSecurityAllLabel,
1378
SELinuxRestoreSecurityAllLabel,
1380
SELinuxSetSecurityHostdevLabel,
1381
SELinuxRestoreSecurityHostdevLabel,
1383
SELinuxSetSavedStateLabel,
1384
SELinuxRestoreSavedStateLabel,
1386
SELinuxSetImageFDLabel,