bc50933de3
resolves: rhbz#1950632
149 lines
5.2 KiB
Diff
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
|
|
|