All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Cc: Shahar Frank <sfrank@redhat.com>, Uri Lublin <uril@redhat.com>
Subject: Re: [Qemu-devel] [PATCH] qemu: block.c: introducing "fmt:FMT:" prefix to image-filenames
Date: Wed, 07 Jan 2009 10:55:17 -0600	[thread overview]
Message-ID: <4964DE75.1010502@codemonkey.ws> (raw)
In-Reply-To: <49616228.4030608@redhat.com>

Uri Lublin wrote:
> Hello,
>
> This patch below can be considered as a version 2 of Shahar's "Qemu 
> image over raw devices" patch
> http://lists.gnu.org/archive/html/qemu-devel/2008-12/msg01083.html
>
> I think we've fixed the security flaw (that was discovered but not 
> introduced by Shahar's patch).

Doesn't the fmt= option to the block drivers achieve the same thing 
(except for not probing the backend formats)?

Regards,

Anthony Liguori

> Also I'm attaching an examples file with some debugging messages.
>
> Thanks,
>     Uri.
>
>
> ----------
> From: Uri Lublin <uril@redhat.com>
>
> The purpose of this prefix is to
> 1. Provide a way to know the backing file format without probing
>    it (setting the format upon creation time).
> 2. Enable using qcow2 format (and others) over host block devices.
>    (only if the user specifically asks for it).
>
> If no fmt:FMT: is provided we go back to probing.
>
> Based on a similar patch from Shahar Frank ("Qemu image over raw 
> devices").
> http://lists.gnu.org/archive/html/qemu-devel/2008-12/msg01083.html
>
> Also fixes a security flaw found by Daniel P. Berrange on the
> above thread which summarizes: "Autoprobing: just say no."
>
> Examples:
>
> backing file format is qcow2 (even though it's on a host block device)
> $ qemu-img create -b fmt:qcow2:/dev/loop0 -f qcow2 /tmp/uuu.qcow2
>
> force backing file format to raw (no probing)
> $ qemu-img create -f raw /tmp/image1.raw 10G
> $ qemu-img create -b fmt:raw:/tmp/image1.raw -f qcow2 /tmp/image1.qcow2
>
> Use together with other protocols, e.g. nbd
> $ qemu-nbd -v -n --snapshot -t -k /tmp/uuu.socket 
> fmt:qcow2:/tmp/images/uuu.qcow2 &
> $ qemu-img info nbd:unix:/tmp/uuu.socket
> $ qemu-system-x86_64 -snapshot -hda nbd:unix:/tmp/uuu.socket
>
> Or fat
> $ qemu-system-x86_64 -hda fmt:qcow2:/tmp/uuu.qcow2 -hdb 
> fat:floppy:/tmp/images
>
> Signed-off-by: Uri Lublin <uril@redhat.com>
> ---
>  qemu/block.c |   72 
> ++++++++++++++++++++++++++++++++++++++++++++++++---------
>  1 files changed, 60 insertions(+), 12 deletions(-)
>
> diff --git a/qemu/block.c b/qemu/block.c
> index dc744dd..5b4c517 100644
> --- a/qemu/block.c
> +++ b/qemu/block.c
> @@ -72,7 +72,7 @@ int path_is_absolute(const char *path)
>      if (*path == '/' || *path == '\\')
>          return 1;
>  #endif
> -    p = strchr(path, ':');
> +    p = strrchr(path, ':');
>      if (p)
>          p++;
>      else
> @@ -96,10 +96,23 @@ void path_combine(char *dest, int dest_size,
>
>      if (dest_size <= 0)
>          return;
> +
> +    /* copy "fmt:" prefix of filename if exists */
> +    p = strrchr(filename, ':');
> +    if (p) {
> +        len = p - filename + 1;
> +        if (dest_size <= len)
> +            return;
> +        strncpy(dest, filename, len);
> +        filename  += len;
> +        dest      += len;
> +        dest_size -= len;
> +    }
> +
>      if (path_is_absolute(filename)) {
>          pstrcpy(dest, dest_size, filename);
>      } else {
> -        p = strchr(base_path, ':');
> +        p = strrchr(base_path, ':');
>          if (p)
>              p++;
>          else
> @@ -227,30 +240,51 @@ static int is_windows_drive(const char *filename)
>  }
>  #endif
>
> +static const char *raw_filename(const char *filename)
> +{
> +    char *_filename;
> +
> +    _filename = strrchr(filename, ':');
> +    if (_filename)
> +        return _filename + 1;
> +    else
> +        return filename;
> +}
> +
>  static BlockDriver *find_protocol(const char *filename)
>  {
>      BlockDriver *drv1;
>      char protocol[128];
> -    int len;
> +    int len, is_fmt = 0;
>      const char *p;
>
> +    if (!strncmp(filename, "fmt:", 4)) {
> +        filename += 4;
> +        is_fmt = 1;
> +    }
> +
>  #ifdef _WIN32
>      if (is_windows_drive(filename) ||
>          is_windows_drive_prefix(filename))
> -        return &bdrv_raw;
> +        return NULL;
>  #endif
>      p = strchr(filename, ':');
>      if (!p)
> -        return &bdrv_raw;
> +        return NULL;
>      len = p - filename;
>      if (len > sizeof(protocol) - 1)
>          len = sizeof(protocol) - 1;
>      memcpy(protocol, filename, len);
>      protocol[len] = '\0';
>      for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
> -        if (drv1->protocol_name &&
> -            !strcmp(drv1->protocol_name, protocol))
> -            return drv1;
> +        if (is_fmt) {
> +            if (!strcmp(drv1->format_name, protocol))
> +                return drv1;
> +        } else {
> +            if (drv1->protocol_name &&
> +                !strcmp(drv1->protocol_name, protocol))
> +                return drv1;
> +        }
>      }
>      return NULL;
>  }
> @@ -268,6 +302,14 @@ static BlockDriver *find_image_format(const char 
> *filename)
>         recognized as a host CDROM */
>      if (strstart(filename, "/dev/cdrom", NULL))
>          return &bdrv_host_device;
> +
> +    drv = find_protocol(filename);
> +    if ((drv != NULL) && (drv->protocol_name == NULL))
> +        return drv;
> +
> +    if (drv == NULL)
> +        filename = raw_filename(filename);
> +
>  #ifdef _WIN32
>      if (is_windows_drive(filename))
>          return &bdrv_host_device;
> @@ -281,7 +323,6 @@ static BlockDriver *find_image_format(const char 
> *filename)
>      }
>  #endif
>
> -    drv = find_protocol(filename);
>      /* no need to test disk image formats for vvfat */
>      if (drv == &bdrv_vvfat)
>          return drv;
> @@ -371,8 +412,11 @@ int bdrv_open2(BlockDriverState *bs, const char 
> *filename, int flags,
>          if (is_protocol)
>              snprintf(backing_filename, sizeof(backing_filename),
>                       "%s", filename);
> -        else
> -            realpath(filename, backing_filename);
> +        else {
> +            const char *p;
> +            p = realpath(raw_filename(filename), backing_filename);
> +            path_combine(backing_filename, sizeof(backing_filename), 
> p, filename);
> +        }
>
>          if (bdrv_create(&bdrv_qcow2, tmp_filename,
>                          total_size, backing_filename, 0) < 0) {
> @@ -386,7 +430,7 @@ int bdrv_open2(BlockDriverState *bs, const char 
> *filename, int flags,
>      if (flags & BDRV_O_FILE) {
>          drv = find_protocol(filename);
>          if (!drv)
> -            return -ENOENT;
> +            drv = &bdrv_raw;
>      } else {
>          if (!drv) {
>              drv = find_image_format(filename);
> @@ -404,6 +448,10 @@ int bdrv_open2(BlockDriverState *bs, const char 
> *filename, int flags,
>          open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK);
>      else
>          open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
> +
> +    if (drv && !drv->protocol_name)
> +        filename = raw_filename(filename);
> +
>      ret = drv->bdrv_open(bs, filename, open_flags);
>      if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
>          ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);

  reply	other threads:[~2009-01-07 16:55 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-05  1:28 [Qemu-devel] [PATCH] qemu: block.c: introducing "fmt:FMT:" prefix to image-filenames Uri Lublin
2009-01-07 16:55 ` Anthony Liguori [this message]
2009-01-07 17:56   ` Uri Lublin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4964DE75.1010502@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=qemu-devel@nongnu.org \
    --cc=sfrank@redhat.com \
    --cc=uril@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.