mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Improve security label error reporting & verification (Dan Walsh)
This commit is contained in:
parent
d9ec9c6937
commit
11b0ed46c5
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
Thu Apr 3 11:55:00 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
Improve error reporting/ verification of security labels
|
||||||
|
(Dan Walsh)
|
||||||
|
* src/domain_conf.c: Improve error reporting for parsing of
|
||||||
|
seclabel XML
|
||||||
|
* src/libvirt_private.syms: Export virSecurityDriverVerify
|
||||||
|
* src/qemu_driver.c: Verify seclabel when creating or
|
||||||
|
defining a new domain
|
||||||
|
* src/security.c, src/security.h, src/security_linux.c: Add
|
||||||
|
functions for verifying security labels
|
||||||
|
* tests/.gitignore: Ignore seclabeltest
|
||||||
|
* tests/Makefile.am, tests/seclabeltest.c: Add test for
|
||||||
|
security driver
|
||||||
|
|
||||||
Thu Apr 2 19:41:00 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
Thu Apr 2 19:41:00 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
Mingw portability fixes
|
Mingw portability fixes
|
||||||
|
@ -419,7 +419,8 @@ EXTRA_DIST += \
|
|||||||
$(STORAGE_DRIVER_DISK_SOURCES) \
|
$(STORAGE_DRIVER_DISK_SOURCES) \
|
||||||
$(NODE_DEVICE_DRIVER_SOURCES) \
|
$(NODE_DEVICE_DRIVER_SOURCES) \
|
||||||
$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
|
$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
|
||||||
$(NODE_DEVICE_DRIVER_DEVKIT_SOURCES)
|
$(NODE_DEVICE_DRIVER_DEVKIT_SOURCES) \
|
||||||
|
$(SECURITY_DRIVER_SELINUX_SOURCES)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build our version script. This is composed of three parts:
|
# Build our version script. This is composed of three parts:
|
||||||
|
@ -1859,29 +1859,44 @@ virSecurityLabelDefParseXML(virConnectPtr conn,
|
|||||||
if (virXPathNode(conn, "./seclabel", ctxt) == NULL)
|
if (virXPathNode(conn, "./seclabel", ctxt) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
p = virXPathStringLimit(conn, "string(./seclabel/@model)",
|
||||||
|
VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
|
||||||
|
if (p == NULL) {
|
||||||
|
virDomainReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
|
"%s", _("missing security model"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
def->seclabel.model = p;
|
||||||
|
|
||||||
p = virXPathStringLimit(conn, "string(./seclabel/@type)",
|
p = virXPathStringLimit(conn, "string(./seclabel/@type)",
|
||||||
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||||
if (p == NULL)
|
if (p == NULL) {
|
||||||
goto error;
|
virDomainReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
if ((def->seclabel.type = virDomainSeclabelTypeFromString(p)) < 0)
|
"%s", _("missing security type"));
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
def->seclabel.type = virDomainSeclabelTypeFromString(p);
|
||||||
VIR_FREE(p);
|
VIR_FREE(p);
|
||||||
|
if (def->seclabel.type < 0) {
|
||||||
|
virDomainReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid security type"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only parse details, if using static labels, or
|
/* Only parse details, if using static labels, or
|
||||||
* if the 'live' VM XML is requested
|
* if the 'live' VM XML is requested
|
||||||
*/
|
*/
|
||||||
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC ||
|
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC ||
|
||||||
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
||||||
p = virXPathStringLimit(conn, "string(./seclabel/@model)",
|
|
||||||
VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
|
|
||||||
if (p == NULL)
|
|
||||||
goto error;
|
|
||||||
def->seclabel.model = p;
|
|
||||||
|
|
||||||
p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
|
p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
|
||||||
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||||
if (p == NULL)
|
if (p == NULL) {
|
||||||
|
virDomainReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
|
_("security label is missing"));
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
def->seclabel.label = p;
|
def->seclabel.label = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,6 +248,7 @@ free_qparam_set;
|
|||||||
|
|
||||||
|
|
||||||
# security.h
|
# security.h
|
||||||
|
virSecurityDriverVerify;
|
||||||
virSecurityDriverStartup;
|
virSecurityDriverStartup;
|
||||||
virSecurityDriverInit;
|
virSecurityDriverInit;
|
||||||
virSecurityDriverSetDOI;
|
virSecurityDriverSetDOI;
|
||||||
|
@ -2115,6 +2115,9 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
|
|||||||
VIR_DOMAIN_XML_INACTIVE)))
|
VIR_DOMAIN_XML_INACTIVE)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virSecurityDriverVerify(conn, def) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
vm = virDomainFindByName(&driver->domains, def->name);
|
vm = virDomainFindByName(&driver->domains, def->name);
|
||||||
if (vm) {
|
if (vm) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
||||||
@ -3398,6 +3401,9 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
|
|||||||
VIR_DOMAIN_XML_INACTIVE)))
|
VIR_DOMAIN_XML_INACTIVE)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virSecurityDriverVerify(conn, def) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
vm = virDomainFindByName(&driver->domains, def->name);
|
vm = virDomainFindByName(&driver->domains, def->name);
|
||||||
if (vm) {
|
if (vm) {
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
|
@ -27,6 +27,25 @@ static virSecurityDriverPtr security_drivers[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
virSecurityDriverVerify(virConnectPtr conn, virDomainDefPtr def)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
||||||
|
|
||||||
|
if (STREQ(secdef->model, "none"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; security_drivers[i] != NULL ; i++) {
|
||||||
|
if (STREQ(security_drivers[i]->name, secdef->model)) {
|
||||||
|
return security_drivers[i]->domainSecurityVerify(conn, def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virSecurityReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid security model"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
virSecurityDriverStartup(virSecurityDriverPtr *drv,
|
virSecurityDriverStartup(virSecurityDriverPtr *drv,
|
||||||
const char *name)
|
const char *name)
|
||||||
|
@ -46,11 +46,14 @@ typedef int (*virSecurityDomainRestoreLabel) (virConnectPtr conn,
|
|||||||
typedef int (*virSecurityDomainSetLabel) (virConnectPtr conn,
|
typedef int (*virSecurityDomainSetLabel) (virConnectPtr conn,
|
||||||
virSecurityDriverPtr drv,
|
virSecurityDriverPtr drv,
|
||||||
virDomainObjPtr vm);
|
virDomainObjPtr vm);
|
||||||
|
typedef int (*virSecurityDomainSecurityVerify) (virConnectPtr conn,
|
||||||
|
virDomainDefPtr def);
|
||||||
|
|
||||||
struct _virSecurityDriver {
|
struct _virSecurityDriver {
|
||||||
const char *name;
|
const char *name;
|
||||||
virSecurityDriverProbe probe;
|
virSecurityDriverProbe probe;
|
||||||
virSecurityDriverOpen open;
|
virSecurityDriverOpen open;
|
||||||
|
virSecurityDomainSecurityVerify domainSecurityVerify;
|
||||||
virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel;
|
virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel;
|
||||||
virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
|
virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
|
||||||
virSecurityDomainGenLabel domainGenSecurityLabel;
|
virSecurityDomainGenLabel domainGenSecurityLabel;
|
||||||
@ -71,6 +74,9 @@ struct _virSecurityDriver {
|
|||||||
int virSecurityDriverStartup(virSecurityDriverPtr *drv,
|
int virSecurityDriverStartup(virSecurityDriverPtr *drv,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
|
int
|
||||||
|
virSecurityDriverVerify(virConnectPtr conn, virDomainDefPtr def);
|
||||||
|
|
||||||
void
|
void
|
||||||
virSecurityReportError(virConnectPtr conn, int code, const char *fmt, ...)
|
virSecurityReportError(virConnectPtr conn, int code, const char *fmt, ...)
|
||||||
ATTRIBUTE_FORMAT(printf, 3, 4);
|
ATTRIBUTE_FORMAT(printf, 3, 4);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 Red Hat, Inc.
|
* Copyright (C) 2008,2009 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -8,6 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* James Morris <jmorris@namei.org>
|
* James Morris <jmorris@namei.org>
|
||||||
|
* Dan Walsh <dwalsh@redhat.com>
|
||||||
*
|
*
|
||||||
* SELinux security driver.
|
* SELinux security driver.
|
||||||
*/
|
*/
|
||||||
@ -356,6 +357,20 @@ SELinuxRestoreSecurityLabel(virConnectPtr conn,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxSecurityVerify(virConnectPtr conn, virDomainDefPtr def)
|
||||||
|
{
|
||||||
|
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
||||||
|
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
|
||||||
|
if (security_check_context(secdef->label) != 0) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
|
_("Invalid security label %s"), secdef->label);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSetSecurityLabel(virConnectPtr conn,
|
SELinuxSetSecurityLabel(virConnectPtr conn,
|
||||||
virSecurityDriverPtr drv,
|
virSecurityDriverPtr drv,
|
||||||
@ -402,6 +417,7 @@ virSecurityDriver virSELinuxSecurityDriver = {
|
|||||||
.name = SECURITY_SELINUX_NAME,
|
.name = SECURITY_SELINUX_NAME,
|
||||||
.probe = SELinuxSecurityDriverProbe,
|
.probe = SELinuxSecurityDriverProbe,
|
||||||
.open = SELinuxSecurityDriverOpen,
|
.open = SELinuxSecurityDriverOpen,
|
||||||
|
.domainSecurityVerify = SELinuxSecurityVerify,
|
||||||
.domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
|
.domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
|
||||||
.domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
|
.domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
|
||||||
.domainGenSecurityLabel = SELinuxGenSecurityLabel,
|
.domainGenSecurityLabel = SELinuxGenSecurityLabel,
|
||||||
|
@ -15,6 +15,7 @@ nodedevxml2xmltest
|
|||||||
nodeinfotest
|
nodeinfotest
|
||||||
statstest
|
statstest
|
||||||
qparamtest
|
qparamtest
|
||||||
|
seclabeltest
|
||||||
*.gcda
|
*.gcda
|
||||||
*.gcno
|
*.gcno
|
||||||
*.exe
|
*.exe
|
||||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -15,6 +15,7 @@ nodedevxml2xmltest
|
|||||||
nodeinfotest
|
nodeinfotest
|
||||||
statstest
|
statstest
|
||||||
qparamtest
|
qparamtest
|
||||||
|
seclabeltest
|
||||||
*.gcda
|
*.gcda
|
||||||
*.gcno
|
*.gcno
|
||||||
*.exe
|
*.exe
|
||||||
|
@ -64,6 +64,10 @@ if WITH_QEMU
|
|||||||
noinst_PROGRAMS += qemuxml2argvtest qemuxml2xmltest
|
noinst_PROGRAMS += qemuxml2argvtest qemuxml2xmltest
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if WITH_SECDRIVER_SELINUX
|
||||||
|
noinst_PROGRAMS += seclabeltest
|
||||||
|
endif
|
||||||
|
|
||||||
noinst_PROGRAMS += nodedevxml2xmltest
|
noinst_PROGRAMS += nodedevxml2xmltest
|
||||||
|
|
||||||
test_scripts = \
|
test_scripts = \
|
||||||
@ -114,6 +118,10 @@ if WITH_QEMU
|
|||||||
TESTS += qemuxml2argvtest qemuxml2xmltest
|
TESTS += qemuxml2argvtest qemuxml2xmltest
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if WITH_SECDRIVER_SELINUX
|
||||||
|
TESTS += seclabeltest
|
||||||
|
endif
|
||||||
|
|
||||||
TESTS += nodedevxml2xmltest
|
TESTS += nodedevxml2xmltest
|
||||||
|
|
||||||
path_add = $$abs_top_builddir/src$(PATH_SEPARATOR)$$abs_top_builddir/qemud
|
path_add = $$abs_top_builddir/src$(PATH_SEPARATOR)$$abs_top_builddir/qemud
|
||||||
@ -203,6 +211,14 @@ statstest_SOURCES = \
|
|||||||
statstest.c testutils.h testutils.c
|
statstest.c testutils.h testutils.c
|
||||||
statstest_LDADD = $(LDADDS)
|
statstest_LDADD = $(LDADDS)
|
||||||
|
|
||||||
|
if WITH_SECDRIVER_SELINUX
|
||||||
|
seclabeltest_SOURCES = \
|
||||||
|
seclabeltest.c
|
||||||
|
seclabeltest_LDADD = ../src/libvirt_driver_security.la $(LDADDS)
|
||||||
|
else
|
||||||
|
EXTRA_DIST += seclabeltest.c
|
||||||
|
endif
|
||||||
|
|
||||||
qparamtest_SOURCES = \
|
qparamtest_SOURCES = \
|
||||||
qparamtest.c testutils.h testutils.c
|
qparamtest.c testutils.h testutils.c
|
||||||
qparamtest_LDADD = $(LDADDS)
|
qparamtest_LDADD = $(LDADDS)
|
||||||
|
45
tests/seclabeltest.c
Normal file
45
tests/seclabeltest.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "security.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
const char *doi, *model;
|
||||||
|
virSecurityDriverPtr security_drv;
|
||||||
|
|
||||||
|
ret = virSecurityDriverStartup (&security_drv, "selinux");
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Failed to start security driver");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
/* No security driver wanted to be enabled: just return */
|
||||||
|
if (ret == -2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
model = virSecurityDriverGetModel (security_drv);
|
||||||
|
if (!model)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Failed to copy secModel model: %s",
|
||||||
|
strerror (errno));
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
doi = virSecurityDriverGetDOI (security_drv);
|
||||||
|
if (!doi)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Failed to copy secModel DOI: %s",
|
||||||
|
strerror (errno));
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user