On 12/11/2014 10:44, Michael S. Tsirkin wrote: > During migration, the values read from migration stream during ram load > are not validated. Especially offset in host_from_stream_offset() and > also the length of the writes in the callers of said function. > > To fix this, we need to make sure that the [offset, offset + length] > range fits into one of the allocated memory regions. > > Validating addr < len should be sufficient since data seems to always be > managed in TARGET_PAGE_SIZE chunks. > > Fixes: CVE-2014-7840 > > Note: follow-up patches add extra checks on each block->host access. > > Signed-off-by: Michael S. Tsirkin <m...@redhat.com> > --- > arch_init.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/arch_init.c b/arch_init.c > index 88a5ba0..593a990 100644 > --- a/arch_init.c > +++ b/arch_init.c > @@ -1006,7 +1006,7 @@ static inline void *host_from_stream_offset(QEMUFile *f, > uint8_t len; > > if (flags & RAM_SAVE_FLAG_CONTINUE) { > - if (!block) { > + if (!block || block->length <= offset) { > error_report("Ack, bad migration stream!"); > return NULL; > } > @@ -1019,8 +1019,9 @@ static inline void *host_from_stream_offset(QEMUFile *f, > id[len] = 0; > > QTAILQ_FOREACH(block, &ram_list.blocks, next) { > - if (!strncmp(id, block->idstr, sizeof(id))) > + if (!strncmp(id, block->idstr, sizeof(id)) && block->length > > offset) { > return memory_region_get_ram_ptr(block->mr) + offset; > + } > } > > error_report("Can't find block %s!", id); >
Sort-of Yoda conditionals, i.e. I think "offset >= block->length" and "offset < block->length" would have been more common and indeed that's what you use in patch 3. That's the only comment I have. Series Reviewed-by: Paolo Bonzini <pbonz...@redhat.com>