goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
if (transactionStarted &&
virSecurityManagerTransactionCommit(driver->securityManager,
- -1, priv->rememberOwner) < 0)
+ -1, priv->rememberOwner,
+ false) < 0)
VIR_WARN("Unable to run security manager transaction");
virSecurityManagerTransactionAbort(driver->securityManager);
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- -1, priv->rememberOwner) < 0)
+ -1, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- -1, priv->rememberOwner) < 0)
+ -1, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- pid, priv->rememberOwner) < 0)
+ pid, priv->rememberOwner,
+ false) < 0)
goto cleanup;
ret = 0;
goto cleanup;
if (virSecurityManagerTransactionCommit(driver->securityManager,
- vm->pid, false) < 0)
+ vm->pid, false, false) < 0)
goto cleanup;
ret = 0;
virSecurityDACChownItem **items;
size_t nItems;
bool lock;
+ bool lockMetadataException;
};
if (!(state = virSecurityManagerMetadataLock(list->manager,
list->sharedFilesystems,
- paths, npaths)))
+ paths, npaths,
+ list->lockMetadataException)))
return -1;
for (i = 0; i < list->nItems; i++) {
* @mgr: security manager
* @pid: domain's PID
* @lock: lock and unlock paths that are relabeled
+ * @lockMetadataException: don't lock metadata for lock files
*
* 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
static int
virSecurityDACTransactionCommit(virSecurityManager *mgr G_GNUC_UNUSED,
pid_t pid,
- bool lock)
+ bool lock,
+ bool lockMetadataException)
{
g_autoptr(virSecurityDACChownList) list = NULL;
int rc;
}
list->lock = lock;
+ list->lockMetadataException = lockMetadataException;
if (pid != -1) {
rc = virProcessRunInMountNamespace(pid,
if (!(state = virSecurityManagerMetadataLock(data->mgr,
data->sharedFilesystems,
- paths, G_N_ELEMENTS(paths))))
+ paths, G_N_ELEMENTS(paths),
+ false)))
return -1;
ret = virSecurityMoveRememberedLabel(SECURITY_DAC_NAME, data->src, data->dst);
char *const *sharedFilesystems);
typedef int (*virSecurityDriverTransactionCommit) (virSecurityManager *mgr,
pid_t pid,
- bool lock);
+ bool lock,
+ bool lockMetadataException);
typedef void (*virSecurityDriverTransactionAbort) (virSecurityManager *mgr);
typedef int (*virSecurityDomainSetDaemonSocketLabel)(virSecurityManager *mgr,
#include "virobject.h"
#include "virlog.h"
#include "virfile.h"
+#include "virstring.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
* @mgr: security manager
* @pid: domain's PID
* @lock: lock and unlock paths that are relabeled
+ * @lockMetadataException: don't lock metadata for lock files
*
* 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.
int
virSecurityManagerTransactionCommit(virSecurityManager *mgr,
pid_t pid,
- bool lock)
+ bool lock,
+ bool lockMetadataException)
{
VIR_LOCK_GUARD lockguard = virObjectLockGuard(mgr);
if (!mgr->drv->transactionCommit)
return 0;
- return mgr->drv->transactionCommit(mgr, pid, lock);
+ return mgr->drv->transactionCommit(mgr, pid, lock, lockMetadataException);
}
* @sharedFilesystems: list of filesystem to consider shared
* @paths: paths to lock
* @npaths: number of items in @paths array
+ * @lockMetadataException: don't lock metadata for lock files
*
* Lock passed @paths for metadata change. The returned state
* should be passed to virSecurityManagerMetadataUnlock.
virSecurityManagerMetadataLock(virSecurityManager *mgr G_GNUC_UNUSED,
char *const *sharedFilesystems,
const char **paths,
- size_t npaths)
+ size_t npaths,
+ bool lockMetadataException)
{
size_t i = 0;
size_t nfds = 0;
if (i != j)
continue;
+ /* Any attempt to lock a lock file is likely to go very
+ * poorly. This is a problem for TPM persistent storage,
+ * since on migration we need to relabel it while the swtpm
+ * process is still holding on to its lock file. As a way to
+ * resolve the conundrum, skip metadata locking for paths
+ * that look like they might be referring to lock files, if
+ * we have also been explicitly asked to make this exception */
+ if (lockMetadataException && virStringHasSuffix(p, ".lock"))
+ continue;
+
if (stat(p, &sb) < 0)
continue;
char *const *sharedFilesystems);
int virSecurityManagerTransactionCommit(virSecurityManager *mgr,
pid_t pid,
- bool lock);
+ bool lock,
+ bool lockMetadataException);
void virSecurityManagerTransactionAbort(virSecurityManager *mgr);
void *virSecurityManagerGetPrivateData(virSecurityManager *mgr);
virSecurityManagerMetadataLock(virSecurityManager *mgr,
char *const *sharedFilesystems,
const char **paths,
- size_t npaths);
+ size_t npaths,
+ bool lockMetadataException);
void
virSecurityManagerMetadataUnlock(virSecurityManager *mgr,
virSecuritySELinuxContextItem **items;
size_t nItems;
bool lock;
+ bool lockMetadataException;
};
#define SECURITY_SELINUX_VOID_DOI "0"
if (!(state = virSecurityManagerMetadataLock(list->manager,
list->sharedFilesystems,
- paths, npaths)))
+ paths, npaths,
+ list->lockMetadataException)))
goto cleanup;
for (i = 0; i < list->nItems; i++) {
* @mgr: security manager
* @pid: domain's PID
* @lock: lock and unlock paths that are relabeled
+ * @lockMetadataException: don't lock metadata for lock files
*
* 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
static int
virSecuritySELinuxTransactionCommit(virSecurityManager *mgr G_GNUC_UNUSED,
pid_t pid,
- bool lock)
+ bool lock,
+ bool lockMetadataException)
{
virSecuritySELinuxContextList *list;
int rc;
}
list->lock = lock;
+ list->lockMetadataException = lockMetadataException;
if (pid != -1) {
rc = virProcessRunInMountNamespace(pid,
if (!(state = virSecurityManagerMetadataLock(data->mgr,
data->sharedFilesystems,
- paths, G_N_ELEMENTS(paths))))
+ paths, G_N_ELEMENTS(paths),
+ false)))
return -1;
ret = virSecurityMoveRememberedLabel(SECURITY_SELINUX_NAME, data->src, data->dst);
static int
virSecurityStackTransactionCommit(virSecurityManager *mgr,
pid_t pid,
- bool lock)
+ bool lock,
+ bool lockMetadataException)
{
virSecurityStackData *priv = virSecurityManagerGetPrivateData(mgr);
virSecurityStackItem *item = priv->itemsHead;
for (; item; item = item->next) {
- if (virSecurityManagerTransactionCommit(item->securityManager, pid, lock) < 0)
+ if (virSecurityManagerTransactionCommit(item->securityManager, pid,
+ lock, lockMetadataException) < 0)
goto rollback;
}