[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |