From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 26 Mar 2014 13:05:37 +0100
Subject: vpc: Validate block size (CVE-2014-0142)

This fixes some cases of division by zero crashes.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 5e71dfad763d67bb64be79e20e93411c0c30ad25)
(also is_power_of_2 from 9fb26641ab497eda9138f9af75cbeb02ed59b5ae)

Conflicts:
	tests/qemu-iotests/088
	tests/qemu-iotests/088.out
	tests/qemu-iotests/group

diff --git a/block/vpc.c b/block/vpc.c
index f064b4a..23ca3cc 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -154,6 +154,15 @@ static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
     return 0;
 }
 
+static inline bool is_power_of_2(uint64_t value)
+{
+    if (!value) {
+        return 0;
+    }
+
+    return !(value & (value - 1));
+}
+
 static int vpc_open(BlockDriverState *bs, int flags)
 {
     BDRVVPCState *s = bs->opaque;
@@ -220,6 +229,11 @@ static int vpc_open(BlockDriverState *bs, int flags)
         }
 
         s->block_size = be32_to_cpu(dyndisk_header->block_size);
+        if (!is_power_of_2(s->block_size) || s->block_size < BDRV_SECTOR_SIZE) {
+            fprintf(stderr, "Invalid block size %" PRIu32 "\n", s->block_size);
+            err = -EINVAL;
+            goto fail;
+        }
         s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
 
         s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
-- 
1.7.10.4

