This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
Home Products Support Community News


Re: [Xen-devel] [PATCH 1 of 2] tools/libxc: Remus Checkpoint Compression

On Mon, Jun 27, 2011 at 11:33 AM, Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> wrote:
Shriram Rajagopalan writes ("[Xen-devel] [PATCH 1 of 2] tools/libxc: Remus Checkpoint Compression"):
> [stuff]

Thanks for this.  I have some comments.

TBH I don't think "remus" is the right name for this functionality.
This checkpoint compression may be useful in non-Remus applications
(we won't know until we get some numbers) so it would be sensible to
name the functions and files accordingly.

> +        if (!buf->pages) {
> +            if (!(buf->pages = malloc(buf->compbuf_size))) {
> +                ERROR("Could not allocate compression buffer");
> +                return -1;
> +            }
> +        } else {
> +            if (!(ptmp = realloc(buf->pages, buf->compbuf_size))) {
> +                ERROR("Could not reallocate compression buffer");
> +                return -1;
> +            }
> +            buf->pages = ptmp;

realloc(0, some_nonzero_size) is legal and does what you would hope.
Using that would simplify this.  (Yes, I know the original code does
it the verbose way later too...)

> +static
> +int __uncompress(xc_interface *xch, char *destpage, unsigned long *compbuf_pos,
> +                 char *compbuf, unsigned long compbuf_size)

Identifiers starting with "__" are reserved for the C implementation
and must not be used in Xen userspace libraries like libxc.  (The same
goes for identifiers starting with "_" with external linkage; although
those may be used for other purposes.)

> +typedef unsigned int data_t;

uint16_t surely.

> +    if (src[0].off == BEGIN)
> +    {
> +        *compbuf_pos += sizeof(struct marker);
> +        for (i = 1; (*compbuf_pos < compbuf_size) && (src[i].off >= 0);
> +             i++, *compbuf_pos += sizeof(struct marker))
> +            dest[src[i].off] = src[i].val;
> +    }
> +    else if (src[0].off == FULLPAGE)
> +    {
> +        *compbuf_pos += sizeof(struct marker) + XC_PAGE_SIZE;
> +        memcpy(destpage, (char *)&src[1], XC_PAGE_SIZE);
> +    }

I think there are some bugs here:

1. The accesses of src, and both arms of the conditional I quote
  above, seem to be able to read beyond the end of the compressed
  data buffer.
I dont think that is possible in the if() block , as the conditional in the
for statement (*compbuf_pos < compbuf_size) takes care of it. But I agree
that the else() block can use some checks.

2. The value of src[i].off is used without checking that it's within
  the allowable range.
3. The code seems to be full of unaligned accesses.

 Can you elaborate on this? When the data is compressed, it automatically
loses the alignments (no more page boundaries, or 4 byte boundaries).
Do you mean padding the struct marker to 8 bytes instead of 6 bytes ?
 (the counter argument is given in the comment section preceding the typedefs)

When you have prepared a draft revised patch, can you please have
another Remus developer review the code for security problems ?
I would like to see them provide a formal reviewed-by/acked-by on your


Xen-devel mailing list