diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2012-10-25 17:04:37 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2012-10-25 17:04:37 +0100 |
commit | f9ea792edccc5832eb92917ba87c46eccca42a0d (patch) | |
tree | d129ff81bb44d4ff12ad4fd4c67a77651fbcb650 /tools/libxc/xc_dom_bzimageloader.c | |
parent | fe0f4baccbec6eedef517ab98a0f14970697d06c (diff) | |
download | xen-f9ea792edccc5832eb92917ba87c46eccca42a0d.tar.gz xen-f9ea792edccc5832eb92917ba87c46eccca42a0d.tar.bz2 xen-f9ea792edccc5832eb92917ba87c46eccca42a0d.zip |
xl: Do not leak events when a domain exits.
The goto in both of these places misses the event free which would
normally clean up.
==8655== 80 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8655== at 0x4024370: calloc (vg_replace_malloc.c:593)
==8655== by 0x406EAAE: libxl__zalloc (libxl_internal.c:83)
==8655== by 0x4078173: libxl__event_new (libxl_event.c:1167)
==8655== by 0x4056373: domain_death_occurred (libxl.c:958)
==8655== by 0x4058D06: domain_death_xswatch_callback (libxl.c:1038)
==8655== by 0x4078EB5: watchfd_callback (libxl_event.c:458)
==8655== by 0x407839E: afterpoll_internal (libxl_event.c:949)
==8655== by 0x4079142: eventloop_iteration (libxl_event.c:1371)
==8655== by 0x40799BB: libxl_event_wait (libxl_event.c:1396)
==8655== by 0x805CC67: create_domain (xl_cmdimpl.c:1698)
==8655== by 0x805E001: main_create (xl_cmdimpl.c:3986)
==8655== by 0x804D43D: main (xl.c:285)
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxc/xc_dom_bzimageloader.c')
-rw-r--r-- | tools/libxc/xc_dom_bzimageloader.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/tools/libxc/xc_dom_bzimageloader.c b/tools/libxc/xc_dom_bzimageloader.c index 113d40ff2f..2b3602fcde 100644 --- a/tools/libxc/xc_dom_bzimageloader.c +++ b/tools/libxc/xc_dom_bzimageloader.c @@ -47,7 +47,7 @@ static int xc_try_bzip2_decode( char *out_buf; char *tmp_buf; int retval = -1; - int outsize; + unsigned int outsize; uint64_t total; stream.bzalloc = NULL; @@ -79,6 +79,17 @@ static int xc_try_bzip2_decode( stream.next_out = out_buf; stream.avail_out = dom->kernel_size; + /* + * stream.avail_in is an unsigned int, while kernel_size is a + * size_t. Check we aren't overflowing. + */ + if ( stream.avail_in != dom->kernel_size ) + { + DOMPRINTF("BZIP2: Input too large"); + free(out_buf); + goto bzip2_cleanup; + } + for ( ; ; ) { ret = BZ2_bzDecompress(&stream); @@ -98,13 +109,20 @@ static int xc_try_bzip2_decode( if ( stream.avail_out == 0 ) { /* Protect against output buffer overflow */ - if ( outsize > INT_MAX / 2 ) + if ( outsize > UINT_MAX / 2 ) { DOMPRINTF("BZIP2: output buffer overflow"); free(out_buf); goto bzip2_cleanup; } + if ( xc_dom_kernel_check_size(dom, outsize * 2) ) + { + DOMPRINTF("BZIP2: output too large"); + free(out_buf); + goto bzip2_cleanup; + } + tmp_buf = realloc(out_buf, outsize * 2); if ( tmp_buf == NULL ) { @@ -172,7 +190,7 @@ static int _xc_try_lzma_decode( unsigned char *out_buf; unsigned char *tmp_buf; int retval = -1; - int outsize; + size_t outsize; const char *msg; /* sigh. We don't know up-front how much memory we are going to need @@ -244,13 +262,20 @@ static int _xc_try_lzma_decode( if ( stream->avail_out == 0 ) { /* Protect against output buffer overflow */ - if ( outsize > INT_MAX / 2 ) + if ( outsize > SIZE_MAX / 2 ) { DOMPRINTF("%s: output buffer overflow", what); free(out_buf); goto lzma_cleanup; } + if ( xc_dom_kernel_check_size(dom, outsize * 2) ) + { + DOMPRINTF("%s: output too large", what); + free(out_buf); + goto lzma_cleanup; + } + tmp_buf = realloc(out_buf, outsize * 2); if ( tmp_buf == NULL ) { @@ -359,6 +384,12 @@ static int xc_try_lzo1x_decode( 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a }; + /* + * lzo_uint should match size_t. Check that this is the case to be + * sure we won't overflow various lzo_uint fields. + */ + XC_BUILD_BUG_ON(sizeof(lzo_uint) != sizeof(size_t)); + ret = lzo_init(); if ( ret != LZO_E_OK ) { @@ -438,6 +469,14 @@ static int xc_try_lzo1x_decode( if ( src_len <= 0 || src_len > dst_len || src_len > left ) break; + msg = "Output buffer overflow"; + if ( *size > SIZE_MAX - dst_len ) + break; + + msg = "Decompressed image too large"; + if ( xc_dom_kernel_check_size(dom, *size + dst_len) ) + break; + msg = "Failed to (re)alloc memory"; tmp_buf = realloc(out_buf, *size + dst_len); if ( tmp_buf == NULL ) |