@@ -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) )
{
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@suse.com> --- 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.