qemu: Refactor initialisation of security drivers.

The security driver loading code in qemu has a flaw that causes it to
register the DAC security driver twice. This causes problems (machines
unable to start) as the two DAC drivers clash together.

This patch refactors the code to allow loading the DAC driver even if
its specified in configuration (it can't be registered as a common
security driver), and does not add the driver twice.
This commit is contained in:
Peter Krempa 2012-08-29 14:19:39 +02:00
parent ba150e5504
commit eb8e9b6027
1 changed files with 68 additions and 44 deletions

View File

@ -249,40 +249,69 @@ static int
qemuSecurityInit(struct qemud_driver *driver) qemuSecurityInit(struct qemud_driver *driver)
{ {
char **names; char **names;
char *primary; char *primary = NULL;
virSecurityManagerPtr mgr, nested, stack = NULL; virSecurityManagerPtr mgr = NULL;
virSecurityManagerPtr nested = NULL;
virSecurityManagerPtr stack = NULL;
bool hasDAC = false;
if (driver->securityDriverNames == NULL) /* set the name of the primary security driver */
primary = NULL; if (driver->securityDriverNames)
else
primary = driver->securityDriverNames[0]; primary = driver->securityDriverNames[0];
/* Create primary driver */ /* add primary security driver */
mgr = virSecurityManagerNew(primary, if ((primary == NULL && driver->privileged) ||
QEMU_DRIVER_NAME, STREQ_NULLABLE(primary, "dac")) {
driver->allowDiskFormatProbing, if (!driver->privileged) {
driver->securityDefaultConfined, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
driver->securityRequireConfined); _("DAC security driver usable only when "
"running privileged (as root)"));
goto error;
}
mgr = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
driver->user,
driver->group,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined,
driver->dynamicOwnership);
hasDAC = true;
} else {
mgr = virSecurityManagerNew(primary,
QEMU_DRIVER_NAME,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined);
}
if (!mgr) if (!mgr)
goto error; goto error;
/* If a DAC driver is required or additional drivers are provived, a stack /* We need a stack to group the security drivers if:
* driver should be create to group them all */ * - additional drivers are provived in configuration
if (driver->privileged || * - the primary driver isn't DAC and we are running privileged
*/
if ((driver->privileged && !hasDAC) ||
(driver->securityDriverNames && driver->securityDriverNames[1])) { (driver->securityDriverNames && driver->securityDriverNames[1])) {
stack = virSecurityManagerNewStack(mgr); if (!(stack = virSecurityManagerNewStack(mgr)))
if (!stack)
goto error; goto error;
mgr = stack; mgr = stack;
} }
/* Loop through additional driver names and add a secudary driver to each /* Loop through additional driver names and add them as nested */
* one */
if (driver->securityDriverNames) { if (driver->securityDriverNames) {
names = driver->securityDriverNames + 1; names = driver->securityDriverNames + 1;
while (names && *names) { while (names && *names) {
if (STREQ("dac", *names)) { if (STREQ("dac", *names)) {
/* A DAC driver has specific parameters */ /* A DAC driver has specific parameters */
if (!driver->privileged) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("DAC security driver usable only when "
"running privileged (as root)"));
goto error;
}
nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME, nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
driver->user, driver->user,
driver->group, driver->group,
@ -290,6 +319,7 @@ qemuSecurityInit(struct qemud_driver *driver)
driver->securityDefaultConfined, driver->securityDefaultConfined,
driver->securityRequireConfined, driver->securityRequireConfined,
driver->dynamicOwnership); driver->dynamicOwnership);
hasDAC = true;
} else { } else {
nested = virSecurityManagerNew(*names, nested = virSecurityManagerNew(*names,
QEMU_DRIVER_NAME, QEMU_DRIVER_NAME,
@ -297,39 +327,32 @@ qemuSecurityInit(struct qemud_driver *driver)
driver->securityDefaultConfined, driver->securityDefaultConfined,
driver->securityRequireConfined); driver->securityRequireConfined);
} }
if (nested == NULL)
if (!nested)
goto error; goto error;
if (virSecurityManagerStackAddNested(stack, nested)) if (virSecurityManagerStackAddNested(stack, nested))
goto error; goto error;
nested = NULL;
names++; names++;
} }
} }
if (driver->privileged) { if (driver->privileged && !hasDAC) {
/* When a DAC driver is required, check if there is already one in the if (!(nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
* additional drivers */ driver->user,
names = driver->securityDriverNames; driver->group,
while (names && *names) { driver->allowDiskFormatProbing,
if (STREQ("dac", *names)) { driver->securityDefaultConfined,
break; driver->securityRequireConfined,
} driver->dynamicOwnership)))
names++; goto error;
}
/* If there is no DAC driver, create a new one and add it to the stack if (virSecurityManagerStackAddNested(stack, nested))
* manager */ goto error;
if (names == NULL || *names == NULL) {
nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME, nested = NULL;
driver->user,
driver->group,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined,
driver->dynamicOwnership);
if (nested == NULL)
goto error;
if (virSecurityManagerStackAddNested(stack, nested))
goto error;
}
} }
driver->securityManager = mgr; driver->securityManager = mgr;
@ -338,6 +361,7 @@ qemuSecurityInit(struct qemud_driver *driver)
error: error:
VIR_ERROR(_("Failed to initialize security drivers")); VIR_ERROR(_("Failed to initialize security drivers"));
virSecurityManagerFree(mgr); virSecurityManagerFree(mgr);
virSecurityManagerFree(nested);
return -1; return -1;
} }