Blame SOURCES/kvm-bochs-Unify-header-structs-and-make-them-QEMU_PACKED.patch

0a122b
From 30e78b5a6fc16e3669f83b27e02c8eb53e646b48 Mon Sep 17 00:00:00 2001
0a122b
From: Kevin Wolf <kwolf@redhat.com>
0a122b
Date: Tue, 25 Mar 2014 14:23:17 +0100
0a122b
Subject: [PATCH 10/49] bochs: Unify header structs and make them QEMU_PACKED
0a122b
0a122b
RH-Author: Kevin Wolf <kwolf@redhat.com>
0a122b
Message-id: <1395753835-7591-11-git-send-email-kwolf@redhat.com>
0a122b
Patchwork-id: n/a
0a122b
O-Subject: [virt-devel] [EMBARGOED RHEL-7.0 qemu-kvm PATCH 10/48] bochs: Unify header structs and make them QEMU_PACKED
0a122b
Bugzilla: 1066691
0a122b
RH-Acked-by: Jeff Cody <jcody@redhat.com>
0a122b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
0a122b
0a122b
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1066691
0a122b
Upstream status: Series embargoed
0a122b
0a122b
This is an on-disk structure, so offsets must be accurate.
0a122b
0a122b
Before this patch, sizeof(bochs) != sizeof(header_v1), which makes the
0a122b
memcpy() between both invalid. We're lucky enough that the destination
0a122b
buffer happened to be the larger one, and the memcpy size to be taken
0a122b
from the smaller one, so we didn't get a buffer overflow in practice.
0a122b
0a122b
This patch unifies the both structures, eliminating the need to do a
0a122b
memcpy in the first place. The common fields are extracted to the top
0a122b
level of the struct and the actually differing part gets a union of the
0a122b
two versions.
0a122b
0a122b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
0a122b
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
---
0a122b
 block/bochs.c |   67 +++++++++++++++++++++-----------------------------------
0a122b
 1 files changed, 25 insertions(+), 42 deletions(-)
0a122b
0a122b
diff --git a/block/bochs.c b/block/bochs.c
0a122b
index 51d9a90..708780d 100644
0a122b
--- a/block/bochs.c
0a122b
+++ b/block/bochs.c
0a122b
@@ -39,45 +39,30 @@
0a122b
 // not allocated: 0xffffffff
0a122b
 
0a122b
 // always little-endian
0a122b
-struct bochs_header_v1 {
0a122b
-    char magic[32]; // "Bochs Virtual HD Image"
0a122b
-    char type[16]; // "Redolog"
0a122b
-    char subtype[16]; // "Undoable" / "Volatile" / "Growing"
0a122b
-    uint32_t version;
0a122b
-    uint32_t header; // size of header
0a122b
-
0a122b
-    union {
0a122b
-	struct {
0a122b
-	    uint32_t catalog; // num of entries
0a122b
-	    uint32_t bitmap; // bitmap size
0a122b
-	    uint32_t extent; // extent size
0a122b
-	    uint64_t disk; // disk size
0a122b
-	    char padding[HEADER_SIZE - 64 - 8 - 20];
0a122b
-	} redolog;
0a122b
-	char padding[HEADER_SIZE - 64 - 8];
0a122b
-    } extra;
0a122b
-};
0a122b
-
0a122b
-// always little-endian
0a122b
 struct bochs_header {
0a122b
-    char magic[32]; // "Bochs Virtual HD Image"
0a122b
-    char type[16]; // "Redolog"
0a122b
-    char subtype[16]; // "Undoable" / "Volatile" / "Growing"
0a122b
+    char magic[32];     /* "Bochs Virtual HD Image" */
0a122b
+    char type[16];      /* "Redolog" */
0a122b
+    char subtype[16];   /* "Undoable" / "Volatile" / "Growing" */
0a122b
     uint32_t version;
0a122b
-    uint32_t header; // size of header
0a122b
+    uint32_t header;    /* size of header */
0a122b
+
0a122b
+    uint32_t catalog;   /* num of entries */
0a122b
+    uint32_t bitmap;    /* bitmap size */
0a122b
+    uint32_t extent;    /* extent size */
0a122b
 
0a122b
     union {
0a122b
-	struct {
0a122b
-	    uint32_t catalog; // num of entries
0a122b
-	    uint32_t bitmap; // bitmap size
0a122b
-	    uint32_t extent; // extent size
0a122b
-	    uint32_t reserved; // for ???
0a122b
-	    uint64_t disk; // disk size
0a122b
-	    char padding[HEADER_SIZE - 64 - 8 - 24];
0a122b
-	} redolog;
0a122b
-	char padding[HEADER_SIZE - 64 - 8];
0a122b
+        struct {
0a122b
+            uint32_t reserved;  /* for ??? */
0a122b
+            uint64_t disk;      /* disk size */
0a122b
+            char padding[HEADER_SIZE - 64 - 20 - 12];
0a122b
+        } QEMU_PACKED redolog;
0a122b
+        struct {
0a122b
+            uint64_t disk;      /* disk size */
0a122b
+            char padding[HEADER_SIZE - 64 - 20 - 8];
0a122b
+        } QEMU_PACKED redolog_v1;
0a122b
+        char padding[HEADER_SIZE - 64 - 20];
0a122b
     } extra;
0a122b
-};
0a122b
+} QEMU_PACKED;
0a122b
 
0a122b
 typedef struct BDRVBochsState {
0a122b
     CoMutex lock;
0a122b
@@ -114,7 +99,6 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
0a122b
     BDRVBochsState *s = bs->opaque;
0a122b
     int i;
0a122b
     struct bochs_header bochs;
0a122b
-    struct bochs_header_v1 header_v1;
0a122b
     int ret;
0a122b
 
0a122b
     bs->read_only = 1; // no write support yet
0a122b
@@ -133,13 +117,12 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
0a122b
     }
0a122b
 
0a122b
     if (le32_to_cpu(bochs.version) == HEADER_V1) {
0a122b
-      memcpy(&header_v1, &bochs, sizeof(bochs));
0a122b
-      bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512;
0a122b
+        bs->total_sectors = le64_to_cpu(bochs.extra.redolog_v1.disk) / 512;
0a122b
     } else {
0a122b
-      bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
0a122b
+        bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
0a122b
     }
0a122b
 
0a122b
-    s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
0a122b
+    s->catalog_size = le32_to_cpu(bochs.catalog);
0a122b
     s->catalog_bitmap = g_malloc(s->catalog_size * 4);
0a122b
 
0a122b
     ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
0a122b
@@ -153,10 +136,10 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
0a122b
 
0a122b
     s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);
0a122b
 
0a122b
-    s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512;
0a122b
-    s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512;
0a122b
+    s->bitmap_blocks = 1 + (le32_to_cpu(bochs.bitmap) - 1) / 512;
0a122b
+    s->extent_blocks = 1 + (le32_to_cpu(bochs.extent) - 1) / 512;
0a122b
 
0a122b
-    s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
0a122b
+    s->extent_size = le32_to_cpu(bochs.extent);
0a122b
 
0a122b
     qemu_co_mutex_init(&s->lock);
0a122b
     return 0;
0a122b
-- 
0a122b
1.7.1
0a122b