[Libguestfs] [PATCH nbdkit] filters: cache, cow: Handle bitmap overflow on 32 bit architectures.

Richard W.M. Jones rjones at redhat.com
Fri Jan 26 13:17:22 UTC 2018


When compiling on armv7 it becomes clear from the compiler warnings
that the current code is wrong.

The bitmap has to be allocated in virtual memory, so use size_t to
describe the length of the bitmap.  When changing the length of the
bitmap, compute the new size as an unsigned 64 bit int, and then check
whether or not it is too large to fit into size_t before casting it.
---
 filters/cache/cache.c | 13 ++++++++++---
 filters/cow/cow.c     | 13 ++++++++++---
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/filters/cache/cache.c b/filters/cache/cache.c
index 7410f0d..9473f2c 100644
--- a/filters/cache/cache.c
+++ b/filters/cache/cache.c
@@ -72,7 +72,7 @@ static int fd = -1;
 static uint8_t *bitmap;
 
 /* Size of the bitmap in bytes. */
-static uint64_t bm_size;
+static size_t bm_size;
 
 enum bm_entry {
   BLOCK_NOT_CACHED = 0,
@@ -167,7 +167,14 @@ blk_set_size (uint64_t new_size)
 {
   uint8_t *new_bm;
   const size_t old_bm_size = bm_size;
-  size_t new_bm_size = DIV_ROUND_UP (new_size, BLKSIZE*8/2);
+  uint64_t new_bm_size_u64 = DIV_ROUND_UP (new_size, BLKSIZE*8/2);
+  size_t new_bm_size;
+
+  if (new_bm_size_u64 > SIZE_MAX) {
+    nbdkit_error ("bitmap too large for this architecture");
+    return -1;
+  }
+  new_bm_size = (size_t) new_bm_size_u64;
 
   new_bm = realloc (bitmap, new_bm_size);
   if (new_bm == NULL) {
@@ -179,7 +186,7 @@ blk_set_size (uint64_t new_size)
   if (old_bm_size < new_bm_size)
     memset (&bitmap[old_bm_size], 0, new_bm_size-old_bm_size);
 
-  nbdkit_debug ("cache: bitmap resized to %" PRIu64 " bytes", new_bm_size);
+  nbdkit_debug ("cache: bitmap resized to %zu bytes", new_bm_size);
 
   if (ftruncate (fd, new_size) == -1) {
     nbdkit_error ("ftruncate: %m");
diff --git a/filters/cow/cow.c b/filters/cow/cow.c
index 2b023af..5c2fcd0 100644
--- a/filters/cow/cow.c
+++ b/filters/cow/cow.c
@@ -97,7 +97,7 @@ static int fd = -1;
 static uint8_t *bitmap;
 
 /* Size of the bitmap in bytes. */
-static uint64_t bm_size;
+static size_t bm_size;
 
 static void
 cow_load (void)
@@ -153,7 +153,14 @@ blk_set_size (uint64_t new_size)
 {
   uint8_t *new_bm;
   const size_t old_bm_size = bm_size;
-  size_t new_bm_size = DIV_ROUND_UP (new_size, BLKSIZE*8);
+  uint64_t new_bm_size_u64 = DIV_ROUND_UP (new_size, BLKSIZE*8);
+  size_t new_bm_size;
+
+  if (new_bm_size_u64 > SIZE_MAX) {
+    nbdkit_error ("bitmap too large for this architecture");
+    return -1;
+  }
+  new_bm_size = (size_t) new_bm_size_u64;
 
   new_bm = realloc (bitmap, new_bm_size);
   if (new_bm == NULL) {
@@ -165,7 +172,7 @@ blk_set_size (uint64_t new_size)
   if (old_bm_size < new_bm_size)
     memset (&bitmap[old_bm_size], 0, new_bm_size-old_bm_size);
 
-  nbdkit_debug ("cow: bitmap resized to %" PRIu64 " bytes", new_bm_size);
+  nbdkit_debug ("cow: bitmap resized to %zu bytes", new_bm_size);
 
   if (ftruncate (fd, new_size) == -1) {
     nbdkit_error ("ftruncate: %m");
-- 
2.13.2




More information about the Libguestfs mailing list