nbdkit/0007-cow-Fix-assert-failure-in-cow_extents.patch
2021-07-26 09:56:31 +01:00

149 lines
5.2 KiB
Diff

From c0c0728f40466cf4a8ab4868002e331df6d85b1e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 24 Jul 2021 13:30:55 +0100
Subject: [PATCH 7/7] cow: Fix assert failure in cow_extents
$ nbdkit sparse-random 4G --filter=cow --run 'nbdinfo --map $uri'
nbdkit: cow.c:591: cow_extents: Assertion `count > 0' failed.
nbdinfo calls us with count = 0xfffffe00 [1] stored in a 32 bit
quantity. This was rounded up to the next block boundary and so
overflows (count becomes 0, hence the assertion).
Use a 64 bit variable for count to allow rounding up. This requires
further changes as a further 32 bit variable must not be allowed to
overflow.
This also adds a regression test.
[1] UINT32_MAX - 512 + 1 from:
https://gitlab.com/nbdkit/libnbd/-/blob/c55c5d9960809efd27cd044d007a33ea1636f4b0/info/map.c#L64
(cherry picked from commit 4d66ab72b29fc56190c7a6368eff3a6ba94c0f9f)
---
tests/Makefile.am | 2 ++
filters/cow/cow.c | 16 +++++++++---
tests/test-cow-extents-large.sh | 46 +++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+), 3 deletions(-)
create mode 100755 tests/test-cow-extents-large.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e0b31ba9..9630205d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1402,6 +1402,7 @@ TESTS += \
test-cow.sh \
test-cow-extents1.sh \
test-cow-extents2.sh \
+ test-cow-extents-large.sh \
test-cow-unaligned.sh \
$(NULL)
endif
@@ -1410,6 +1411,7 @@ EXTRA_DIST += \
test-cow.sh \
test-cow-extents1.sh \
test-cow-extents2.sh \
+ test-cow-extents-large.sh \
test-cow-null.sh \
test-cow-unaligned.sh \
$(NULL)
diff --git a/filters/cow/cow.c b/filters/cow/cow.c
index 83844845..3bd09399 100644
--- a/filters/cow/cow.c
+++ b/filters/cow/cow.c
@@ -571,19 +571,23 @@ cow_cache (nbdkit_next *next,
/* Extents. */
static int
cow_extents (nbdkit_next *next,
- void *handle, uint32_t count, uint64_t offset, uint32_t flags,
+ void *handle, uint32_t count32, uint64_t offset, uint32_t flags,
struct nbdkit_extents *extents, int *err)
{
const bool can_extents = next->can_extents (next);
const bool req_one = flags & NBDKIT_FLAG_REQ_ONE;
+ uint64_t count = count32;
uint64_t end;
uint64_t blknum;
- /* To make this easier, align the requested extents to whole blocks. */
+ /* To make this easier, align the requested extents to whole blocks.
+ * Note that count is a 64 bit variable containing at most a 32 bit
+ * value so rounding up is safe here.
+ */
end = offset + count;
offset = ROUND_DOWN (offset, BLKSIZE);
end = ROUND_UP (end, BLKSIZE);
- count = end - offset;
+ count = end - offset;
blknum = offset / BLKSIZE;
assert (IS_ALIGNED (offset, BLKSIZE));
@@ -628,6 +632,12 @@ cow_extents (nbdkit_next *next,
* as we can.
*/
for (;;) {
+ /* nbdkit_extents_full cannot read more than a 32 bit range
+ * (range_count), but count is a 64 bit quantity, so don't
+ * overflow range_count here.
+ */
+ if (range_count >= UINT32_MAX - BLKSIZE + 1) break;
+
blknum++;
offset += BLKSIZE;
count -= BLKSIZE;
diff --git a/tests/test-cow-extents-large.sh b/tests/test-cow-extents-large.sh
new file mode 100755
index 00000000..ea981dcb
--- /dev/null
+++ b/tests/test-cow-extents-large.sh
@@ -0,0 +1,46 @@
+#!/usr/bin/env bash
+# nbdkit
+# Copyright (C) 2018-2021 Red Hat Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Red Hat nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+# Regression test of an earlier overflow in cow_extents.
+# https://listman.redhat.com/archives/libguestfs/2021-July/msg00037.html
+
+source ./functions.sh
+set -e
+set -x
+
+requires_filter cow
+requires_plugin sparse-random
+requires nbdinfo --version
+
+for size in 0 3G 4G 5G 8G; do
+ nbdkit -U - sparse-random $size --filter=cow --run 'nbdinfo --map $uri'
+done
--
2.32.0