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

[Xen-changelog] [xen master] libxc: add LZ4 decompression support



commit 84f04d8f0dbfc24a48ee888011ca7410b7bbafc5
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Mon Oct 7 09:42:51 2013 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Oct 7 09:42:51 2013 +0200

    libxc: add LZ4 decompression support
    
    Since there's no shared or static library to link against, this simply
    re-uses the hypervisor side code. However, I only audited the code
    added here for possible security issues, not the referenced code in
    the hypervisor tree.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Keir Fraser <keir@xxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 tools/libxc/Makefile                |    1 +
 tools/libxc/xc_dom_bzimageloader.c  |   13 +++-
 tools/libxc/xc_dom_decompress.h     |    8 ++
 tools/libxc/xc_dom_decompress_lz4.c |  136 +++++++++++++++++++++++++++++++++++
 4 files changed, 157 insertions(+), 1 deletions(-)

diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index 512a994..4c64c15 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -63,6 +63,7 @@ $(patsubst %.c,%.opic,$(ELF_SRCS-y)): CFLAGS += 
-Wno-pointer-sign
 GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
 GUEST_SRCS-y                 += xc_dom_elfloader.c
 GUEST_SRCS-$(CONFIG_X86)     += xc_dom_bzimageloader.c
+GUEST_SRCS-$(CONFIG_X86)     += xc_dom_decompress_lz4.c
 GUEST_SRCS-$(CONFIG_ARM)     += xc_dom_armzimageloader.c
 GUEST_SRCS-y                 += xc_dom_binloader.c
 GUEST_SRCS-y                 += xc_dom_compat_linux.c
diff --git a/tools/libxc/xc_dom_bzimageloader.c 
b/tools/libxc/xc_dom_bzimageloader.c
index 3870c6d..2225699 100644
--- a/tools/libxc/xc_dom_bzimageloader.c
+++ b/tools/libxc/xc_dom_bzimageloader.c
@@ -33,7 +33,7 @@
 #include <inttypes.h>
 
 #include "xg_private.h"
-#include "xc_dom.h"
+#include "xc_dom_decompress.h"
 
 #ifndef __MINIOS__
 
@@ -733,6 +733,17 @@ static int xc_dom_probe_bzimage_kernel(struct xc_dom_image 
*dom)
             return -EINVAL;
         }
     }
+    else if ( check_magic(dom, "\x02\x21", 2) )
+    {
+        ret = xc_try_lz4_decode(dom, &dom->kernel_blob, &dom->kernel_size);
+        if ( ret < 0 )
+        {
+            xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
+                         "%s unable to LZ4 decompress kernel\n",
+                         __FUNCTION__);
+            return -EINVAL;
+        }
+    }
     else
     {
         xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
diff --git a/tools/libxc/xc_dom_decompress.h b/tools/libxc/xc_dom_decompress.h
new file mode 100644
index 0000000..42cefa3
--- /dev/null
+++ b/tools/libxc/xc_dom_decompress.h
@@ -0,0 +1,8 @@
+#ifndef __MINIOS__
+# include "xc_dom.h"
+#else
+# include "xc_dom_decompress_unsafe.h"
+#endif
+
+int xc_try_lz4_decode(struct xc_dom_image *dom, void **blob, size_t *size);
+
diff --git a/tools/libxc/xc_dom_decompress_lz4.c 
b/tools/libxc/xc_dom_decompress_lz4.c
new file mode 100644
index 0000000..4787535
--- /dev/null
+++ b/tools/libxc/xc_dom_decompress_lz4.c
@@ -0,0 +1,136 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <endian.h>
+#include <stdint.h>
+
+#include "xg_private.h"
+#include "xc_dom_decompress.h"
+
+#define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+#define likely(a) a
+#define unlikely(a) a
+
+static inline uint_fast16_t le16_to_cpup(const unsigned char *buf)
+{
+    return buf[0] | (buf[1] << 8);
+}
+
+static inline uint_fast32_t le32_to_cpup(const unsigned char *buf)
+{
+    return le16_to_cpup(buf) | ((uint32_t)le16_to_cpup(buf + 2) << 16);
+}
+
+#include "../../xen/include/xen/lz4.h"
+#include "../../xen/common/decompress.h"
+
+#ifndef __MINIOS__
+
+#include "../../xen/common/lz4/decompress.c"
+
+#define ARCHIVE_MAGICNUMBER 0x184C2102
+
+int xc_try_lz4_decode(
+       struct xc_dom_image *dom, void **blob, size_t *psize)
+{
+       int ret = -1;
+       unsigned char *inp = *blob, *output, *outp;
+       ssize_t size = *psize - 4;
+       size_t out_len, dest_len, chunksize;
+       const char *msg;
+
+       if (size < 4) {
+               msg = "input too small";
+               goto exit_0;
+       }
+
+       out_len = get_unaligned_le32(inp + size);
+       if (xc_dom_kernel_check_size(dom, out_len)) {
+               msg = "Decompressed image too large";
+               goto exit_0;
+       }
+
+       output = malloc(out_len);
+       if (!output) {
+               msg = "Could not allocate output buffer";
+               goto exit_0;
+       }
+       outp = output;
+
+       chunksize = get_unaligned_le32(inp);
+       if (chunksize == ARCHIVE_MAGICNUMBER) {
+               inp += 4;
+               size -= 4;
+       } else {
+               msg = "invalid header";
+               goto exit_2;
+       }
+
+       for (;;) {
+               if (size < 4) {
+                       msg = "missing data";
+                       goto exit_2;
+               }
+               chunksize = get_unaligned_le32(inp);
+               if (chunksize == ARCHIVE_MAGICNUMBER) {
+                       inp += 4;
+                       size -= 4;
+                       continue;
+               }
+               inp += 4;
+               size -= 4;
+               if (chunksize > size) {
+                       msg = "insufficient input data";
+                       goto exit_2;
+               }
+
+               dest_len = out_len - (outp - output);
+               ret = lz4_decompress_unknownoutputsize(inp, chunksize, outp,
+                               &dest_len);
+               if (ret < 0) {
+                       msg = "decoding failed";
+                       goto exit_2;
+               }
+
+               outp += dest_len;
+               size -= chunksize;
+
+               if (size == 0)
+               {
+                       *blob = output;
+                       *psize = out_len;
+                       return 0;
+               }
+
+               if (size < 0) {
+                       msg = "data corrupted";
+                       goto exit_2;
+               }
+
+               inp += chunksize;
+       }
+
+exit_2:
+       free(output);
+exit_0:
+       DOMPRINTF("LZ4 decompression error: %s\n", msg);
+       return ret;
+}
+
+#else /* __MINIOS__ */
+
+#include "../../xen/common/unlz4.c"
+
+int xc_try_lz4_decode(
+    struct xc_dom_image *dom, void **blob, size_t *size)
+{
+    return xc_dom_decompress_unsafe(unlz4, dom, blob, size);
+}
+
+#endif
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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