[Libguestfs] [PATCH v2 3/5] launch: libvirt: Allow the SELinux label to be set on qcow2 overlay files.

Matthew Booth mbooth at redhat.com
Fri Mar 1 10:22:14 UTC 2013


On Thu, 2013-02-28 at 16:02 +0000, Richard W.M. Jones wrote:
> From: "Richard W.M. Jones" <rjones at 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
> imagelabel specified by guestfs_internal_set_libvirt_selinux_label.
> 
> The above only applies to the libvirt attach-method.
> ---
>  src/launch-libvirt.c | 28 ++++++++++++++++++++--------
>  1 file changed, 20 insertions(+), 8 deletions(-)
> 
> diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c
> index 318847a..b692fd6 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, const char *selinux_imagelabel);
> +static int make_qcow2_overlay_for_drive (guestfs_h *g, struct drive *drv, const char *selinux_imagelabel);
>  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", NULL);
>      if (!params.appliance_overlay)
>        goto cleanup;
>    }

I remain convinced that this is going to bite us at some point in the
future. The fact that it works now is essentially a quirk of the default
SELinux policy. I still don't understand at all how the confined guest
can access the underlying appliance image, which libvirt presumably
doesn't relabel.

Given that it does currently work I don't think we should hold up these
patches for a solution. However, I think we should document the problem
as we currently understand it somewhere in the source tree, perhaps the
TODO file.

>  
>    ITER_DRIVES (g, i, drv) {
> -    if (make_qcow2_overlay_for_drive (g, drv) == -1)
> +    if (make_qcow2_overlay_for_drive (g, drv, g->virt_selinux_imagelabel) == -1)
>        goto cleanup;
>    }
>  
> @@ -1353,7 +1353,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,
> +                    const char *selinux_imagelabel)
>  {
>    char *tmpfile = NULL;
>    CLEANUP_CMD_CLOSE struct command *cmd = guestfs___new_command (g);
> @@ -1384,6 +1385,15 @@ make_qcow2_overlay (guestfs_h *g, const char *path, const char *format)
>      goto error;
>    }
>  
> +#if HAVE_LIBSELINUX
> +  if (selinux_imagelabel) {
> +    debug (g, "setting SELinux label on %s to %s",
> +           tmpfile, selinux_imagelabel);
> +    if (setfilecon (tmpfile, (security_context_t) selinux_imagelabel) == -1)
> +      selinux_warning (g, __func__, "setfilecon", tmpfile);
> +  }
> +#endif
> +
>    return tmpfile;               /* caller frees */
>  
>   error:
> @@ -1393,7 +1403,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,
> +                              const char *selinux_imagelabel)
>  {
>    char *path;
>    struct drive_libvirt *drv_priv;
> @@ -1417,7 +1428,8 @@ 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_imagelabel);
>      free (path);
>      if (!drv_priv->path)
>        return -1;
> @@ -1534,7 +1546,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, g->virt_selinux_imagelabel) == -1)
>      return -1;
>  
>    /* Create the XML for the new disk. */

I'd prefer documentation of the problem of SELinux and the appliance
image, but otherwise ACK.

Matt




More information about the Libguestfs mailing list