From: "Richard W.M. Jones" <rjones(a)redhat.com>
When a disk is opened readonly, the libvirt attach-method privately
creates a qcow2 overlay on top.
This commit lets that overlay get an SELinux label, and sets it to the
label specified by guestfs_internal_set_libvirt_selinux_label.
We have to adjust the SELinux label (which is a process label) to make
it applicable to images. We do this by changing the role from
'system_r' to 'object_r', and the type from 'svirt_t' to
'svirt_image_t'.
The above only applies to the libvirt attach-method.
---
src/launch-libvirt.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c
index 45950e2..5c14155 100644
--- a/src/launch-libvirt.c
+++ b/src/launch-libvirt.c
@@ -133,8 +133,8 @@ static int is_custom_qemu (guestfs_h *g);
static int is_blk (const char *path);
static int random_chars (char *ret, size_t len);
static void ignore_errors (void *ignore, virErrorPtr ignore2);
-static char *make_qcow2_overlay (guestfs_h *g, const char *path, const char *format);
-static int make_qcow2_overlay_for_drive (guestfs_h *g, struct drive *drv);
+static char *make_qcow2_overlay (guestfs_h *g, const char *path, const char *format, bool
selinux_label);
+static int make_qcow2_overlay_for_drive (guestfs_h *g, struct drive *drv, bool
selinux_label);
static void drive_free_priv (void *);
static void set_socket_create_context (guestfs_h *g);
static void clear_socket_create_context (guestfs_h *g);
@@ -235,13 +235,13 @@ launch_libvirt (guestfs_h *g, const char *libvirt_uri)
* Note that appliance can be NULL if using the old-style appliance.
*/
if (appliance) {
- params.appliance_overlay = make_qcow2_overlay (g, appliance, "raw");
+ params.appliance_overlay = make_qcow2_overlay (g, appliance, "raw",
false);
if (!params.appliance_overlay)
goto cleanup;
}
ITER_DRIVES (g, i, drv) {
- if (make_qcow2_overlay_for_drive (g, drv) == -1)
+ if (make_qcow2_overlay_for_drive (g, drv, true) == -1)
goto cleanup;
}
@@ -1350,7 +1350,8 @@ ignore_errors (void *ignore, virErrorPtr ignore2)
/* Create a temporary qcow2 overlay on top of 'path'. */
static char *
-make_qcow2_overlay (guestfs_h *g, const char *path, const char *format)
+make_qcow2_overlay (guestfs_h *g, const char *path, const char *format,
+ bool selinux_label)
{
char *tmpfile = NULL;
CLEANUP_CMD_CLOSE struct command *cmd = guestfs___new_command (g);
@@ -1381,6 +1382,15 @@ make_qcow2_overlay (guestfs_h *g, const char *path, const char
*format)
goto error;
}
+#if HAVE_LIBSELINUX
+ if (selinux_label && g->virt_selinux_imagelabel) {
+ debug (g, "setting SELinux label on %s to %s",
+ tmpfile, g->virt_selinux_imagelabel);
+ if (setfilecon (tmpfile, g->virt_selinux_imagelabel) == -1)
+ selinux_warning (g, __func__, "setfilecon", tmpfile);
+ }
+#endif
+
return tmpfile; /* caller frees */
error:
@@ -1390,7 +1400,8 @@ make_qcow2_overlay (guestfs_h *g, const char *path, const char
*format)
}
static int
-make_qcow2_overlay_for_drive (guestfs_h *g, struct drive *drv)
+make_qcow2_overlay_for_drive (guestfs_h *g, struct drive *drv,
+ bool selinux_label)
{
char *path;
struct drive_libvirt *drv_priv;
@@ -1414,7 +1425,7 @@ make_qcow2_overlay_for_drive (guestfs_h *g, struct drive *drv)
drv_priv->format = drv->format ? safe_strdup (g, drv->format) : NULL;
}
else {
- drv_priv->path = make_qcow2_overlay (g, path, drv->format);
+ drv_priv->path = make_qcow2_overlay (g, path, drv->format, selinux_label);
free (path);
if (!drv_priv->path)
return -1;
@@ -1531,7 +1542,7 @@ hot_add_drive_libvirt (guestfs_h *g, struct drive *drv, size_t
drv_index)
/* Create overlay for read-only drive. This works around lack of
* support for <transient/> disks in libvirt.
*/
- if (make_qcow2_overlay_for_drive (g, drv) == -1)
+ if (make_qcow2_overlay_for_drive (g, drv, true) == -1)
return -1;
/* Create the XML for the new disk. */
--
1.8.1.2