[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 3/8] libxenguest: guard against overflow from too large p2m when checkpointing
struct xc_sr_record's length field has just 32 bits. Fill it early and check that the calculated value hasn't overflowed. Additionally check for counter overflow early - there's no point even trying to allocate any memory in such an event. While there also limit an induction variable's type to unsigned long: There's no gain from it being uint64_t. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- Of course looping over test_bit() is pretty inefficient, but given that I have no idea how to test this code I wanted to restrict changes to what can sensibly be seen as no worse than before from just looking at the changes. --- a/tools/libs/guest/xg_sr_restore.c +++ b/tools/libs/guest/xg_sr_restore.c @@ -424,7 +424,8 @@ static int send_checkpoint_dirty_pfn_lis xc_interface *xch = ctx->xch; int rc = -1; unsigned int count, written; - uint64_t i, *pfns = NULL; + unsigned long i; + uint64_t *pfns = NULL; struct iovec *iov = NULL; xc_shadow_op_stats_t stats = { 0, ctx->restore.p2m_size }; struct xc_sr_record rec = { @@ -444,16 +445,28 @@ static int send_checkpoint_dirty_pfn_lis for ( i = 0, count = 0; i < ctx->restore.p2m_size; i++ ) { - if ( test_bit(i, dirty_bitmap) ) - count++; + if ( test_bit(i, dirty_bitmap) && !++count ) + break; } + if ( i < ctx->restore.p2m_size ) + { + ERROR("Too many dirty pfns"); + goto err; + } + + rec.length = count * sizeof(*pfns); + if ( rec.length / sizeof(*pfns) != count ) + { + ERROR("Too many (%u) dirty pfns", count); + goto err; + } - pfns = malloc(count * sizeof(*pfns)); + pfns = malloc(rec.length); if ( !pfns ) { - ERROR("Unable to allocate %zu bytes of memory for dirty pfn list", - count * sizeof(*pfns)); + ERROR("Unable to allocate %u bytes of memory for dirty pfn list", + rec.length); goto err; } @@ -479,8 +492,6 @@ static int send_checkpoint_dirty_pfn_lis goto err; } - rec.length = count * sizeof(*pfns); - iov[0].iov_base = &rec.type; iov[0].iov_len = sizeof(rec.type); @@ -488,7 +499,7 @@ static int send_checkpoint_dirty_pfn_lis iov[1].iov_len = sizeof(rec.length); iov[2].iov_base = pfns; - iov[2].iov_len = count * sizeof(*pfns); + iov[2].iov_len = rec.length; if ( writev_exact(ctx->restore.send_back_fd, iov, 3) ) {
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |