[Libguestfs] [nbdkit PATCH 1/2] filters: Add .export_description wrappers

Richard W.M. Jones rjones at redhat.com
Tue Sep 1 14:30:20 UTC 2020


On Thu, Aug 27, 2020 at 05:03:45PM -0500, Eric Blake wrote:
> When extracting an obvious subset of a larger container (ext2, gzip,
> partition, tar, xz), it's fairly easy to add a nice updated
> description for what the client is seeing.  Not all clients request
> the description, but if you are worried about this leaking too much
> information, it can be silenced with nbdkit-exportname-filter.

No?

The trouble with this is it leaks configuration information of the
server which most users of nbdkit would not really be aware of.  NBD
protocol export descriptions are a pretty obscure thing - even I would
have to look at the qemu-nbd manual to work out how to read them from
an NBD server.

Also I don't really see the benefit of this to anyone.  The server
admin already knows this, and the client doesn't care unless they're
looking for a way to attack the server.

> And maybe this is an excuse for adding nbdkit_[v]printf_intern()...

This could well be useful.

Rich.

>  filters/ext2/ext2.c           | 54 ++++++++++++++++++++++----------
>  filters/gzip/gzip.c           | 40 ++++++++++++++++--------
>  filters/partition/partition.c | 58 +++++++++++++++++++++++++----------
>  filters/tar/tar.c             | 48 +++++++++++++++++++----------
>  filters/xz/xz.c               | 43 ++++++++++++++++++--------
>  5 files changed, 168 insertions(+), 75 deletions(-)
> 
> diff --git a/filters/ext2/ext2.c b/filters/ext2/ext2.c
> index 75ac2c4c..7ad4a005 100644
> --- a/filters/ext2/ext2.c
> +++ b/filters/ext2/ext2.c
> @@ -294,6 +294,25 @@ static int ext2_thread_model (void)
>    return NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS;
>  }
> 
> +/* Description. */
> +static const char *
> +ext2_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
> +                         void *handle)
> +{
> +  struct handle *h = handle;
> +  const char *fname = file ?: h->exportname;
> +  const char *slash = fname[0] == '/' ? "" : "/";
> +  const char *base = next_ops->export_description (nxdata);
> +  CLEANUP_FREE char *desc = NULL;
> +
> +  if (base)
> +    asprintf (&desc, "embedded '%s%s' from within ext2 image: %s",
> +              slash, fname, base);
> +  else
> +    asprintf (&desc, "embedded '%s%s' from within ext2 image", slash, fname);
> +  return nbdkit_strdup_intern (desc);
> +}
> +
>  /* Get the disk size. */
>  static int64_t
>  ext2_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
> @@ -412,23 +431,24 @@ ext2_flush (struct nbdkit_next_ops *next_ops, void *nxdata,
>   */
> 
>  static struct nbdkit_filter filter = {
> -  .name              = "ext2",
> -  .longname          = "nbdkit ext2 filter",
> -  .load              = ext2_load,
> -  .unload            = ext2_unload,
> -  .config            = ext2_config,
> -  .config_complete   = ext2_config_complete,
> -  .config_help       = ext2_config_help,
> -  .thread_model      = ext2_thread_model,
> -  .open              = ext2_open,
> -  .prepare           = ext2_prepare,
> -  .close             = ext2_close,
> -  .can_fua           = ext2_can_fua,
> -  .can_cache         = ext2_can_cache,
> -  .get_size          = ext2_get_size,
> -  .pread             = ext2_pread,
> -  .pwrite            = ext2_pwrite,
> -  .flush             = ext2_flush,
> +  .name               = "ext2",
> +  .longname           = "nbdkit ext2 filter",
> +  .load               = ext2_load,
> +  .unload             = ext2_unload,
> +  .config             = ext2_config,
> +  .config_complete    = ext2_config_complete,
> +  .config_help        = ext2_config_help,
> +  .thread_model       = ext2_thread_model,
> +  .open               = ext2_open,
> +  .prepare            = ext2_prepare,
> +  .close              = ext2_close,
> +  .can_fua            = ext2_can_fua,
> +  .can_cache          = ext2_can_cache,
> +  .export_description = ext2_export_description,
> +  .get_size           = ext2_get_size,
> +  .pread              = ext2_pread,
> +  .pwrite             = ext2_pwrite,
> +  .flush              = ext2_flush,
>  };
> 
>  NBDKIT_REGISTER_FILTER(filter)
> diff --git a/filters/gzip/gzip.c b/filters/gzip/gzip.c
> index 929260bf..833ea937 100644
> --- a/filters/gzip/gzip.c
> +++ b/filters/gzip/gzip.c
> @@ -287,6 +287,21 @@ gzip_can_cache (struct nbdkit_next_ops *next_ops, void *nxdata,
>    return NBDKIT_CACHE_EMULATE;
>  }
> 
> +/* Description. */
> +static const char *
> +gzip_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
> +                         void *handle)
> +{
> +  const char *base = next_ops->export_description (nxdata);
> +  CLEANUP_FREE char *desc = NULL;
> +
> +  if (base) {
> +    asprintf (&desc, "expansion of gzip-compressed image: %s", base);
> +    return nbdkit_strdup_intern (desc);
> +  }
> +  return "expansion of gzip-compressed image";
> +}
> +
>  /* Get the file size. */
>  static int64_t
>  gzip_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
> @@ -339,18 +354,19 @@ gzip_pread (struct nbdkit_next_ops *next_ops, void *nxdata,
>  }
> 
>  static struct nbdkit_filter filter = {
> -  .name              = "gzip",
> -  .longname          = "nbdkit gzip filter",
> -  .unload            = gzip_unload,
> -  .thread_model      = gzip_thread_model,
> -  .open              = gzip_open,
> -  .prepare           = gzip_prepare,
> -  .can_write         = gzip_can_write,
> -  .can_extents       = gzip_can_extents,
> -  .can_cache         = gzip_can_cache,
> -  .prepare           = gzip_prepare,
> -  .get_size          = gzip_get_size,
> -  .pread             = gzip_pread,
> +  .name               = "gzip",
> +  .longname           = "nbdkit gzip filter",
> +  .unload             = gzip_unload,
> +  .thread_model       = gzip_thread_model,
> +  .open               = gzip_open,
> +  .prepare            = gzip_prepare,
> +  .can_write          = gzip_can_write,
> +  .can_extents        = gzip_can_extents,
> +  .can_cache          = gzip_can_cache,
> +  .prepare            = gzip_prepare,
> +  .export_description = gzip_export_description,
> +  .get_size           = gzip_get_size,
> +  .pread              = gzip_pread,
>  };
> 
>  NBDKIT_REGISTER_FILTER(filter)
> diff --git a/filters/partition/partition.c b/filters/partition/partition.c
> index 849f0cc7..bb83da7b 100644
> --- a/filters/partition/partition.c
> +++ b/filters/partition/partition.c
> @@ -37,6 +37,7 @@
>  #include <stdint.h>
>  #include <string.h>
>  #include <inttypes.h>
> +#include <assert.h>
> 
>  #include <nbdkit-filter.h>
> 
> @@ -83,6 +84,7 @@ partition_config_complete (nbdkit_next_config_complete *next, void *nxdata)
>  struct handle {
>    int64_t offset;
>    int64_t range;
> +  const char *type;
>  };
> 
>  /* Open a connection. */
> @@ -139,13 +141,17 @@ partition_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,
> 
>    /* Is it GPT? */
>    if (size >= 2 * 34 * SECTOR_SIZE &&
> -      memcmp (&lba01[SECTOR_SIZE], "EFI PART", 8) == 0)
> +      memcmp (&lba01[SECTOR_SIZE], "EFI PART", 8) == 0) {
>      r = find_gpt_partition (next_ops, nxdata, size, &lba01[SECTOR_SIZE],
>                              &h->offset, &h->range);
> +    h->type = "GPT";
> +  }
>    /* Is it MBR? */
> -  else if (lba01[0x1fe] == 0x55 && lba01[0x1ff] == 0xAA)
> +  else if (lba01[0x1fe] == 0x55 && lba01[0x1ff] == 0xAA) {
>      r = find_mbr_partition (next_ops, nxdata, size, lba01,
>                              &h->offset, &h->range);
> +    h->type = "MBR";
> +  }
>    else {
>      nbdkit_error ("disk does not contain MBR or GPT partition table signature");
>      r = -1;
> @@ -168,6 +174,23 @@ partition_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,
>    return 0;
>  }
> 
> +/* Description. */
> +static const char *
> +partition_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
> +                              void *handle)
> +{
> +  struct handle *h = handle;
> +  const char *base = next_ops->export_description (nxdata);
> +  CLEANUP_FREE char *desc = NULL;
> +
> +  assert (h->type);
> +  if (base)
> +    asprintf (&desc, "partition %d of %s disk: %s", partnum, h->type, base);
> +  else
> +    asprintf (&desc, "partition %d of %s disk", partnum, h->type);
> +  return nbdkit_strdup_intern (desc);
> +}
> +
>  /* Get the file size. */
>  static int64_t
>  partition_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
> @@ -266,21 +289,22 @@ partition_cache (struct nbdkit_next_ops *next_ops, void *nxdata,
>  }
> 
>  static struct nbdkit_filter filter = {
> -  .name              = "partition",
> -  .longname          = "nbdkit partition filter",
> -  .config            = partition_config,
> -  .config_complete   = partition_config_complete,
> -  .config_help       = partition_config_help,
> -  .open              = partition_open,
> -  .prepare           = partition_prepare,
> -  .close             = partition_close,
> -  .get_size          = partition_get_size,
> -  .pread             = partition_pread,
> -  .pwrite            = partition_pwrite,
> -  .trim              = partition_trim,
> -  .zero              = partition_zero,
> -  .extents           = partition_extents,
> -  .cache             = partition_cache,
> +  .name               = "partition",
> +  .longname           = "nbdkit partition filter",
> +  .config             = partition_config,
> +  .config_complete    = partition_config_complete,
> +  .config_help        = partition_config_help,
> +  .open               = partition_open,
> +  .prepare            = partition_prepare,
> +  .close              = partition_close,
> +  .export_description = partition_export_description,
> +  .get_size           = partition_get_size,
> +  .pread              = partition_pread,
> +  .pwrite             = partition_pwrite,
> +  .trim               = partition_trim,
> +  .zero               = partition_zero,
> +  .extents            = partition_extents,
> +  .cache              = partition_cache,
>  };
> 
>  NBDKIT_REGISTER_FILTER(filter)
> diff --git a/filters/tar/tar.c b/filters/tar/tar.c
> index cb42b918..090a2144 100644
> --- a/filters/tar/tar.c
> +++ b/filters/tar/tar.c
> @@ -295,6 +295,21 @@ tar_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,
>    return 0;
>  }
> 
> +/* Description. */
> +static const char *
> +tar_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
> +                        void *handle)
> +{
> +  const char *base = next_ops->export_description (nxdata);
> +  CLEANUP_FREE char *desc = NULL;
> +
> +  if (base)
> +    asprintf (&desc, "embedded %s from within tar file: %s", entry, base);
> +  else
> +    asprintf (&desc, "embedded %s from within tar file", entry);
> +  return nbdkit_strdup_intern (desc);
> +}
> +
>  /* Get the file size. */
>  static int64_t
>  tar_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
> @@ -395,22 +410,23 @@ tar_cache (struct nbdkit_next_ops *next_ops, void *nxdata,
>  }
> 
>  static struct nbdkit_filter filter = {
> -  .name              = "tar",
> -  .longname          = "nbdkit tar filter",
> -  .config            = tar_config,
> -  .config_complete   = tar_config_complete,
> -  .config_help       = tar_config_help,
> -  .thread_model      = tar_thread_model,
> -  .open              = tar_open,
> -  .close             = tar_close,
> -  .prepare           = tar_prepare,
> -  .get_size          = tar_get_size,
> -  .pread             = tar_pread,
> -  .pwrite            = tar_pwrite,
> -  .trim              = tar_trim,
> -  .zero              = tar_zero,
> -  .extents           = tar_extents,
> -  .cache             = tar_cache,
> +  .name               = "tar",
> +  .longname           = "nbdkit tar filter",
> +  .config             = tar_config,
> +  .config_complete    = tar_config_complete,
> +  .config_help        = tar_config_help,
> +  .thread_model       = tar_thread_model,
> +  .open               = tar_open,
> +  .close              = tar_close,
> +  .prepare            = tar_prepare,
> +  .export_description = tar_export_description,
> +  .get_size           = tar_get_size,
> +  .pread              = tar_pread,
> +  .pwrite             = tar_pwrite,
> +  .trim               = tar_trim,
> +  .zero               = tar_zero,
> +  .extents            = tar_extents,
> +  .cache              = tar_cache,
>  };
> 
>  NBDKIT_REGISTER_FILTER(filter)
> diff --git a/filters/xz/xz.c b/filters/xz/xz.c
> index 26cfa959..2aa8c893 100644
> --- a/filters/xz/xz.c
> +++ b/filters/xz/xz.c
> @@ -47,6 +47,7 @@
> 
>  #include "xzfile.h"
>  #include "blkcache.h"
> +#include "cleanup.h"
> 
>  static uint64_t maxblock = 512 * 1024 * 1024;
>  static uint32_t maxdepth = 8;
> @@ -156,6 +157,21 @@ xz_prepare (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle,
>    return 0;
>  }
> 
> +/* Description. */
> +static const char *
> +xz_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
> +                       void *handle)
> +{
> +  const char *base = next_ops->export_description (nxdata);
> +  CLEANUP_FREE char *desc = NULL;
> +
> +  if (base) {
> +    asprintf (&desc, "expansion of xz-compressed image: %s", base);
> +    return nbdkit_strdup_intern (desc);
> +  }
> +  return "expansion of xz-compressed image";
> +}
> +
>  /* Get the file size. */
>  static int64_t
>  xz_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
> @@ -245,19 +261,20 @@ static int xz_thread_model (void)
>  }
> 
>  static struct nbdkit_filter filter = {
> -  .name              = "xz",
> -  .longname          = "nbdkit XZ filter",
> -  .config            = xz_config,
> -  .config_help       = xz_config_help,
> -  .thread_model      = xz_thread_model,
> -  .open              = xz_open,
> -  .close             = xz_close,
> -  .prepare           = xz_prepare,
> -  .get_size          = xz_get_size,
> -  .can_write         = xz_can_write,
> -  .can_extents       = xz_can_extents,
> -  .can_cache         = xz_can_cache,
> -  .pread             = xz_pread,
> +  .name               = "xz",
> +  .longname           = "nbdkit XZ filter",
> +  .config             = xz_config,
> +  .config_help        = xz_config_help,
> +  .thread_model       = xz_thread_model,
> +  .open               = xz_open,
> +  .close              = xz_close,
> +  .prepare            = xz_prepare,
> +  .export_description = xz_export_description,
> +  .get_size           = xz_get_size,
> +  .can_write          = xz_can_write,
> +  .can_extents        = xz_can_extents,
> +  .can_cache          = xz_can_cache,
> +  .pread              = xz_pread,
>  };
> 
>  NBDKIT_REGISTER_FILTER(filter)
> -- 
> 2.28.0
> 
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://www.redhat.com/mailman/listinfo/libguestfs

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW




More information about the Libguestfs mailing list