int qemuSecuritySetAllLabel(virQEMUDriverPtr driver, virDomainObjPtr vm, const char *stdin_path) { struct qemuSecuritySetRestoreAllLabelData data; memset(&data, 0, sizeof(data)); data.set = true; data.driver = driver; data.vm = vm; data.stdin_path = stdin_path; if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) { if (virSecurityManagerPreFork(driver->securityManager) < 0) return -1; if (virProcessRunInMountNamespace(vm->pid, qemuSecuritySetRestoreAllLabelHelper, &data) < 0) { virSecurityManagerPostFork(driver->securityManager); return -1; } virSecurityManagerPostFork(driver->securityManager); } else { if (virSecurityManagerSetAllLabel(driver->securityManager, vm->def, stdin_path) < 0) return -1; } return 0; }
void qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver, virDomainObjPtr vm, bool migrated) { struct qemuSecuritySetRestoreAllLabelData data; memset(&data, 0, sizeof(data)); data.driver = driver; data.vm = vm; data.migrated = migrated; if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) { if (virSecurityManagerPreFork(driver->securityManager) < 0) return; virProcessRunInMountNamespace(vm->pid, qemuSecuritySetRestoreAllLabelHelper, &data); virSecurityManagerPostFork(driver->securityManager); } else { virSecurityManagerRestoreAllLabel(driver->securityManager, vm->def, migrated); } }
static int qemuSecuritySetRestoreAllLabelHelper(pid_t pid, void *opaque) { struct qemuSecuritySetRestoreAllLabelData *data = opaque; virSecurityManagerPostFork(data->driver->securityManager); if (data->set) { VIR_DEBUG("Setting up security labels inside namespace pid=%lld", (long long) pid); if (virSecurityManagerSetAllLabel(data->driver->securityManager, data->vm->def, data->stdin_path) < 0) return -1; } else { VIR_DEBUG("Restoring security labels inside namespace pid=%lld", (long long) pid); if (virSecurityManagerRestoreAllLabel(data->driver->securityManager, data->vm->def, data->migrated) < 0) return -1; } return 0; }
/* * qemuSecurityStartTPMEmulator: * * @driver: the QEMU driver * @def: the domain definition * @cmd: the command to run * @uid: the uid to run the emulator * @gid: the gid to run the emulator * @existstatus: pointer to int returning exit status of process * @cmdret: pointer to int returning result of virCommandRun * * Start the TPM emulator with approriate labels. Apply security * labels to files first. * This function returns -1 on security setup error, 0 if all the * setup was done properly. In case the virCommand failed to run * 0 is returned but cmdret is set appropriately with the process * exitstatus also set. */ int qemuSecurityStartTPMEmulator(virQEMUDriverPtr driver, virDomainDefPtr def, virCommandPtr cmd, uid_t uid, gid_t gid, int *exitstatus, int *cmdret) { int ret = -1; bool transactionStarted = false; if (virSecurityManagerTransactionStart(driver->securityManager) < 0) return -1; transactionStarted = true; if (virSecurityManagerSetTPMLabels(driver->securityManager, def) < 0) { virSecurityManagerTransactionAbort(driver->securityManager); return -1; } if (virSecurityManagerTransactionCommit(driver->securityManager, -1) < 0) goto cleanup; transactionStarted = false; if (virSecurityManagerSetChildProcessLabel(driver->securityManager, def, cmd) < 0) goto cleanup; if (virSecurityManagerPreFork(driver->securityManager) < 0) goto cleanup; ret = 0; /* make sure we run this with the appropriate user */ virCommandSetUID(cmd, uid); virCommandSetGID(cmd, gid); *cmdret = virCommandRun(cmd, exitstatus); virSecurityManagerPostFork(driver->securityManager); if (*cmdret < 0) goto cleanup; return 0; cleanup: if (!transactionStarted && virSecurityManagerTransactionStart(driver->securityManager) >= 0) transactionStarted = true; virSecurityManagerRestoreTPMLabels(driver->securityManager, def); if (transactionStarted && virSecurityManagerTransactionCommit(driver->securityManager, -1) < 0) VIR_WARN("Unable to run security manager transaction"); virSecurityManagerTransactionAbort(driver->securityManager); return ret; }