提交 a2f0b97a 编写于 作者: M Michal Privoznik

virSecurityManagerTransactionCommit: Do metadata locking iff enabled in config

When metadata locking is enabled that means the security commit
processing will be run in a fork similar to how namespaces use fork()'s
for processing. This is done to ensure libvirt can properly and
synchronously modify the metadata to store the original owner data.

Since fork()'s (e.g. virFork) have been seen as a performance bottleneck
being able to disable them allows the admin to choose whether the
performance 'hit' is worth the extra 'security' of being able to
remember the original owner of a lock.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NJohn Ferlan <jferlan@redhat.com>
上级 7a44ffa6
...@@ -53,7 +53,8 @@ qemuSecuritySetAllLabel(virQEMUDriverPtr driver, ...@@ -53,7 +53,8 @@ qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
priv->chardevStdioLogd) < 0) priv->chardevStdioLogd) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -86,7 +87,8 @@ qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver, ...@@ -86,7 +87,8 @@ qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
priv->chardevStdioLogd); priv->chardevStdioLogd);
if (transactionStarted && if (transactionStarted &&
virSecurityManagerTransactionCommit(driver->securityManager, -1) < 0) virSecurityManagerTransactionCommit(driver->securityManager,
-1, priv->rememberOwner) < 0)
VIR_WARN("Unable to run security manager transaction"); VIR_WARN("Unable to run security manager transaction");
virSecurityManagerTransactionAbort(driver->securityManager); virSecurityManagerTransactionAbort(driver->securityManager);
...@@ -98,6 +100,7 @@ qemuSecuritySetDiskLabel(virQEMUDriverPtr driver, ...@@ -98,6 +100,7 @@ qemuSecuritySetDiskLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDiskDefPtr disk) virDomainDiskDefPtr disk)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -112,7 +115,8 @@ qemuSecuritySetDiskLabel(virQEMUDriverPtr driver, ...@@ -112,7 +115,8 @@ qemuSecuritySetDiskLabel(virQEMUDriverPtr driver,
disk) < 0) disk) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -127,6 +131,7 @@ qemuSecurityRestoreDiskLabel(virQEMUDriverPtr driver, ...@@ -127,6 +131,7 @@ qemuSecurityRestoreDiskLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDiskDefPtr disk) virDomainDiskDefPtr disk)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -141,7 +146,8 @@ qemuSecurityRestoreDiskLabel(virQEMUDriverPtr driver, ...@@ -141,7 +146,8 @@ qemuSecurityRestoreDiskLabel(virQEMUDriverPtr driver,
disk) < 0) disk) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -156,6 +162,7 @@ qemuSecuritySetImageLabel(virQEMUDriverPtr driver, ...@@ -156,6 +162,7 @@ qemuSecuritySetImageLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virStorageSourcePtr src) virStorageSourcePtr src)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -170,7 +177,8 @@ qemuSecuritySetImageLabel(virQEMUDriverPtr driver, ...@@ -170,7 +177,8 @@ qemuSecuritySetImageLabel(virQEMUDriverPtr driver,
src) < 0) src) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -185,6 +193,7 @@ qemuSecurityRestoreImageLabel(virQEMUDriverPtr driver, ...@@ -185,6 +193,7 @@ qemuSecurityRestoreImageLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virStorageSourcePtr src) virStorageSourcePtr src)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -199,7 +208,8 @@ qemuSecurityRestoreImageLabel(virQEMUDriverPtr driver, ...@@ -199,7 +208,8 @@ qemuSecurityRestoreImageLabel(virQEMUDriverPtr driver,
src) < 0) src) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -214,6 +224,7 @@ qemuSecuritySetHostdevLabel(virQEMUDriverPtr driver, ...@@ -214,6 +224,7 @@ qemuSecuritySetHostdevLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev) virDomainHostdevDefPtr hostdev)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -229,7 +240,8 @@ qemuSecuritySetHostdevLabel(virQEMUDriverPtr driver, ...@@ -229,7 +240,8 @@ qemuSecuritySetHostdevLabel(virQEMUDriverPtr driver,
NULL) < 0) NULL) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -244,6 +256,7 @@ qemuSecurityRestoreHostdevLabel(virQEMUDriverPtr driver, ...@@ -244,6 +256,7 @@ qemuSecurityRestoreHostdevLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev) virDomainHostdevDefPtr hostdev)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -259,7 +272,8 @@ qemuSecurityRestoreHostdevLabel(virQEMUDriverPtr driver, ...@@ -259,7 +272,8 @@ qemuSecurityRestoreHostdevLabel(virQEMUDriverPtr driver,
NULL) < 0) NULL) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -274,6 +288,7 @@ qemuSecuritySetMemoryLabel(virQEMUDriverPtr driver, ...@@ -274,6 +288,7 @@ qemuSecuritySetMemoryLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainMemoryDefPtr mem) virDomainMemoryDefPtr mem)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -288,7 +303,8 @@ qemuSecuritySetMemoryLabel(virQEMUDriverPtr driver, ...@@ -288,7 +303,8 @@ qemuSecuritySetMemoryLabel(virQEMUDriverPtr driver,
mem) < 0) mem) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -303,6 +319,7 @@ qemuSecurityRestoreMemoryLabel(virQEMUDriverPtr driver, ...@@ -303,6 +319,7 @@ qemuSecurityRestoreMemoryLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainMemoryDefPtr mem) virDomainMemoryDefPtr mem)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -317,7 +334,8 @@ qemuSecurityRestoreMemoryLabel(virQEMUDriverPtr driver, ...@@ -317,7 +334,8 @@ qemuSecurityRestoreMemoryLabel(virQEMUDriverPtr driver,
mem) < 0) mem) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -347,7 +365,8 @@ qemuSecuritySetInputLabel(virDomainObjPtr vm, ...@@ -347,7 +365,8 @@ qemuSecuritySetInputLabel(virDomainObjPtr vm,
input) < 0) input) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -377,7 +396,8 @@ qemuSecurityRestoreInputLabel(virDomainObjPtr vm, ...@@ -377,7 +396,8 @@ qemuSecurityRestoreInputLabel(virDomainObjPtr vm,
input) < 0) input) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -408,7 +428,8 @@ qemuSecuritySetChardevLabel(virQEMUDriverPtr driver, ...@@ -408,7 +428,8 @@ qemuSecuritySetChardevLabel(virQEMUDriverPtr driver,
priv->chardevStdioLogd) < 0) priv->chardevStdioLogd) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -439,7 +460,8 @@ qemuSecurityRestoreChardevLabel(virQEMUDriverPtr driver, ...@@ -439,7 +460,8 @@ qemuSecurityRestoreChardevLabel(virQEMUDriverPtr driver,
priv->chardevStdioLogd) < 0) priv->chardevStdioLogd) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -476,6 +498,7 @@ qemuSecurityStartTPMEmulator(virQEMUDriverPtr driver, ...@@ -476,6 +498,7 @@ qemuSecurityStartTPMEmulator(virQEMUDriverPtr driver,
int *exitstatus, int *exitstatus,
int *cmdret) int *cmdret)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1; int ret = -1;
bool transactionStarted = false; bool transactionStarted = false;
...@@ -489,7 +512,8 @@ qemuSecurityStartTPMEmulator(virQEMUDriverPtr driver, ...@@ -489,7 +512,8 @@ qemuSecurityStartTPMEmulator(virQEMUDriverPtr driver,
return -1; return -1;
} }
if (virSecurityManagerTransactionCommit(driver->securityManager, -1) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
-1, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
transactionStarted = false; transactionStarted = false;
...@@ -522,7 +546,8 @@ qemuSecurityStartTPMEmulator(virQEMUDriverPtr driver, ...@@ -522,7 +546,8 @@ qemuSecurityStartTPMEmulator(virQEMUDriverPtr driver,
virSecurityManagerRestoreTPMLabels(driver->securityManager, vm->def); virSecurityManagerRestoreTPMLabels(driver->securityManager, vm->def);
if (transactionStarted && if (transactionStarted &&
virSecurityManagerTransactionCommit(driver->securityManager, -1) < 0) virSecurityManagerTransactionCommit(driver->securityManager,
-1, priv->rememberOwner) < 0)
VIR_WARN("Unable to run security manager transaction"); VIR_WARN("Unable to run security manager transaction");
virSecurityManagerTransactionAbort(driver->securityManager); virSecurityManagerTransactionAbort(driver->securityManager);
...@@ -534,6 +559,7 @@ void ...@@ -534,6 +559,7 @@ void
qemuSecurityCleanupTPMEmulator(virQEMUDriverPtr driver, qemuSecurityCleanupTPMEmulator(virQEMUDriverPtr driver,
virDomainObjPtr vm) virDomainObjPtr vm)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
bool transactionStarted = false; bool transactionStarted = false;
if (virSecurityManagerTransactionStart(driver->securityManager) >= 0) if (virSecurityManagerTransactionStart(driver->securityManager) >= 0)
...@@ -542,7 +568,8 @@ qemuSecurityCleanupTPMEmulator(virQEMUDriverPtr driver, ...@@ -542,7 +568,8 @@ qemuSecurityCleanupTPMEmulator(virQEMUDriverPtr driver,
virSecurityManagerRestoreTPMLabels(driver->securityManager, vm->def); virSecurityManagerRestoreTPMLabels(driver->securityManager, vm->def);
if (transactionStarted && if (transactionStarted &&
virSecurityManagerTransactionCommit(driver->securityManager, -1) < 0) virSecurityManagerTransactionCommit(driver->securityManager,
-1, priv->rememberOwner) < 0)
VIR_WARN("Unable to run security manager transaction"); VIR_WARN("Unable to run security manager transaction");
virSecurityManagerTransactionAbort(driver->securityManager); virSecurityManagerTransactionAbort(driver->securityManager);
...@@ -555,6 +582,7 @@ qemuSecurityDomainSetPathLabel(virQEMUDriverPtr driver, ...@@ -555,6 +582,7 @@ qemuSecurityDomainSetPathLabel(virQEMUDriverPtr driver,
const char *path, const char *path,
bool allowSubtree) bool allowSubtree)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -570,7 +598,8 @@ qemuSecurityDomainSetPathLabel(virQEMUDriverPtr driver, ...@@ -570,7 +598,8 @@ qemuSecurityDomainSetPathLabel(virQEMUDriverPtr driver,
allowSubtree) < 0) allowSubtree) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -585,6 +614,7 @@ qemuSecuritySetSavedStateLabel(virQEMUDriverPtr driver, ...@@ -585,6 +614,7 @@ qemuSecuritySetSavedStateLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
const char *savefile) const char *savefile)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -599,7 +629,8 @@ qemuSecuritySetSavedStateLabel(virQEMUDriverPtr driver, ...@@ -599,7 +629,8 @@ qemuSecuritySetSavedStateLabel(virQEMUDriverPtr driver,
savefile) < 0) savefile) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
...@@ -614,6 +645,7 @@ qemuSecurityRestoreSavedStateLabel(virQEMUDriverPtr driver, ...@@ -614,6 +645,7 @@ qemuSecurityRestoreSavedStateLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
const char *savefile) const char *savefile)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData;
pid_t pid = -1; pid_t pid = -1;
int ret = -1; int ret = -1;
...@@ -628,7 +660,8 @@ qemuSecurityRestoreSavedStateLabel(virQEMUDriverPtr driver, ...@@ -628,7 +660,8 @@ qemuSecurityRestoreSavedStateLabel(virQEMUDriverPtr driver,
savefile) < 0) savefile) < 0)
goto cleanup; goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(driver->securityManager,
pid, priv->rememberOwner) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
......
...@@ -86,6 +86,7 @@ struct _virSecurityDACChownList { ...@@ -86,6 +86,7 @@ struct _virSecurityDACChownList {
virSecurityManagerPtr manager; virSecurityManagerPtr manager;
virSecurityDACChownItemPtr *items; virSecurityDACChownItemPtr *items;
size_t nItems; size_t nItems;
bool lock;
}; };
...@@ -210,21 +211,23 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED, ...@@ -210,21 +211,23 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED,
int rv = 0; int rv = 0;
int ret = -1; int ret = -1;
if (VIR_ALLOC_N(paths, list->nItems) < 0) if (list->lock) {
return -1; if (VIR_ALLOC_N(paths, list->nItems) < 0)
return -1;
for (i = 0; i < list->nItems; i++) { for (i = 0; i < list->nItems; i++) {
const char *p = list->items[i]->path; const char *p = list->items[i]->path;
if (!p || if (!p ||
virFileIsDir(p)) virFileIsDir(p))
continue; continue;
VIR_APPEND_ELEMENT_COPY_INPLACE(paths, npaths, p); VIR_APPEND_ELEMENT_COPY_INPLACE(paths, npaths, p);
} }
if (virSecurityManagerMetadataLock(list->manager, paths, npaths) < 0) if (virSecurityManagerMetadataLock(list->manager, paths, npaths) < 0)
goto cleanup; goto cleanup;
}
for (i = 0; i < list->nItems; i++) { for (i = 0; i < list->nItems; i++) {
virSecurityDACChownItemPtr item = list->items[i]; virSecurityDACChownItemPtr item = list->items[i];
...@@ -246,7 +249,8 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED, ...@@ -246,7 +249,8 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED,
break; break;
} }
if (virSecurityManagerMetadataUnlock(list->manager, paths, npaths) < 0) if (list->lock &&
virSecurityManagerMetadataUnlock(list->manager, paths, npaths) < 0)
goto cleanup; goto cleanup;
if (rv < 0) if (rv < 0)
...@@ -529,11 +533,15 @@ virSecurityDACTransactionStart(virSecurityManagerPtr mgr) ...@@ -529,11 +533,15 @@ virSecurityDACTransactionStart(virSecurityManagerPtr mgr)
* virSecurityDACTransactionCommit: * virSecurityDACTransactionCommit:
* @mgr: security manager * @mgr: security manager
* @pid: domain's PID * @pid: domain's PID
* @lock: lock and unlock paths that are relabeled
* *
* If @pid is not -1 then enter the @pid namespace (usually @pid refers * If @pid is not -1 then enter the @pid namespace (usually @pid refers
* to a domain) and perform all the chown()-s on the list. If @pid is -1 * to a domain) and perform all the chown()-s on the list. If @pid is -1
* then the transaction is performed in the namespace of the caller. * then the transaction is performed in the namespace of the caller.
* *
* If @lock is true then all the paths that transaction would
* touch are locked before and unlocked after it is done so.
*
* Note that the transaction is also freed, therefore new one has to be * Note that the transaction is also freed, therefore new one has to be
* started after successful return from this function. Also it is * started after successful return from this function. Also it is
* considered as error if there's no transaction set and this function * considered as error if there's no transaction set and this function
...@@ -544,9 +552,11 @@ virSecurityDACTransactionStart(virSecurityManagerPtr mgr) ...@@ -544,9 +552,11 @@ virSecurityDACTransactionStart(virSecurityManagerPtr mgr)
*/ */
static int static int
virSecurityDACTransactionCommit(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virSecurityDACTransactionCommit(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
pid_t pid) pid_t pid,
bool lock)
{ {
virSecurityDACChownListPtr list; virSecurityDACChownListPtr list;
int rc;
int ret = -1; int ret = -1;
list = virThreadLocalGet(&chownList); list = virThreadLocalGet(&chownList);
...@@ -562,12 +572,20 @@ virSecurityDACTransactionCommit(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, ...@@ -562,12 +572,20 @@ virSecurityDACTransactionCommit(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
goto cleanup; goto cleanup;
} }
if ((pid == -1 && list->lock = lock;
virSecurityDACTransactionRun(pid, list) < 0) ||
(pid != -1 && if (pid == -1) {
virProcessRunInMountNamespace(pid, if (lock)
virSecurityDACTransactionRun, rc = virProcessRunInFork(virSecurityDACTransactionRun, list);
list) < 0)) else
rc = virSecurityDACTransactionRun(pid, list);
} else {
rc = virProcessRunInMountNamespace(pid,
virSecurityDACTransactionRun,
list);
}
if (rc < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
......
...@@ -53,7 +53,8 @@ typedef int (*virSecurityDriverPreFork) (virSecurityManagerPtr mgr); ...@@ -53,7 +53,8 @@ typedef int (*virSecurityDriverPreFork) (virSecurityManagerPtr mgr);
typedef int (*virSecurityDriverTransactionStart) (virSecurityManagerPtr mgr); typedef int (*virSecurityDriverTransactionStart) (virSecurityManagerPtr mgr);
typedef int (*virSecurityDriverTransactionCommit) (virSecurityManagerPtr mgr, typedef int (*virSecurityDriverTransactionCommit) (virSecurityManagerPtr mgr,
pid_t pid); pid_t pid,
bool lock);
typedef void (*virSecurityDriverTransactionAbort) (virSecurityManagerPtr mgr); typedef void (*virSecurityDriverTransactionAbort) (virSecurityManagerPtr mgr);
typedef int (*virSecurityDomainRestoreDiskLabel) (virSecurityManagerPtr mgr, typedef int (*virSecurityDomainRestoreDiskLabel) (virSecurityManagerPtr mgr,
......
...@@ -299,12 +299,16 @@ virSecurityManagerTransactionStart(virSecurityManagerPtr mgr) ...@@ -299,12 +299,16 @@ virSecurityManagerTransactionStart(virSecurityManagerPtr mgr)
* virSecurityManagerTransactionCommit: * virSecurityManagerTransactionCommit:
* @mgr: security manager * @mgr: security manager
* @pid: domain's PID * @pid: domain's PID
* @lock: lock and unlock paths that are relabeled
* *
* If @pid is not -1 then enter the @pid namespace (usually @pid refers * If @pid is not -1 then enter the @pid namespace (usually @pid refers
* to a domain) and perform all the operations on the transaction list. * to a domain) and perform all the operations on the transaction list.
* If @pid is -1 then the transaction is performed in the namespace of * If @pid is -1 then the transaction is performed in the namespace of
* the caller. * the caller.
* *
* If @lock is true then all the paths that transaction would
* touch are locked before and unlocked after it is done so.
*
* Note that the transaction is also freed, therefore new one has to be * Note that the transaction is also freed, therefore new one has to be
* started after successful return from this function. Also it is * started after successful return from this function. Also it is
* considered as error if there's no transaction set and this function * considered as error if there's no transaction set and this function
...@@ -315,13 +319,14 @@ virSecurityManagerTransactionStart(virSecurityManagerPtr mgr) ...@@ -315,13 +319,14 @@ virSecurityManagerTransactionStart(virSecurityManagerPtr mgr)
*/ */
int int
virSecurityManagerTransactionCommit(virSecurityManagerPtr mgr, virSecurityManagerTransactionCommit(virSecurityManagerPtr mgr,
pid_t pid) pid_t pid,
bool lock)
{ {
int ret = 0; int ret = 0;
virObjectLock(mgr); virObjectLock(mgr);
if (mgr->drv->transactionCommit) if (mgr->drv->transactionCommit)
ret = mgr->drv->transactionCommit(mgr, pid); ret = mgr->drv->transactionCommit(mgr, pid, lock);
virObjectUnlock(mgr); virObjectUnlock(mgr);
return ret; return ret;
} }
......
...@@ -79,7 +79,8 @@ void virSecurityManagerPostFork(virSecurityManagerPtr mgr); ...@@ -79,7 +79,8 @@ void virSecurityManagerPostFork(virSecurityManagerPtr mgr);
int virSecurityManagerTransactionStart(virSecurityManagerPtr mgr); int virSecurityManagerTransactionStart(virSecurityManagerPtr mgr);
int virSecurityManagerTransactionCommit(virSecurityManagerPtr mgr, int virSecurityManagerTransactionCommit(virSecurityManagerPtr mgr,
pid_t pid); pid_t pid,
bool lock);
void virSecurityManagerTransactionAbort(virSecurityManagerPtr mgr); void virSecurityManagerTransactionAbort(virSecurityManagerPtr mgr);
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr); void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr);
......
...@@ -93,6 +93,7 @@ struct _virSecuritySELinuxContextList { ...@@ -93,6 +93,7 @@ struct _virSecuritySELinuxContextList {
virSecurityManagerPtr manager; virSecurityManagerPtr manager;
virSecuritySELinuxContextItemPtr *items; virSecuritySELinuxContextItemPtr *items;
size_t nItems; size_t nItems;
bool lock;
}; };
#define SECURITY_SELINUX_VOID_DOI "0" #define SECURITY_SELINUX_VOID_DOI "0"
...@@ -221,20 +222,22 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_UNUSED, ...@@ -221,20 +222,22 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_UNUSED,
int rv; int rv;
int ret = -1; int ret = -1;
if (VIR_ALLOC_N(paths, list->nItems) < 0) if (list->lock) {
return -1; if (VIR_ALLOC_N(paths, list->nItems) < 0)
return -1;
for (i = 0; i < list->nItems; i++) { for (i = 0; i < list->nItems; i++) {
const char *p = list->items[i]->path; const char *p = list->items[i]->path;
if (virFileIsDir(p)) if (virFileIsDir(p))
continue; continue;
VIR_APPEND_ELEMENT_COPY_INPLACE(paths, npaths, p); VIR_APPEND_ELEMENT_COPY_INPLACE(paths, npaths, p);
} }
if (virSecurityManagerMetadataLock(list->manager, paths, npaths) < 0) if (virSecurityManagerMetadataLock(list->manager, paths, npaths) < 0)
goto cleanup; goto cleanup;
}
rv = 0; rv = 0;
for (i = 0; i < list->nItems; i++) { for (i = 0; i < list->nItems; i++) {
...@@ -250,7 +253,8 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_UNUSED, ...@@ -250,7 +253,8 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_UNUSED,
} }
} }
if (virSecurityManagerMetadataUnlock(list->manager, paths, npaths) < 0) if (list->lock &&
virSecurityManagerMetadataUnlock(list->manager, paths, npaths) < 0)
goto cleanup; goto cleanup;
if (rv < 0) if (rv < 0)
...@@ -1072,12 +1076,16 @@ virSecuritySELinuxTransactionStart(virSecurityManagerPtr mgr) ...@@ -1072,12 +1076,16 @@ virSecuritySELinuxTransactionStart(virSecurityManagerPtr mgr)
* virSecuritySELinuxTransactionCommit: * virSecuritySELinuxTransactionCommit:
* @mgr: security manager * @mgr: security manager
* @pid: domain's PID * @pid: domain's PID
* @lock: lock and unlock paths that are relabeled
* *
* If @pis is not -1 then enter the @pid namespace (usually @pid refers * If @pis is not -1 then enter the @pid namespace (usually @pid refers
* to a domain) and perform all the sefilecon()-s on the list. If @pid * to a domain) and perform all the sefilecon()-s on the list. If @pid
* is -1 then the transaction is performed in the namespace of the * is -1 then the transaction is performed in the namespace of the
* caller. * caller.
* *
* If @lock is true then all the paths that transaction would
* touch are locked before and unlocked after it is done so.
*
* Note that the transaction is also freed, therefore new one has to be * Note that the transaction is also freed, therefore new one has to be
* started after successful return from this function. Also it is * started after successful return from this function. Also it is
* considered as error if there's no transaction set and this function * considered as error if there's no transaction set and this function
...@@ -1088,9 +1096,11 @@ virSecuritySELinuxTransactionStart(virSecurityManagerPtr mgr) ...@@ -1088,9 +1096,11 @@ virSecuritySELinuxTransactionStart(virSecurityManagerPtr mgr)
*/ */
static int static int
virSecuritySELinuxTransactionCommit(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virSecuritySELinuxTransactionCommit(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
pid_t pid) pid_t pid,
bool lock)
{ {
virSecuritySELinuxContextListPtr list; virSecuritySELinuxContextListPtr list;
int rc;
int ret = -1; int ret = -1;
list = virThreadLocalGet(&contextList); list = virThreadLocalGet(&contextList);
...@@ -1106,12 +1116,20 @@ virSecuritySELinuxTransactionCommit(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, ...@@ -1106,12 +1116,20 @@ virSecuritySELinuxTransactionCommit(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
goto cleanup; goto cleanup;
} }
if ((pid == -1 && list->lock = lock;
virSecuritySELinuxTransactionRun(pid, list) < 0) ||
(pid != -1 && if (pid == -1) {
virProcessRunInMountNamespace(pid, if (lock)
virSecuritySELinuxTransactionRun, rc = virProcessRunInFork(virSecuritySELinuxTransactionRun, list);
list) < 0)) else
rc = virSecuritySELinuxTransactionRun(pid, list);
} else {
rc = virProcessRunInMountNamespace(pid,
virSecuritySELinuxTransactionRun,
list);
}
if (rc < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
......
...@@ -156,14 +156,15 @@ virSecurityStackTransactionStart(virSecurityManagerPtr mgr) ...@@ -156,14 +156,15 @@ virSecurityStackTransactionStart(virSecurityManagerPtr mgr)
static int static int
virSecurityStackTransactionCommit(virSecurityManagerPtr mgr, virSecurityStackTransactionCommit(virSecurityManagerPtr mgr,
pid_t pid) pid_t pid,
bool lock)
{ {
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr); virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
virSecurityStackItemPtr item = priv->itemsHead; virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0; int rc = 0;
for (; item; item = item->next) { for (; item; item = item->next) {
if (virSecurityManagerTransactionCommit(item->securityManager, pid) < 0) if (virSecurityManagerTransactionCommit(item->securityManager, pid, lock) < 0)
rc = -1; rc = -1;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册