mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-09 14:35:25 +00:00
selinux: add security selinux function to label tapfd
BZ:https://bugzilla.redhat.com/show_bug.cgi?id=851981 When using macvtap, a character device gets first created by kernel with name /dev/tapN, its selinux context is: system_u:object_r:device_t:s0 Shortly, when udev gets notification when new file is created in /dev, it will then jump in and relabel this file back to the expected default context: system_u:object_r:tun_tap_device_t:s0 There is a time gap happened. Sometimes, it will have migration failed, AVC error message: type=AVC msg=audit(1349858424.233:42507): avc: denied { read write } for pid=19926 comm="qemu-kvm" path="/dev/tap33" dev=devtmpfs ino=131524 scontext=unconfined_u:system_r:svirt_t:s0:c598,c908 tcontext=system_u:object_r:device_t:s0 tclass=chr_file This patch will label the tapfd device before qemu process starts: system_u:object_r:tun_tap_device_t:MCS(MCS from seclabel->label)
This commit is contained in:
parent
7ba5defb5a
commit
ae368ebfcc
@ -1059,6 +1059,7 @@ virSecurityManagerSetHostdevLabel;
|
|||||||
virSecurityManagerSetProcessLabel;
|
virSecurityManagerSetProcessLabel;
|
||||||
virSecurityManagerSetSavedStateLabel;
|
virSecurityManagerSetSavedStateLabel;
|
||||||
virSecurityManagerSetSocketLabel;
|
virSecurityManagerSetSocketLabel;
|
||||||
|
virSecurityManagerSetTapFDLabel;
|
||||||
virSecurityManagerStackAddNested;
|
virSecurityManagerStackAddNested;
|
||||||
virSecurityManagerVerify;
|
virSecurityManagerVerify;
|
||||||
virSecurityManagerGetMountOptions;
|
virSecurityManagerGetMountOptions;
|
||||||
|
@ -5412,6 +5412,10 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
if (tapfd < 0)
|
if (tapfd < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (virSecurityManagerSetTapFDLabel(driver->securityManager,
|
||||||
|
def, tapfd) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
last_good_net = i;
|
last_good_net = i;
|
||||||
virCommandTransferFD(cmd, tapfd);
|
virCommandTransferFD(cmd, tapfd);
|
||||||
|
|
||||||
|
@ -872,6 +872,15 @@ AppArmorSetImageFDLabel(virSecurityManagerPtr mgr,
|
|||||||
return reload_profile(mgr, def, fd_path, true);
|
return reload_profile(mgr, def, fd_path, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO need code here */
|
||||||
|
static int
|
||||||
|
AppArmorSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
||||||
|
int fd ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virSecurityDriver virAppArmorSecurityDriver = {
|
virSecurityDriver virAppArmorSecurityDriver = {
|
||||||
.privateDataLen = 0,
|
.privateDataLen = 0,
|
||||||
.name = SECURITY_APPARMOR_NAME,
|
.name = SECURITY_APPARMOR_NAME,
|
||||||
@ -908,4 +917,5 @@ virSecurityDriver virAppArmorSecurityDriver = {
|
|||||||
.domainRestoreSavedStateLabel = AppArmorRestoreSavedStateLabel,
|
.domainRestoreSavedStateLabel = AppArmorRestoreSavedStateLabel,
|
||||||
|
|
||||||
.domainSetSecurityImageFDLabel = AppArmorSetImageFDLabel,
|
.domainSetSecurityImageFDLabel = AppArmorSetImageFDLabel,
|
||||||
|
.domainSetSecurityTapFDLabel = AppArmorSetTapFDLabel,
|
||||||
};
|
};
|
||||||
|
@ -1029,6 +1029,14 @@ virSecurityDACSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
||||||
|
int fd ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static char *virSecurityDACGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
static char *virSecurityDACGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainDefPtr vm ATTRIBUTE_UNUSED) {
|
virDomainDefPtr vm ATTRIBUTE_UNUSED) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1070,6 +1078,7 @@ virSecurityDriver virSecurityDriverDAC = {
|
|||||||
.domainRestoreSavedStateLabel = virSecurityDACRestoreSavedStateLabel,
|
.domainRestoreSavedStateLabel = virSecurityDACRestoreSavedStateLabel,
|
||||||
|
|
||||||
.domainSetSecurityImageFDLabel = virSecurityDACSetImageFDLabel,
|
.domainSetSecurityImageFDLabel = virSecurityDACSetImageFDLabel,
|
||||||
|
.domainSetSecurityTapFDLabel = virSecurityDACSetTapFDLabel,
|
||||||
|
|
||||||
.domainGetSecurityMountOptions = virSecurityDACGetMountOptions,
|
.domainGetSecurityMountOptions = virSecurityDACGetMountOptions,
|
||||||
};
|
};
|
||||||
|
@ -95,6 +95,9 @@ typedef int (*virSecurityDomainSecurityVerify) (virSecurityManagerPtr mgr,
|
|||||||
typedef int (*virSecurityDomainSetImageFDLabel) (virSecurityManagerPtr mgr,
|
typedef int (*virSecurityDomainSetImageFDLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
int fd);
|
int fd);
|
||||||
|
typedef int (*virSecurityDomainSetTapFDLabel) (virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr def,
|
||||||
|
int fd);
|
||||||
typedef char *(*virSecurityDomainGetMountOptions) (virSecurityManagerPtr mgr,
|
typedef char *(*virSecurityDomainGetMountOptions) (virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def);
|
virDomainDefPtr def);
|
||||||
|
|
||||||
@ -134,6 +137,7 @@ struct _virSecurityDriver {
|
|||||||
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
|
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
|
||||||
|
|
||||||
virSecurityDomainSetImageFDLabel domainSetSecurityImageFDLabel;
|
virSecurityDomainSetImageFDLabel domainSetSecurityImageFDLabel;
|
||||||
|
virSecurityDomainSetTapFDLabel domainSetSecurityTapFDLabel;
|
||||||
|
|
||||||
virSecurityDomainGetMountOptions domainGetSecurityMountOptions;
|
virSecurityDomainGetMountOptions domainGetSecurityMountOptions;
|
||||||
};
|
};
|
||||||
|
@ -469,6 +469,17 @@ int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerSetTapFDLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr vm,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainSetSecurityTapFDLabel)
|
||||||
|
return mgr->drv->domainSetSecurityTapFDLabel(mgr, vm, fd);
|
||||||
|
|
||||||
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
|
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
|
@ -105,6 +105,9 @@ int virSecurityManagerVerify(virSecurityManagerPtr mgr,
|
|||||||
int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
|
int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
int fd);
|
int fd);
|
||||||
|
int virSecurityManagerSetTapFDLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr vm,
|
||||||
|
int fd);
|
||||||
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
|
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr vm);
|
virDomainDefPtr vm);
|
||||||
virSecurityManagerPtr*
|
virSecurityManagerPtr*
|
||||||
|
@ -204,7 +204,8 @@ virSecurityDriver virSecurityDriverNop = {
|
|||||||
.domainSetSavedStateLabel = virSecurityDomainSetSavedStateLabelNop,
|
.domainSetSavedStateLabel = virSecurityDomainSetSavedStateLabelNop,
|
||||||
.domainRestoreSavedStateLabel = virSecurityDomainRestoreSavedStateLabelNop,
|
.domainRestoreSavedStateLabel = virSecurityDomainRestoreSavedStateLabelNop,
|
||||||
|
|
||||||
.domainSetSecurityImageFDLabel = virSecurityDomainSetFDLabelNop,
|
.domainSetSecurityImageFDLabel = virSecurityDomainSetFDLabelNop,
|
||||||
|
.domainSetSecurityTapFDLabel = virSecurityDomainSetFDLabelNop,
|
||||||
|
|
||||||
.domainGetSecurityMountOptions = virSecurityDomainGetMountOptionsNop,
|
.domainGetSecurityMountOptions = virSecurityDomainGetMountOptionsNop,
|
||||||
};
|
};
|
||||||
|
@ -237,6 +237,46 @@ cleanup:
|
|||||||
return mcs;
|
return mcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
virSecuritySELinuxContextAddRange(security_context_t src,
|
||||||
|
security_context_t dst)
|
||||||
|
{
|
||||||
|
char *str = NULL;
|
||||||
|
char *ret = NULL;
|
||||||
|
context_t srccon = NULL;
|
||||||
|
context_t dstcon = NULL;
|
||||||
|
|
||||||
|
if (!src || !dst)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!(srccon = context_new(src)) || !(dstcon = context_new(dst))) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("unable to allocate security context"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context_range_set(dstcon, context_range_get(srccon)) == -1) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("unable to set security context range '%s'"), dst);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(str = context_str(dstcon))) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to format SELinux context"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ret = strdup(str))) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (srccon) context_free(srccon);
|
||||||
|
if (dstcon) context_free(dstcon);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
virSecuritySELinuxGenNewContext(const char *basecontext,
|
virSecuritySELinuxGenNewContext(const char *basecontext,
|
||||||
@ -1597,6 +1637,7 @@ virSecuritySELinuxSetSecurityDaemonSocketLabel(virSecurityManagerPtr mgr,
|
|||||||
context_t execcon = NULL;
|
context_t execcon = NULL;
|
||||||
context_t proccon = NULL;
|
context_t proccon = NULL;
|
||||||
security_context_t scon = NULL;
|
security_context_t scon = NULL;
|
||||||
|
char *str = NULL;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
@ -1615,13 +1656,6 @@ virSecuritySELinuxSetSecurityDaemonSocketLabel(virSecurityManagerPtr mgr,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !(execcon = context_new(secdef->label)) ) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("unable to allocate socket security context '%s'"),
|
|
||||||
secdef->label);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getcon_raw(&scon) == -1) {
|
if (getcon_raw(&scon) == -1) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("unable to get current process context '%s'"),
|
_("unable to get current process context '%s'"),
|
||||||
@ -1629,26 +1663,13 @@ virSecuritySELinuxSetSecurityDaemonSocketLabel(virSecurityManagerPtr mgr,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !(proccon = context_new(scon)) ) {
|
if (!(str = virSecuritySELinuxContextAddRange(secdef->label, scon)))
|
||||||
virReportSystemError(errno,
|
|
||||||
_("unable to set socket security context '%s'"),
|
|
||||||
secdef->label);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
if (context_range_set(proccon, context_range_get(execcon)) == -1) {
|
VIR_DEBUG("Setting VM %s socket context %s", def->name, str);
|
||||||
|
if (setsockcreatecon_raw(str) == -1) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("unable to set socket security context range '%s'"),
|
_("unable to set socket security context '%s'"), str);
|
||||||
secdef->label);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
VIR_DEBUG("Setting VM %s socket context %s",
|
|
||||||
def->name, context_str(proccon));
|
|
||||||
if (setsockcreatecon_raw(context_str(proccon)) == -1) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("unable to set socket security context '%s'"),
|
|
||||||
context_str(proccon));
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1660,6 +1681,7 @@ done:
|
|||||||
if (execcon) context_free(execcon);
|
if (execcon) context_free(execcon);
|
||||||
if (proccon) context_free(proccon);
|
if (proccon) context_free(proccon);
|
||||||
freecon(scon);
|
freecon(scon);
|
||||||
|
VIR_FREE(str);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1869,6 +1891,53 @@ virSecuritySELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
return virSecuritySELinuxFSetFilecon(fd, secdef->imagelabel);
|
return virSecuritySELinuxFSetFilecon(fd, secdef->imagelabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDefPtr def,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
security_context_t fcon = NULL;
|
||||||
|
virSecurityLabelDefPtr secdef;
|
||||||
|
char *str = NULL;
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (secdef->label == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fstat(fd, &buf) < 0) {
|
||||||
|
virReportSystemError(errno, _("cannot stat tap fd %d"), fd);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((buf.st_mode & S_IFMT) != S_IFCHR) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("tap fd %d is not character device"), fd);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getContext("/dev/tap.*", buf.st_mode, &fcon) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("cannot lookup default selinux label for tap fd %d"), fd);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(str = virSecuritySELinuxContextAddRange(secdef->label, fcon))) {
|
||||||
|
goto cleanup;
|
||||||
|
} else {
|
||||||
|
rc = virSecuritySELinuxFSetFilecon(fd, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
freecon(fcon);
|
||||||
|
VIR_FREE(str);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
virSecuritySELinuxGenImageLabel(virSecurityManagerPtr mgr,
|
virSecuritySELinuxGenImageLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
@ -1969,6 +2038,7 @@ virSecurityDriver virSecurityDriverSELinux = {
|
|||||||
.domainRestoreSavedStateLabel = virSecuritySELinuxRestoreSavedStateLabel,
|
.domainRestoreSavedStateLabel = virSecuritySELinuxRestoreSavedStateLabel,
|
||||||
|
|
||||||
.domainSetSecurityImageFDLabel = virSecuritySELinuxSetImageFDLabel,
|
.domainSetSecurityImageFDLabel = virSecuritySELinuxSetImageFDLabel,
|
||||||
|
.domainSetSecurityTapFDLabel = virSecuritySELinuxSetTapFDLabel,
|
||||||
|
|
||||||
.domainGetSecurityMountOptions = virSecuritySELinuxGetSecurityMountOptions,
|
.domainGetSecurityMountOptions = virSecuritySELinuxGetSecurityMountOptions,
|
||||||
};
|
};
|
||||||
|
@ -445,6 +445,23 @@ virSecurityStackSetImageFDLabel(virSecurityManagerPtr mgr,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackSetTapFDLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr vm,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
for (; item; item = item->next) {
|
||||||
|
if (virSecurityManagerSetTapFDLabel(item->securityManager, vm, fd) < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static char *virSecurityStackGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
static char *virSecurityStackGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainDefPtr vm ATTRIBUTE_UNUSED) {
|
virDomainDefPtr vm ATTRIBUTE_UNUSED) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -509,6 +526,7 @@ virSecurityDriver virSecurityDriverStack = {
|
|||||||
.domainRestoreSavedStateLabel = virSecurityStackRestoreSavedStateLabel,
|
.domainRestoreSavedStateLabel = virSecurityStackRestoreSavedStateLabel,
|
||||||
|
|
||||||
.domainSetSecurityImageFDLabel = virSecurityStackSetImageFDLabel,
|
.domainSetSecurityImageFDLabel = virSecurityStackSetImageFDLabel,
|
||||||
|
.domainSetSecurityTapFDLabel = virSecurityStackSetTapFDLabel,
|
||||||
|
|
||||||
.domainGetSecurityMountOptions = virSecurityStackGetMountOptions,
|
.domainGetSecurityMountOptions = virSecurityStackGetMountOptions,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user