Example #1
0
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);
}