[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] libxc: Add unsafe decompressors



WRT the freeze I have reworked the changes so there is only minimal
change to the hypervisor and non-stubdom builds of libxc, so at worst
it'll be an obvious build failure which we should easily catch before
release.

The real risk is to users of pvgrub. The risk is that it stops working
for them but since this only adds new compression algorithms I'd say the
risk of breaking with kernels with existing compression algorithms is
small and outweighed by the benefit of being able to work with xz
compressed kernels which are becoming more common e.g. default in Debian
trunk builds, and I think they are used by Fedora too.

Ian.

On Thu, 2013-04-18 at 12:49 +0100, Ian Campbell wrote:
> From: Bastian Blank <bastian@xxxxxxxxxxxx>
> 
> Add decompressors based on hypervisor code.  This are used in mini-os by
> pv-grub.
> 
> This enables pv-grub to boot kernels compressed with e.g. xz, which are
> becoming more common.
> 
> Signed-off-by: Bastian Blank <waldi@xxxxxxxxxx>
> 
> Adjusted to use terminology "unsafe" rather than "trusted" to indicate
> that the user had better sanitise the data (or not care, as in stub
> domains) as suggested by Tim Deegan. This was effectively a sed script.
> 
> Minimise the changes to hypervisor code by moving the "compat layer" into the
> relevant libxc source files (which include the Xen ones).
> 
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
> ---
>  stubdom/Makefile                             |    2 +-
>  tools/libxc/Makefile                         |    8 ++++
>  tools/libxc/xc_dom_bzimageloader.c           |   11 +++++
>  tools/libxc/xc_dom_decompress_unsafe.c       |   48 +++++++++++++++++++++
>  tools/libxc/xc_dom_decompress_unsafe.h       |   20 +++++++++
>  tools/libxc/xc_dom_decompress_unsafe_bzip2.c |   14 ++++++
>  tools/libxc/xc_dom_decompress_unsafe_lzma.c  |   14 ++++++
>  tools/libxc/xc_dom_decompress_unsafe_lzo1x.c |   49 ++++++++++++++++++++++
>  tools/libxc/xc_dom_decompress_unsafe_xz.c    |   57 
> ++++++++++++++++++++++++++
>  xen/common/decompress.h                      |   13 ++++++
>  xen/common/lzo.c                             |    3 +
>  xen/common/unlzma.c                          |    2 +
>  xen/common/unlzo.c                           |    3 +
>  xen/common/xz/private.h                      |    3 +
>  14 files changed, 246 insertions(+), 1 deletions(-)
>  create mode 100644 tools/libxc/xc_dom_decompress_unsafe.c
>  create mode 100644 tools/libxc/xc_dom_decompress_unsafe.h
>  create mode 100644 tools/libxc/xc_dom_decompress_unsafe_bzip2.c
>  create mode 100644 tools/libxc/xc_dom_decompress_unsafe_lzma.c
>  create mode 100644 tools/libxc/xc_dom_decompress_unsafe_lzo1x.c
>  create mode 100644 tools/libxc/xc_dom_decompress_unsafe_xz.c
> 
> diff --git a/stubdom/Makefile b/stubdom/Makefile
> index 427e4d6..a2ac044 100644
> --- a/stubdom/Makefile
> +++ b/stubdom/Makefile
> @@ -331,7 +331,7 @@ $(TARGETS_MINIOS): mini-os-%:
>  .PHONY: libxc
>  libxc: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a 
> libxc-$(XEN_TARGET_ARCH)/libxenguest.a
>  libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: cross-zlib
> -     CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) 
> DESTDIR= -C libxc-$(XEN_TARGET_ARCH)
> +     CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) 
> DESTDIR= CONFIG_LIBXC_MINIOS=y -C libxc-$(XEN_TARGET_ARCH)
>  
>   libxc-$(XEN_TARGET_ARCH)/libxenguest.a: 
> libxc-$(XEN_TARGET_ARCH)/libxenctrl.a
>  
> diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
> index d44abf9..640e333 100644
> --- a/tools/libxc/Makefile
> +++ b/tools/libxc/Makefile
> @@ -68,6 +68,14 @@ GUEST_SRCS-$(CONFIG_X86)     += xc_hvm_build_x86.c
>  GUEST_SRCS-$(CONFIG_ARM)     += xc_dom_arm.c
>  GUEST_SRCS-$(CONFIG_ARM)     += xc_hvm_build_arm.c
>  
> +ifeq ($(CONFIG_LIBXC_MINIOS),y)
> +GUEST_SRCS-y                 += xc_dom_decompress_unsafe.c
> +GUEST_SRCS-y                 += xc_dom_decompress_unsafe_bzip2.c
> +GUEST_SRCS-y                 += xc_dom_decompress_unsafe_lzma.c
> +GUEST_SRCS-y                 += xc_dom_decompress_unsafe_lzo1x.c
> +GUEST_SRCS-y                 += xc_dom_decompress_unsafe_xz.c
> +endif
> +
>  OSDEP_SRCS-y                 += xenctrl_osdep_ENOSYS.c
>  
>  -include $(XEN_TARGET_ARCH)/Makefile
> diff --git a/tools/libxc/xc_dom_bzimageloader.c 
> b/tools/libxc/xc_dom_bzimageloader.c
> index 6daa78c..3870c6d 100644
> --- a/tools/libxc/xc_dom_bzimageloader.c
> +++ b/tools/libxc/xc_dom_bzimageloader.c
> @@ -35,6 +35,8 @@
>  #include "xg_private.h"
>  #include "xc_dom.h"
>  
> +#ifndef __MINIOS__
> +
>  #if defined(HAVE_BZLIB)
>  
>  #include <bzlib.h>
> @@ -562,6 +564,15 @@ static int xc_try_lzo1x_decode(
>  
>  #endif
>  
> +#else /* __MINIOS__ */
> +
> +int xc_try_bzip2_decode(struct xc_dom_image *dom, void **blob, size_t *size);
> +int xc_try_lzma_decode(struct xc_dom_image *dom, void **blob, size_t *size);
> +int xc_try_lzo1x_decode(struct xc_dom_image *dom, void **blob, size_t *size);
> +int xc_try_xz_decode(struct xc_dom_image *dom, void **blob, size_t *size);
> +
> +#endif /* !__MINIOS__ */
> +
>  struct setup_header {
>      uint8_t  _pad0[0x1f1];  /* skip uninteresting stuff */
>      uint8_t  setup_sects;
> diff --git a/tools/libxc/xc_dom_decompress_unsafe.c 
> b/tools/libxc/xc_dom_decompress_unsafe.c
> new file mode 100644
> index 0000000..164e355
> --- /dev/null
> +++ b/tools/libxc/xc_dom_decompress_unsafe.c
> @@ -0,0 +1,48 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <inttypes.h>
> +
> +#include "xg_private.h"
> +#include "xc_dom_decompress_unsafe.h"
> +
> +static struct xc_dom_image *unsafe_dom;
> +static unsigned char *output_blob;
> +static unsigned int output_size;
> +
> +static void unsafe_error(const char *msg)
> +{
> +    xc_dom_panic(unsafe_dom->xch, XC_INVALID_KERNEL, "%s", msg);
> +}
> +
> +static int unsafe_flush(void *src, unsigned int size)
> +{
> +    void *n = realloc(output_blob, output_size + size);
> +    if (!n)
> +        return -1;
> +    output_blob = n;
> +
> +    memcpy(&output_blob[output_size], src, size);
> +    output_size += size;
> +    return size;
> +}
> +
> +int xc_dom_decompress_unsafe(
> +    decompress_fn fn, struct xc_dom_image *dom, void **blob, size_t *size)
> +{
> +    int ret;
> +
> +    unsafe_dom = dom;
> +    output_blob = NULL;
> +    output_size = 0;
> +
> +    ret = fn(dom->kernel_blob, dom->kernel_size, NULL, unsafe_flush, NULL, 
> NULL, unsafe_error);
> +
> +    if (ret)
> +        free(output_blob);
> +    else {
> +        *blob = output_blob;
> +        *size = output_size;
> +    }
> +
> +    return ret;
> +}
> diff --git a/tools/libxc/xc_dom_decompress_unsafe.h 
> b/tools/libxc/xc_dom_decompress_unsafe.h
> new file mode 100644
> index 0000000..64f6886
> --- /dev/null
> +++ b/tools/libxc/xc_dom_decompress_unsafe.h
> @@ -0,0 +1,20 @@
> +#include "xc_dom.h"
> +
> +typedef int decompress_fn(unsigned char *inbuf, unsigned int len,
> +                          int (*fill)(void*, unsigned int),
> +                          int (*flush)(void*, unsigned int),
> +                          unsigned char *outbuf, unsigned int *posp,
> +                          void (*error)(const char *x));
> +
> +int xc_dom_decompress_unsafe(
> +    decompress_fn fn, struct xc_dom_image *dom, void **blob, size_t *size)
> +    __attribute__((visibility("internal")));
> +
> +int xc_try_bzip2_decode(struct xc_dom_image *dom, void **blob, size_t *size)
> +    __attribute__((visibility("internal")));
> +int xc_try_lzma_decode(struct xc_dom_image *dom, void **blob, size_t *size)
> +    __attribute__((visibility("internal")));
> +int xc_try_lzo1x_decode(struct xc_dom_image *dom, void **blob, size_t *size)
> +    __attribute__((visibility("internal")));
> +int xc_try_xz_decode(struct xc_dom_image *dom, void **blob, size_t *size)
> +    __attribute__((visibility("internal")));
> diff --git a/tools/libxc/xc_dom_decompress_unsafe_bzip2.c 
> b/tools/libxc/xc_dom_decompress_unsafe_bzip2.c
> new file mode 100644
> index 0000000..4dcabe4
> --- /dev/null
> +++ b/tools/libxc/xc_dom_decompress_unsafe_bzip2.c
> @@ -0,0 +1,14 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <inttypes.h>
> +
> +#include "xg_private.h"
> +#include "xc_dom_decompress_unsafe.h"
> +
> +#include "../../xen/common/bunzip2.c"
> +
> +int xc_try_bzip2_decode(
> +    struct xc_dom_image *dom, void **blob, size_t *size)
> +{
> +    return xc_dom_decompress_unsafe(bunzip2, dom, blob, size);
> +}
> diff --git a/tools/libxc/xc_dom_decompress_unsafe_lzma.c 
> b/tools/libxc/xc_dom_decompress_unsafe_lzma.c
> new file mode 100644
> index 0000000..4ee8cdb
> --- /dev/null
> +++ b/tools/libxc/xc_dom_decompress_unsafe_lzma.c
> @@ -0,0 +1,14 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <inttypes.h>
> +
> +#include "xg_private.h"
> +#include "xc_dom_decompress_unsafe.h"
> +
> +#include "../../xen/common/unlzma.c"
> +
> +int xc_try_lzma_decode(
> +    struct xc_dom_image *dom, void **blob, size_t *size)
> +{
> +    return xc_dom_decompress_unsafe(unlzma, dom, blob, size);
> +}
> diff --git a/tools/libxc/xc_dom_decompress_unsafe_lzo1x.c 
> b/tools/libxc/xc_dom_decompress_unsafe_lzo1x.c
> new file mode 100644
> index 0000000..57c73e3
> --- /dev/null
> +++ b/tools/libxc/xc_dom_decompress_unsafe_lzo1x.c
> @@ -0,0 +1,49 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <inttypes.h>
> +#include <endian.h>
> +#include <stdint.h>
> +
> +#include "xg_private.h"
> +#include "xc_dom_decompress_unsafe.h"
> +
> +typedef uint8_t u8;
> +typedef uint32_t u32;
> +typedef uint16_t u16;
> +
> +#define likely(a) a
> +#define noinline
> +#define unlikely(a) a
> +
> +static inline u16 be16_to_cpup(const u16 *p)
> +{
> +     u16 v = *p;
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +     return (((v & 0x00ffU) << 8) |
> +                ((v & 0xff00U) >> 8));
> +#else
> +     return v;
> +#endif
> +}
> +
> +static inline u32 be32_to_cpup(const u32 *p)
> +{
> +     u32 v = *p;
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +     return (((v & 0x000000ffUL) << 24) |
> +                ((v & 0x0000ff00UL) <<  8) |
> +                ((v & 0x00ff0000UL) >>  8) |
> +                ((v & 0xff000000UL) >> 24));
> +#else
> +     return v;
> +#endif
> +}
> +
> +#include "../../xen/common/lzo.c"
> +#include "../../xen/common/unlzo.c"
> +
> +int xc_try_lzo1x_decode(
> +    struct xc_dom_image *dom, void **blob, size_t *size)
> +{
> +    return xc_dom_decompress_unsafe(unlzo, dom, blob, size);
> +}
> diff --git a/tools/libxc/xc_dom_decompress_unsafe_xz.c 
> b/tools/libxc/xc_dom_decompress_unsafe_xz.c
> new file mode 100644
> index 0000000..2a32d40
> --- /dev/null
> +++ b/tools/libxc/xc_dom_decompress_unsafe_xz.c
> @@ -0,0 +1,57 @@
> +#include <stdio.h>
> +#include <endian.h>
> +#include <stdlib.h>
> +#include <stddef.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +
> +#include "xg_private.h"
> +#include "xc_dom_decompress_unsafe.h"
> +
> +// TODO
> +#define XZ_DEC_X86
> +
> +typedef char bool_t;
> +typedef uint8_t u8;
> +typedef uint16_t u16;
> +typedef uint32_t u32;
> +typedef uint32_t __le32;
> +
> +static inline u32 cpu_to_le32(const u32 v)
> +{
> +#if BYTE_ORDER == BIG_ENDIAN
> +     return (((v & 0x000000ffUL) << 24) |
> +             ((v & 0x0000ff00UL) <<  8) |
> +             ((v & 0x00ff0000UL) >>  8) |
> +             ((v & 0xff000000UL) >> 24));
> +#else
> +     return v;
> +#endif
> +}
> +
> +static inline u32 le32_to_cpup(const u32 *p)
> +{
> +     return cpu_to_le32(*p);
> +}
> +
> +#define min(x,y) ({ \
> +        const typeof(x) _x = (x);       \
> +        const typeof(y) _y = (y);       \
> +        (void) (&_x == &_y);            \
> +        _x < _y ? _x : _y; })
> +
> +#define min_t(type,x,y) \
> +        ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
> +#define max_t(type,x,y) \
> +        ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
> +
> +#define __force
> +#define always_inline
> +
> +#include "../../xen/common/unxz.c"
> +
> +int xc_try_xz_decode(
> +    struct xc_dom_image *dom, void **blob, size_t *size)
> +{
> +    return xc_dom_decompress_unsafe(unxz, dom, blob, size);
> +}
> diff --git a/xen/common/decompress.h b/xen/common/decompress.h
> index bd62b5d..61e83e5 100644
> --- a/xen/common/decompress.h
> +++ b/xen/common/decompress.h
> @@ -1,3 +1,5 @@
> +#ifdef __XEN__
> +
>  #include <xen/config.h>
>  #include <xen/cache.h>
>  #include <xen/decompress.h>
> @@ -15,3 +17,14 @@
>  
>  #define large_malloc xmalloc_bytes
>  #define large_free xfree
> +
> +#else
> +
> +#define STATIC static
> +#define INIT
> +#define INITDATA
> +
> +#define large_malloc malloc
> +#define large_free free
> +
> +#endif
> diff --git a/xen/common/lzo.c b/xen/common/lzo.c
> index eeb200b..f1213d2 100644
> --- a/xen/common/lzo.c
> +++ b/xen/common/lzo.c
> @@ -68,7 +68,10 @@
>   *  Richard Purdie <rpurdie@xxxxxxxxxxxxxx>
>   */
>  
> +#ifdef __XEN__
>  #include <xen/types.h>
> +#endif
> +
>  #include <xen/lzo.h>
>  #define get_unaligned(_p) (*(_p))
>  #define put_unaligned(_val,_p) (*(_p)=_val)
> diff --git a/xen/common/unlzma.c b/xen/common/unlzma.c
> index 719fd0d..4d04330 100644
> --- a/xen/common/unlzma.c
> +++ b/xen/common/unlzma.c
> @@ -54,7 +54,9 @@ static long long INIT read_int(unsigned char *ptr, int size)
>   * Copyright (c) 1999-2005  Igor Pavlov
>   */
>  
> +#ifdef __XEN__
>  #include <xen/compiler.h>
> +#endif
>  
>  #define LZMA_IOBUF_SIZE      0x10000
>  
> diff --git a/xen/common/unlzo.c b/xen/common/unlzo.c
> index 57d16f3..fc794b0 100644
> --- a/xen/common/unlzo.c
> +++ b/xen/common/unlzo.c
> @@ -32,7 +32,10 @@
>  
>  #include "decompress.h"
>  #include <xen/lzo.h>
> +
> +#ifdef __XEN__
>  #include <asm/byteorder.h>
> +#endif
>  
>  #if 1 /* ndef CONFIG_??? */
>  static inline u16 INIT get_unaligned_be16(void *p)
> diff --git a/xen/common/xz/private.h b/xen/common/xz/private.h
> index 369bcb3..7ea2489 100644
> --- a/xen/common/xz/private.h
> +++ b/xen/common/xz/private.h
> @@ -10,8 +10,11 @@
>  #ifndef XZ_PRIVATE_H
>  #define XZ_PRIVATE_H
>  
> +#ifdef __XEN__
>  #include <xen/kernel.h>
>  #include <asm/byteorder.h>
> +#endif
> +
>  #define get_le32(p) le32_to_cpup((const uint32_t *)(p))
>  
>  #if 1 /* ndef CONFIG_??? */



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.