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

Re: [Xen-devel] [PATCH v3] xen/tools: Introduce QNX IFS loader



Hi Ian

On Tue, Sep 23, 2014 at 6:53 PM, Ian Campbell <Ian.Campbell@xxxxxxxxxx> wrote:
> On Mon, 2014-09-22 at 21:12 +0300, Oleksandr Tyshchenko wrote:
>> This patch was developed according to instruction:
>> http://www.qnx.com/developers/docs/6.4.1/neutrino/building/load_process.html
>>
>> Add ability to load QNX IFS image. The loader probe function
>> based on "Writing an IPL Program" howto from qnx.com
>> and performs image validation and startup entry point location.
>> Because of the fact that the image is already in place some
>> customizations have been done. Also in case of multiple images
>> (very seldom case) only the first image will be loaded.
>>
>> There are some restrictions:
>> 1. The base address of the image (image attribute) and the location
>>    of RAM in system must be synchronized with RAM base address in Xen.
>> 2. The QNX IFS image must be created as a simple binary image.
>
> It might be nice (eventually, not necessarily now) to add something to
> the wiki or the docs/ subtree which describes how to build a suitable
> QNX binary.
>
>> Change-Id: Id125d6eae5847698fb5734c7f28451f5b752062f
>
> What is this?
This Change-Id for our local gerrit. I forgot to drop it.

>
> [...]
>> +    v_start = rambase + 0x8000;
>> +    if ( dom->kernel_size > UINT64_MAX - v_start )
>> +    {
>> +        xc_dom_printf(dom->xch, "%s: QNX IFS is too big", __FUNCTION__);
>> +        return -EINVAL;
>> +    }
>
> This check should be in the parse callback.
ok

>
>> +
>> +    /*
>> +     * Performs a check for a valid OS signature. We assume that nothing
>> +     * preceded by startup header because we expect a simple binary image.
>> +     */
>> +    startup_hdr = (struct startup_header *)dom->kernel_blob;
>> +    if ( startup_hdr->signature != STARTUP_HDR_SIGNATURE )
>> +    {
>> +        xc_dom_printf(dom->xch, "%s: image is not a QNX IFS", __FUNCTION__);
>> +        return -EINVAL;
>> +    }
>> +
>> +    /* Performs a final check for a valid image size */
>> +    if ( (startup_hdr->stored_size + startup_hdr->preboot_size) != 
>> dom->kernel_size )
>
> A suitably large stored_size or preboot_size will potentially overflow
> the addition and the result could be arranged to be == kernel_size.
>
> Since stored_size and preboot_size are 32- and 16-bit it is (I think)
> sufficient to cast to a 64bit type for the addition. Perhaps one way
> which is nice and clear in terms of reviewing for security would be
>         uint64_t total_size;
>
>         ...
>
>         total_size += startup_hdr->stored_size;
>         total_size += startup_hdr->preboot_size;
>         if ( total_size != dom->kernel_size )
>                 ...
ok

>
> BTW, you might want to check > dom->kernel_size to allow for smaller
> images?
No, I would prefer the strong check:
if ( total_size != dom->kernel_size )
   ...

>
>> +    {
>> +        xc_dom_printf(dom->xch, "%s: QNX IFS has wrong size", __FUNCTION__);
>> +        return -EINVAL;
>> +    }
>> +
>> +    /* Performs a checksums on the startup and the OS image filesystem */
>> +    if ( (calc_checksum((uint32_t *)startup_hdr, startup_hdr->startup_size) 
>> != 0) ||
>> +         (calc_checksum((uint32_t *)startup_hdr + 
>> startup_hdr->startup_size/4,
>> +          startup_hdr->stored_size - startup_hdr->startup_size) != 0) )
>
> You haven't validated startup_size yet, so you can't trust it to not
> overrun the buffer. And you need to be careful with that subtraction,
> probably starting with validating that one is larger than the other.
ok

>
> You don't see to use preboot_size for anything, perhaps you meant to
> range check startup_size above instead?
Sorry I don't understand what do you mean.

>
>> +    {
>> +        xc_dom_printf(dom->xch, "%s: QNX IFS has wrong checksum", 
>> __FUNCTION__);
>> +        return -EINVAL;
>> +    }
>> +
>> +    /* Performs a sanity check for a valid startup entry point */
>> +    v_end = v_start + dom->kernel_size;
>> +    if ( (startup_hdr->startup_vaddr < v_start) ||
>> +         (startup_hdr->startup_vaddr > v_end) )
>> +    {
>> +        xc_dom_printf(dom->xch, "%s: QNX IFS has wrong startup entry 
>> point", __FUNCTION__);
>> +        return -EINVAL;
>> +    }
>
> I think this check can also move to parse time. (It may not matter but
> the other loaders don't rely on rambase_pfn in the probe function and
> I'd like to be consistent if possible).
ok

>
>> +
>> +    dom->startup_vaddr = startup_hdr->startup_vaddr;
>
> and having move the above I think you can then just assign virt_entry
> directly from startup_hdr in the parse function. Since you've validated
> the header in the probe function parse can just use it.
ok

>
>> +static int xc_dom_parse_qnx_ifs(struct xc_dom_image *dom)
>> +{
>> +    uint64_t v_start, v_end;
>> +    uint64_t rambase = dom->rambase_pfn << XC_PAGE_SHIFT;
>> +
>> +    DOMPRINTF_CALLED(dom->xch);
>> +
>> +    /* Do not load kernel at the very first RAM address */
>> +    v_start = rambase + 0x8000;
>> +    v_end = v_start + dom->kernel_size;
>
> [...] put the checks which I called about above here.
ok

>
>> +    /* find kernel segment */
>> +    dom->kernel_seg.vstart = v_start;
>> +    dom->kernel_seg.vend   = v_end;
>> +
>> +    dom->parms.virt_entry = dom->startup_vaddr;
>> +    dom->parms.virt_base = rambase;
>> +
>> +    dom->guest_type = "xen-3.0-armv7l";
>> +    DOMPRINTF("%s: %s: RAM starts at %"PRI_xen_pfn,
>> +              __FUNCTION__, dom->guest_type, dom->rambase_pfn);
>> +    DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
>> +              __FUNCTION__, dom->guest_type,
>> +              dom->kernel_seg.vstart, dom->kernel_seg.vend);
>> +
>> +    return 0;
>> +}
>
> [...]
>
> Ian.
>



-- 

Oleksandr Tyshchenko | Embedded Dev
GlobalLogic
www.globallogic.com

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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