To keep original seclabel for files libvirt is touching we need a
single point where the original seclabels can be stored. Instead
of inventing a new one we can misuse virtlockd which already has
nearly all the infrastructure we need. As nice feature, it keeps
its internal state between virtlockd restarts. Again, it's
something we are going to need, as we don't want to lose the
original labels on the lock daemon restart.
In this commit two functions are introduced:
virLockManagerRememberSeclabel that takes three arguments:
path, model and seclabel
where @path is unique identifier for the file we are about to
label, @model and @seclabel then represents original seclabel.
virLockManagerRecallSeclabel then takes:
path, model, *seclabel
and returns number of references held on @path. If the return
value is zero, *seclabel contains the original label stored by
first call of RememberSeclabel(). If a positive value is
returned, other domains are still using the @path and the
original label shall not be restored.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 2 ++
src/locking/lock_driver.h | 41 +++++++++++++++++++++++++++++++++++++++++
src/locking/lock_manager.c | 26 ++++++++++++++++++++++++++
src/locking/lock_manager.h | 9 +++++++++
4 files changed, 78 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fdf4548..cdc476a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -887,7 +887,9 @@ virLockManagerPluginNew;
virLockManagerPluginRef;
virLockManagerPluginUnref;
virLockManagerPluginUsesState;
+virLockManagerRecallSeclabel;
virLockManagerRelease;
+virLockManagerRememberSeclabel;
# nodeinfo.h
diff --git a/src/locking/lock_driver.h b/src/locking/lock_driver.h
index a7d9782..a82f240 100644
--- a/src/locking/lock_driver.h
+++ b/src/locking/lock_driver.h
@@ -275,6 +275,44 @@ typedef int (*virLockDriverInquire)(virLockManagerPtr man,
unsigned int flags);
+/**
+ * virLockDriverRememberSeclabel:
+ * @manager: the lock manager context
+ * @path: which path we are remembering label for
+ * @model: security model (e.g. "DAC", "SELINUX", ...)
+ * @seclabel: security label to remember
+ *
+ * Remember security label for @path. Do that with reference
+ * counting, so only the first time something is actually
+ * remembered.
+ *
+ * Returns -1 on failure, or reference counter for @path.
+ */
+typedef int (*virLockDriverRememberSeclabel)(virLockManagerPtr man,
+ const char *path,
+ const char *model,
+ const char *seclabel);
+
+/**
+ * virLockDriverRecallSeclabel:
+ * @manager: the lock manager context
+ * @path: path to recall
+ * @model: security model (e.g. "DAC", "SELINUX", ...)
+ * @seclabel: previously stored seclabel
+ *
+ * Recall previously set seclabel. The @seclabel argument is
+ * required to be filled with original security label when zero
+ * is returned. It may, however, be filled if a positive value is
+ * returned too (depending on the lock driver used).
+ *
+ * Returns -1 on failure, or reference counter for @path (zero if
+ * @seclabel needs to be restored).
+ */
+typedef int (*virLockDriverRecallSeclabel)(virLockManagerPtr man,
+ const char *path,
+ const char *model,
+ char **seclabel);
+
struct _virLockManager {
virLockDriverPtr driver;
void *privateData;
@@ -303,6 +341,9 @@ struct _virLockDriver {
virLockDriverAcquire drvAcquire;
virLockDriverRelease drvRelease;
virLockDriverInquire drvInquire;
+
+ virLockDriverRememberSeclabel drvRemember;
+ virLockDriverRecallSeclabel drvRecall;
};
diff --git a/src/locking/lock_manager.c b/src/locking/lock_manager.c
index ec90d04..fb5cfe1 100644
--- a/src/locking/lock_manager.c
+++ b/src/locking/lock_manager.c
@@ -397,3 +397,29 @@ int virLockManagerFree(virLockManagerPtr lock)
return 0;
}
+
+int virLockManagerRememberSeclabel(virLockManagerPtr lock,
+ const char *path,
+ const char *model,
+ const char *seclabel)
+{
+ VIR_DEBUG("lock=%p path=%s model=%s seclabel=%s",
+ lock, path, model, seclabel);
+
+ CHECK_MANAGER(drvRemember, -1);
+
+ return lock->driver->drvRemember(lock, path, model, seclabel);
+}
+
+int virLockManagerRecallSeclabel(virLockManagerPtr lock,
+ const char *path,
+ const char *model,
+ char **seclabel)
+{
+ VIR_DEBUG("lock=%p path=%s model=%s seclabel=%p",
+ lock, path, model, seclabel);
+
+ CHECK_MANAGER(drvRecall, -1);
+
+ return lock->driver->drvRecall(lock, path, model, seclabel);
+}
diff --git a/src/locking/lock_manager.h b/src/locking/lock_manager.h
index 4189759..3fd5b9a 100644
--- a/src/locking/lock_manager.h
+++ b/src/locking/lock_manager.h
@@ -67,4 +67,13 @@ int virLockManagerInquire(virLockManagerPtr manager,
int virLockManagerFree(virLockManagerPtr manager);
+int virLockManagerRememberSeclabel(virLockManagerPtr lock,
+ const char *path,
+ const char *model,
+ const char *seclabel);
+int virLockManagerRecallSeclabel(virLockManagerPtr lock,
+ const char *path,
+ const char *model,
+ char **seclabel);
+
#endif /* __VIR_LOCK_MANAGER_H__ */
--
1.8.5.5