aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBastian Blank <bastian@waldi.eu.org>2013-04-18 12:49:54 +0100
committerIan Campbell <ian.campbell@citrix.com>2013-04-22 12:46:30 +0100
commit592d3ef961cafda917a7f123999dc04d426254ee (patch)
tree98f82705cbb7348589b2c2630f069dc25e05ed5b
parent071c61e7367987a9f71dc18c3c58a5dba659a5c8 (diff)
downloadxen-592d3ef961cafda917a7f123999dc04d426254ee.tar.gz
xen-592d3ef961cafda917a7f123999dc04d426254ee.tar.bz2
xen-592d3ef961cafda917a7f123999dc04d426254ee.zip
libxc: Add unsafe decompressors
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@debian.org> 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@citrix.com> Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
-rw-r--r--stubdom/Makefile2
-rw-r--r--tools/libxc/Makefile8
-rw-r--r--tools/libxc/xc_dom_bzimageloader.c11
-rw-r--r--tools/libxc/xc_dom_decompress_unsafe.c48
-rw-r--r--tools/libxc/xc_dom_decompress_unsafe.h20
-rw-r--r--tools/libxc/xc_dom_decompress_unsafe_bzip2.c14
-rw-r--r--tools/libxc/xc_dom_decompress_unsafe_lzma.c14
-rw-r--r--tools/libxc/xc_dom_decompress_unsafe_lzo1x.c49
-rw-r--r--tools/libxc/xc_dom_decompress_unsafe_xz.c57
-rw-r--r--xen/common/decompress.h13
-rw-r--r--xen/common/lzo.c3
-rw-r--r--xen/common/unlzma.c2
-rw-r--r--xen/common/unlzo.c3
-rw-r--r--xen/common/xz/private.h3
14 files changed, 246 insertions, 1 deletions
diff --git a/stubdom/Makefile b/stubdom/Makefile
index 427e4d66e8..a2ac044833 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 d44abf92c6..640e333d9c 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 6daa78ce2a..3870c6d5f5 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 0000000000..164e35558f
--- /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 0000000000..64f68864b1
--- /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 0000000000..4dcabe4061
--- /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 0000000000..4ee8cdbab1
--- /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 0000000000..57c73e30c1
--- /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 0000000000..2a32d40805
--- /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 bd62b5dc74..61e83e518a 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 eeb200b281..f1213d2dbe 100644
--- a/xen/common/lzo.c
+++ b/xen/common/lzo.c
@@ -68,7 +68,10 @@
* Richard Purdie <rpurdie@openedhand.com>
*/
+#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 719fd0d5c8..4d043308f9 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 57d16f3cca..fc794b0538 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 369bcb3d4a..7ea2489229 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_??? */