From: "Richard W.M. Jones" <rjones@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