static int xc_dom_probe_bzimage_kernel(struct xc_dom_image *dom) { struct setup_header *hdr; uint64_t payload_offset, payload_length; int ret; if ( dom->kernel_blob == NULL ) { xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: no kernel image loaded", __FUNCTION__); return -EINVAL; } if ( dom->kernel_size < sizeof(struct setup_header) ) { xc_dom_printf(dom->xch, "%s: kernel image too small", __FUNCTION__); return -EINVAL; } hdr = dom->kernel_blob; if ( memcmp(&hdr->header, HDR_MAGIC, HDR_MAGIC_SZ) != 0 ) { xc_dom_printf(dom->xch, "%s: kernel is not a bzImage", __FUNCTION__); return -EINVAL; } if ( hdr->version < VERSION(2,8) ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: boot protocol" " too old (%04x)", __FUNCTION__, hdr->version); return -EINVAL; } /* upcast to 64 bits to avoid overflow */ /* setup_sects is u8 and so cannot overflow */ payload_offset = (hdr->setup_sects + 1) * 512; payload_offset += hdr->payload_offset; payload_length = hdr->payload_length; if ( payload_offset >= dom->kernel_size ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: payload offset overflow", __FUNCTION__); return -EINVAL; } if ( (payload_offset + payload_length) > dom->kernel_size ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: payload length overflow", __FUNCTION__); return -EINVAL; } dom->kernel_blob = dom->kernel_blob + payload_offset; dom->kernel_size = payload_length; if ( check_magic(dom, "\037\213", 2) ) { ret = xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); if ( ret == -1 ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: unable to" " gzip decompress kernel", __FUNCTION__); return -EINVAL; } } else if ( check_magic(dom, "\102\132\150", 3) ) { ret = xc_try_bzip2_decode(dom, &dom->kernel_blob, &dom->kernel_size); if ( ret < 0 ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s unable to BZIP2 decompress kernel", __FUNCTION__); return -EINVAL; } } else if ( check_magic(dom, "\3757zXZ", 6) ) { ret = xc_try_xz_decode(dom, &dom->kernel_blob, &dom->kernel_size); if ( ret < 0 ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s unable to XZ decompress kernel", __FUNCTION__); return -EINVAL; } } else if ( check_magic(dom, "\135\000", 2) ) { ret = xc_try_lzma_decode(dom, &dom->kernel_blob, &dom->kernel_size); if ( ret < 0 ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s unable to LZMA decompress kernel", __FUNCTION__); return -EINVAL; } } else if ( check_magic(dom, "\x89LZO", 5) ) { ret = xc_try_lzo1x_decode(dom, &dom->kernel_blob, &dom->kernel_size); if ( ret < 0 ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s unable to LZO decompress kernel\n", __FUNCTION__); 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, "%s: unknown compression format", __FUNCTION__); return -EINVAL; } return elf_loader.probe(dom); }
static int xc_dom_probe_bzimage_kernel(struct xc_dom_image *dom) { struct setup_header *hdr; int ret; if ( dom->kernel_blob == NULL ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: no kernel image loaded\n", __FUNCTION__); return -EINVAL; } if ( dom->kernel_size < sizeof(struct setup_header) ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: kernel image too small\n", __FUNCTION__); return -EINVAL; } hdr = dom->kernel_blob; if ( memcmp(&hdr->header, HDR_MAGIC, HDR_MAGIC_SZ) != 0 ) { xc_dom_panic(XC_INVALID_KERNEL, "%s: kernel is not a bzImage\n", __FUNCTION__); return -EINVAL; } if ( hdr->version < VERSION(2,8) ) { xc_dom_panic(XC_INVALID_KERNEL, "%s: boot protocol too old (%04x)\n", __FUNCTION__, hdr->version); return -EINVAL; } dom->kernel_blob = dom->kernel_blob + payload_offset(hdr); dom->kernel_size = hdr->payload_length; if ( memcmp(dom->kernel_blob, "\037\213", 2) == 0 ) { ret = xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); if ( ret == -1 ) { xc_dom_panic(XC_INVALID_KERNEL, "%s: unable to gzip decompress kernel\n", __FUNCTION__); return -EINVAL; } } else if ( memcmp(dom->kernel_blob, "\102\132\150", 3) == 0 ) { ret = xc_try_bzip2_decode(dom, &dom->kernel_blob, &dom->kernel_size); if ( ret < 0 ) { xc_dom_panic(XC_INVALID_KERNEL, "%s unable to BZIP2 decompress kernel", __FUNCTION__); return -EINVAL; } } else if ( memcmp(dom->kernel_blob, "\135\000", 2) == 0 ) { ret = xc_try_lzma_decode(dom, &dom->kernel_blob, &dom->kernel_size); if ( ret < 0 ) { xc_dom_panic(XC_INVALID_KERNEL, "%s unable to LZMA decompress kernel\n", __FUNCTION__); return -EINVAL; } } else { xc_dom_panic(XC_INVALID_KERNEL, "%s: unknown compression format\n", __FUNCTION__); return -EINVAL; } return elf_loader.probe(dom); }