Compare commits

...

No commits in common. "imports/c9/libnbd-1.12.6-1.el9" and "c8-stream-rhel" have entirely different histories.

23 changed files with 794 additions and 2670 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/libguestfs.keyring
SOURCES/libnbd-1.12.6.tar.gz
SOURCES/libnbd-1.6.0.tar.gz

View File

@ -1,2 +1,2 @@
cc1b37b9cfafa515aab3eefd345ecc59aac2ce7b SOURCES/libguestfs.keyring
2d4eb0846d51c25fa7d04295972cbb5a617984ef SOURCES/libnbd-1.12.6.tar.gz
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
b14ac9349d324df71d26cf3de9fb606c56f18cb0 SOURCES/libnbd-1.6.0.tar.gz

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
From 486799e853aa9df034366303230a1785087a507a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 8 Jan 2021 12:14:18 +0000
Subject: [PATCH] copy/copy-nbd-to-sparse-file.sh: Skip test unless nbdkit
available.
This test used nbdkit without checking it is available, which broke
the test on RHEL 8 i686.
Fixes: commit 28fe8d9d8d1ecb491070d20f22e2f34bb147f19f
(cherry picked from commit 781cb44b63a87f2d5f40590ab8c446ad2e7b6702)
---
copy/copy-nbd-to-sparse-file.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/copy/copy-nbd-to-sparse-file.sh b/copy/copy-nbd-to-sparse-file.sh
index aa2cb1b..47ff09a 100755
--- a/copy/copy-nbd-to-sparse-file.sh
+++ b/copy/copy-nbd-to-sparse-file.sh
@@ -24,6 +24,7 @@ set -x
requires cmp --version
requires dd --version
requires dd oflag=seek_bytes </dev/null
+requires nbdkit --version
requires test -r /dev/urandom
requires test -r /dev/zero
--
2.31.1

View File

@ -1,153 +0,0 @@
From ec947323528725fcf12b5b9ba32b02d36dbd9621 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 30 Jun 2022 21:09:39 +0100
Subject: [PATCH] dump: Visually separate columns 0-7 and 8-15
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Before:
0000090000: 68 65 72 65 20 77 65 20 61 72 65 00 68 65 72 65 │...
0000090010: 20 77 65 20 61 72 65 00 68 65 72 65 20 77 65 20 │...
0000090020: 61 72 65 00 68 65 72 65 20 77 65 20 61 72 65 00 │...
After:
0000090000: 68 65 72 65 20 77 65 20 61 72 65 00 68 65 72 65 │...
0000090010: 20 77 65 20 61 72 65 00 68 65 72 65 20 77 65 20 │...
0000090020: 61 72 65 00 68 65 72 65 20 77 65 20 61 72 65 00 │...
Updates: commit c4107b9a40d6451630dcccf1bf6596c8e56420be
(cherry picked from commit 315a637d3eae003c1d84eb1b88a7b47b534f1e80)
---
dump/dump-data.sh | 22 +++++++++++-----------
dump/dump-empty-qcow2.sh | 4 ++--
dump/dump-pattern.sh | 38 +++++++++++++++++++-------------------
dump/dump.c | 5 ++++-
4 files changed, 36 insertions(+), 33 deletions(-)
diff --git a/dump/dump-data.sh b/dump/dump-data.sh
index 23d09da..955cd3b 100755
--- a/dump/dump-data.sh
+++ b/dump/dump-data.sh
@@ -37,21 +37,21 @@ nbdkit -U - data data='
cat $output
-if [ "$(cat $output)" != '0000000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+if [ "$(cat $output)" != '0000000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
-0000008000: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
-0000008010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+0000008000: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+0000008010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
-000000fff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 |...............h|
-0000010000: 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 00 00 00 00 |ello, world!....|
-0000010010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+000000fff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 |...............h|
+0000010000: 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 00 00 00 00 |ello, world!....|
+0000010010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
-00010ffff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 73 70 |..............sp|
-0001100000: 61 6e 6e 69 6e 67 20 62 75 66 66 65 72 20 62 6f |anning buffer bo|
-0001100010: 75 6e 64 61 72 79 00 00 00 00 00 00 00 00 00 00 |undary..........|
-0001100020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00010ffff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 73 70 |..............sp|
+0001100000: 61 6e 6e 69 6e 67 20 62 75 66 66 65 72 20 62 6f |anning buffer bo|
+0001100010: 75 6e 64 61 72 79 00 00 00 00 00 00 00 00 00 00 |undary..........|
+0001100020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
-0001312d00: 00 |. |' ]; then
+0001312d00: 00 |. |' ]; then
echo "$0: unexpected output from nbddump command"
exit 1
fi
diff --git a/dump/dump-empty-qcow2.sh b/dump/dump-empty-qcow2.sh
index c9e583b..472b6eb 100755
--- a/dump/dump-empty-qcow2.sh
+++ b/dump/dump-empty-qcow2.sh
@@ -38,9 +38,9 @@ qemu-img create -f qcow2 $file $size
nbddump -- [ $QEMU_NBD -r -f qcow2 $file ] > $output
cat $output
-if [ "$(cat $output)" != '0000000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+if [ "$(cat $output)" != '0000000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
-003ffffff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|' ]; then
+003ffffff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|' ]; then
echo "$0: unexpected output from nbddump command"
exit 1
fi
diff --git a/dump/dump-pattern.sh b/dump/dump-pattern.sh
index e4016a8..d512b77 100755
--- a/dump/dump-pattern.sh
+++ b/dump/dump-pattern.sh
@@ -32,25 +32,25 @@ nbdkit -U - pattern size=299 --run 'nbddump "$uri"' > $output
cat $output
-if [ "$(cat $output)" != '0000000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 |................|
-0000000010: 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 18 |................|
-0000000020: 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 28 |....... .......(|
-0000000030: 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 38 |.......0.......8|
-0000000040: 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 48 |.......@.......H|
-0000000050: 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 58 |.......P.......X|
-0000000060: 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00 68 |.......`.......h|
-0000000070: 00 00 00 00 00 00 00 70 00 00 00 00 00 00 00 78 |.......p.......x|
-0000000080: 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 88 |................|
-0000000090: 00 00 00 00 00 00 00 90 00 00 00 00 00 00 00 98 |................|
-00000000a0: 00 00 00 00 00 00 00 a0 00 00 00 00 00 00 00 a8 |................|
-00000000b0: 00 00 00 00 00 00 00 b0 00 00 00 00 00 00 00 b8 |................|
-00000000c0: 00 00 00 00 00 00 00 c0 00 00 00 00 00 00 00 c8 |................|
-00000000d0: 00 00 00 00 00 00 00 d0 00 00 00 00 00 00 00 d8 |................|
-00000000e0: 00 00 00 00 00 00 00 e0 00 00 00 00 00 00 00 e8 |................|
-00000000f0: 00 00 00 00 00 00 00 f0 00 00 00 00 00 00 00 f8 |................|
-0000000100: 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 08 |................|
-0000000110: 00 00 00 00 00 00 01 10 00 00 00 00 00 00 01 18 |................|
-0000000120: 00 00 00 00 00 00 01 20 00 00 00 |....... ... |' ]; then
+if [ "$(cat $output)" != '0000000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 |................|
+0000000010: 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 18 |................|
+0000000020: 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 28 |....... .......(|
+0000000030: 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 38 |.......0.......8|
+0000000040: 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 48 |.......@.......H|
+0000000050: 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 58 |.......P.......X|
+0000000060: 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00 68 |.......`.......h|
+0000000070: 00 00 00 00 00 00 00 70 00 00 00 00 00 00 00 78 |.......p.......x|
+0000000080: 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 88 |................|
+0000000090: 00 00 00 00 00 00 00 90 00 00 00 00 00 00 00 98 |................|
+00000000a0: 00 00 00 00 00 00 00 a0 00 00 00 00 00 00 00 a8 |................|
+00000000b0: 00 00 00 00 00 00 00 b0 00 00 00 00 00 00 00 b8 |................|
+00000000c0: 00 00 00 00 00 00 00 c0 00 00 00 00 00 00 00 c8 |................|
+00000000d0: 00 00 00 00 00 00 00 d0 00 00 00 00 00 00 00 d8 |................|
+00000000e0: 00 00 00 00 00 00 00 e0 00 00 00 00 00 00 00 e8 |................|
+00000000f0: 00 00 00 00 00 00 00 f0 00 00 00 00 00 00 00 f8 |................|
+0000000100: 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 08 |................|
+0000000110: 00 00 00 00 00 00 01 10 00 00 00 00 00 00 01 18 |................|
+0000000120: 00 00 00 00 00 00 01 20 00 00 00 |....... ... |' ]; then
echo "$0: unexpected output from nbddump command"
exit 1
fi
diff --git a/dump/dump.c b/dump/dump.c
index 76af04c..7818f1f 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -429,10 +429,13 @@ do_dump (void)
else
ansi_grey ();
printf ("%02x ", buffer[j]);
+ if ((j - i) == 7) printf (" ");
}
ansi_grey ();
- for (; j < i+16; ++j)
+ for (; j < i+16; ++j) {
printf (" ");
+ if ((j - i) == 7) printf (" ");
+ }
/* Print the ASCII codes. */
printf ("%s", pipe);
--
2.31.1

View File

@ -0,0 +1,57 @@
From 5dc2d2261224c9533d2b5ec4df6ed822de4cfc3b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 4 Feb 2021 17:57:06 +0000
Subject: [PATCH] generator: Refactor CONNECT.START state.
Small, neutral refactoring to the CONNECT.START to make the subsequent
commit easier.
(cherry picked from commit cd231fd94bbfaacdd9b89e7d355ba2bbc83c2aeb)
---
generator/states-connect.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/generator/states-connect.c b/generator/states-connect.c
index 392879d..03b34c7 100644
--- a/generator/states-connect.c
+++ b/generator/states-connect.c
@@ -47,11 +47,12 @@ disable_nagle (int sock)
STATE_MACHINE {
CONNECT.START:
- int fd;
+ sa_family_t family;
+ int fd, r;
assert (!h->sock);
- fd = socket (h->connaddr.ss_family,
- SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
+ family = h->connaddr.ss_family;
+ fd = socket (family, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
if (fd == -1) {
SET_NEXT_STATE (%.DEAD);
set_error (errno, "socket");
@@ -65,14 +66,12 @@ STATE_MACHINE {
disable_nagle (fd);
- if (connect (fd, (struct sockaddr *) &h->connaddr,
- h->connaddrlen) == -1) {
- if (errno != EINPROGRESS) {
- SET_NEXT_STATE (%.DEAD);
- set_error (errno, "connect");
- return 0;
- }
- }
+ r = connect (fd, (struct sockaddr *) &h->connaddr, h->connaddrlen);
+ if (r == 0 || (r == -1 && errno == EINPROGRESS))
+ return 0;
+ assert (r == -1);
+ SET_NEXT_STATE (%.DEAD);
+ set_error (errno, "connect");
return 0;
CONNECT.CONNECTING:
--
2.31.1

View File

@ -1,38 +0,0 @@
From 590e3a010d2c840314702883e44ec9841e3383c6 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 30 Jun 2022 22:27:43 +0100
Subject: [PATCH] dump: Fix build on i686
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Because we used the wrong printf format, the build would fail on
32 bit architectures but succeed on 64 bit:
dump.c: In function do_dump:
dump.c:421:21: error: format %zx expects argument of type size_t, but argument 2 has type uint64_t {aka long long unsigned int} [-Werror=format=]
printf ("%010zx", offset + i);
~~~~~^ ~~~~~~~~~~
%010llx
(cherry picked from commit ce004c329c7fcd6c60d11673b7a5c5ce3414413b)
---
dump/dump.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dump/dump.c b/dump/dump.c
index 7818f1f..8bf62f9 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -418,7 +418,7 @@ do_dump (void)
/* Print the offset. */
ansi_green ();
- printf ("%010zx", offset + i);
+ printf ("%010" PRIx64, offset + i);
ansi_grey ();
printf (": ");
--
2.31.1

View File

@ -0,0 +1,48 @@
From f094472efcf34cea8bf1f02a1c5c9442ffc4ca53 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 4 Feb 2021 18:02:46 +0000
Subject: [PATCH] generator: Print a better error message if connect(2) returns
EAGAIN.
The new error message is:
nbd_connect_unix: connect: server backlog overflowed, see https://bugzilla.redhat.com/1925045: Resource temporarily unavailable
Fixes: https://bugzilla.redhat.com/1925045
Thanks: Xin Long, Lukas Doktor, Eric Blake
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 85ed74960a658a82d7b61b0be07f43d1b2dcede9)
---
generator/states-connect.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/generator/states-connect.c b/generator/states-connect.c
index 03b34c7..98c26e5 100644
--- a/generator/states-connect.c
+++ b/generator/states-connect.c
@@ -70,6 +70,22 @@ STATE_MACHINE {
if (r == 0 || (r == -1 && errno == EINPROGRESS))
return 0;
assert (r == -1);
+#ifdef __linux__
+ if (errno == EAGAIN && family == AF_UNIX) {
+ /* This can happen on Linux when connecting to a Unix domain
+ * socket, if the server's backlog is full. Unfortunately there
+ * is nothing good we can do on the client side when this happens
+ * since any solution would involve sleeping or busy-waiting. The
+ * only solution is on the server side, increasing the backlog.
+ * But at least improve the error message.
+ * https://bugzilla.redhat.com/1925045
+ */
+ SET_NEXT_STATE (%.DEAD);
+ set_error (errno, "connect: server backlog overflowed, "
+ "see https://bugzilla.redhat.com/1925045");
+ return 0;
+ }
+#endif
SET_NEXT_STATE (%.DEAD);
set_error (errno, "connect");
return 0;
--
2.31.1

View File

@ -1,41 +0,0 @@
From e7a2815412891d5c13b5b5f0e9aa61882880c87f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 30 Jun 2022 22:31:00 +0100
Subject: [PATCH] dump: Fix tests on Debian 10
The version of nbdkit on Debian 10 does not set $uri. Check for this
or skip the test.
(cherry picked from commit 083b1ca30fb5e6e0dc0e4b0eea9ebe8474d3f864)
---
dump/dump-data.sh | 1 +
dump/dump-pattern.sh | 1 +
2 files changed, 2 insertions(+)
diff --git a/dump/dump-data.sh b/dump/dump-data.sh
index 955cd3b..46e4d1e 100755
--- a/dump/dump-data.sh
+++ b/dump/dump-data.sh
@@ -23,6 +23,7 @@ set -x
requires nbdkit --version
requires nbdkit data --dump-plugin
+requires nbdkit -U - null --run 'test "$uri" != ""'
output=dump-data.out
rm -f $output
diff --git a/dump/dump-pattern.sh b/dump/dump-pattern.sh
index d512b77..e2188ac 100755
--- a/dump/dump-pattern.sh
+++ b/dump/dump-pattern.sh
@@ -23,6 +23,7 @@ set -x
requires nbdkit --version
requires nbdkit pattern --dump-plugin
+requires nbdkit -U - null --run 'test "$uri" != ""'
output=dump-pattern.out
rm -f $output
--
2.31.1

View File

@ -0,0 +1,59 @@
From ffe8f0a994c1f2656aa011353b386663d32db69e Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 1 Mar 2021 15:25:31 -0600
Subject: [PATCH] opt_go: Tolerate unplanned server death
While debugging some experimental nbdkit code that was triggering an
assertion failure in nbdkit, I noticed a secondary failure of nbdsh
also dying from an assertion:
libnbd: debug: nbdsh: nbd_opt_go: transition: NEWSTYLE.OPT_GO.SEND -> DEAD
libnbd: debug: nbdsh: nbd_opt_go: option queued, ignoring state machine failure
nbdsh: opt.c:86: nbd_unlocked_opt_go: Assertion `nbd_internal_is_state_negotiating (get_next_state (h))' failed.
Although my trigger was from non-production nbdkit code, libnbd should
never die from an assertion failure merely because a server
disappeared at the wrong moment during an incomplete reply to
NBD_OPT_GO or NBD_OPT_INFO. If this is assigned a CVE, a followup
patch will add mention of it in docs/libnbd-security.pod.
Fixes: bbf1c51392 (api: Give aio_opt_go a completion callback)
(cherry picked from commit fb4440de9cc76e9c14bd3ddf3333e78621f40ad0)
---
lib/opt.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/opt.c b/lib/opt.c
index 2317b72..e5802f4 100644
--- a/lib/opt.c
+++ b/lib/opt.c
@@ -1,5 +1,5 @@
/* NBD client library in userspace
- * Copyright (C) 2020 Red Hat Inc.
+ * Copyright (C) 2020-2021 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -83,7 +83,8 @@ nbd_unlocked_opt_go (struct nbd_handle *h)
r = wait_for_option (h);
if (r == 0 && err) {
- assert (nbd_internal_is_state_negotiating (get_next_state (h)));
+ assert (nbd_internal_is_state_negotiating (get_next_state (h)) ||
+ nbd_internal_is_state_dead (get_next_state (h)));
set_error (err, "server replied with error to opt_go request");
return -1;
}
@@ -105,7 +106,8 @@ nbd_unlocked_opt_info (struct nbd_handle *h)
r = wait_for_option (h);
if (r == 0 && err) {
- assert (nbd_internal_is_state_negotiating (get_next_state (h)));
+ assert (nbd_internal_is_state_negotiating (get_next_state (h)) ||
+ nbd_internal_is_state_dead (get_next_state (h)));
set_error (err, "server replied with error to opt_info request");
return -1;
}
--
2.31.1

View File

@ -1,31 +0,0 @@
From 7c669783b1b3fab902ce34d7914b62617ed8b263 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 30 Jun 2022 22:35:05 +0100
Subject: [PATCH] dump/dump-data.sh: Test requires nbdkit 1.22
Ubuntu 20.04 has nbdkit 1.16 which lacks support for strings. These
were added in nbdkit 1.22.
(cherry picked from commit a8fa05ffb8b85f41276ffb52498e4528c08e5f21)
---
dump/dump-data.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dump/dump-data.sh b/dump/dump-data.sh
index 46e4d1e..11145b0 100755
--- a/dump/dump-data.sh
+++ b/dump/dump-data.sh
@@ -25,6 +25,10 @@ requires nbdkit --version
requires nbdkit data --dump-plugin
requires nbdkit -U - null --run 'test "$uri" != ""'
+# This test requires nbdkit >= 1.22.
+minor=$( nbdkit --dump-config | grep ^version_minor | cut -d= -f2 )
+requires test $minor -ge 22
+
output=dump-data.out
rm -f $output
cleanup_fn rm -f $output
--
2.31.1

View File

@ -0,0 +1,40 @@
From 171ffdde8be590f784086a021a7e6f36c4ecdb4b Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 12 Mar 2021 17:00:58 -0600
Subject: [PATCH] security: Document assignment of CVE-2021-20286
Now that we finally have a CVE number, it's time to document
the problem (it's low severity, but still a denial of service).
Fixes: fb4440de9cc7 (opt_go: Tolerate unplanned server death)
(cherry picked from commit 40308a005eaa6b2e8f98da8952d0c0cacc51efde)
---
docs/libnbd-security.pod | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/docs/libnbd-security.pod b/docs/libnbd-security.pod
index d8ead87..0cae846 100644
--- a/docs/libnbd-security.pod
+++ b/docs/libnbd-security.pod
@@ -22,6 +22,12 @@ L<https://www.redhat.com/archives/libguestfs/2019-September/msg00128.html>
See the full announcement here:
L<https://www.redhat.com/archives/libguestfs/2019-October/msg00060.html>
+=head2 CVE-2021-20286
+denial of service when using L<nbd_set_opt_mode(3)>
+
+See the full announcement here:
+L<https://listman.redhat.com/archives/libguestfs/2021-March/msg00092.html>
+
=head1 SEE ALSO
L<libnbd(3)>.
@@ -34,4 +40,4 @@ Richard W.M. Jones
=head1 COPYRIGHT
-Copyright (C) 2019 Red Hat Inc.
+Copyright (C) 2019-2021 Red Hat Inc.
--
2.31.1

View File

@ -0,0 +1,163 @@
From 22572f8ac13e2e8daf91d227eac2f384303fb5b4 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 3 Feb 2022 14:25:57 -0600
Subject: [PATCH] copy: Pass in dummy variable rather than &errno to callback
In several places where asynch handlers manually call the provided
nbd_completion_callback, the value of errno is indeterminate (for
example, in file-ops.c:file_asynch_read(), the previous call to
file_synch_read() already triggered exit() on error, but does not
guarantee what is left in errno on success). As the callback should
be paying attention to the value of *error (to be fixed in the next
patch), we are better off ensuring that we pass in a pointer to a
known-zero value. Besides, passing in &errno carries a risk that if
the callback uses any other library function that alters errno prior
to dereferncing *error, it will no longer see the value we passed in.
Thus, it is easier to use a dummy variable on the stack than to mess
around with errno and it's magic macro expansion into a thread-local
storage location.
Note that several callsites then check if the callback returned -1,
and if so assume that the callback has caused errno to now have a sane
value to pass on to perror. In theory, the fact that we are no longer
passing in &errno means that if the callback assigns into *error but
did not otherwise affect errno (a tenuous assumption, given our
argument above that we could not even guarantee that the callback does
not accidentally alter errno prior to reading *error), our perror call
would no longer reflect the intended error value from the callback.
But in practice, since the callback never actually returned -1, nor
even assigned into *error, the call to perror is dead code; although I
have chosen to defer that additional cleanup to the next patch.
Message-Id: <20220203202558.203013-5-eblake@redhat.com>
Acked-by: Richard W.M. Jones <rjones@redhat.com>
Acked-by: Nir Soffer <nsoffer@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit 794c8ce06e995ebd282e8f2b9465a06140572112)
Conflicts:
copy/file-ops.c - no backport of d5f65e56 ("copy: Do not use trim
for zeroing"), so asynch_trim needed same treatment
copy/multi-thread-copying.c - context due to missing refactoring
copy/null-ops.c - no backport of 0b16205e "copy: Implement "null:"
destination."
(cherry picked from commit 26e3dcf80815fe2db320d3046aabc2580c2f7a0d)
---
copy/file-ops.c | 22 +++++++++++++---------
copy/multi-thread-copying.c | 8 +++++---
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/copy/file-ops.c b/copy/file-ops.c
index 086348a..cc312b4 100644
--- a/copy/file-ops.c
+++ b/copy/file-ops.c
@@ -1,5 +1,5 @@
/* NBD client library in userspace.
- * Copyright (C) 2020 Red Hat Inc.
+ * Copyright (C) 2020-2022 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -158,10 +158,11 @@ file_asynch_read (struct rw *rw,
struct command *command,
nbd_completion_callback cb)
{
+ int dummy = 0;
+
file_synch_read (rw, slice_ptr (command->slice),
command->slice.len, command->offset);
- errno = 0;
- if (cb.callback (cb.user_data, &errno) == -1) {
+ if (cb.callback (cb.user_data, &dummy) == -1) {
perror (rw->name);
exit (EXIT_FAILURE);
}
@@ -172,10 +173,11 @@ file_asynch_write (struct rw *rw,
struct command *command,
nbd_completion_callback cb)
{
+ int dummy = 0;
+
file_synch_write (rw, slice_ptr (command->slice),
command->slice.len, command->offset);
- errno = 0;
- if (cb.callback (cb.user_data, &errno) == -1) {
+ if (cb.callback (cb.user_data, &dummy) == -1) {
perror (rw->name);
exit (EXIT_FAILURE);
}
@@ -185,10 +187,11 @@ static bool
file_asynch_trim (struct rw *rw, struct command *command,
nbd_completion_callback cb)
{
+ int dummy = 0;
+
if (!file_synch_trim (rw, command->offset, command->slice.len))
return false;
- errno = 0;
- if (cb.callback (cb.user_data, &errno) == -1) {
+ if (cb.callback (cb.user_data, &dummy) == -1) {
perror (rw->name);
exit (EXIT_FAILURE);
}
@@ -199,10 +202,11 @@ static bool
file_asynch_zero (struct rw *rw, struct command *command,
nbd_completion_callback cb)
{
+ int dummy = 0;
+
if (!file_synch_zero (rw, command->offset, command->slice.len))
return false;
- errno = 0;
- if (cb.callback (cb.user_data, &errno) == -1) {
+ if (cb.callback (cb.user_data, &dummy) == -1) {
perror (rw->name);
exit (EXIT_FAILURE);
}
diff --git a/copy/multi-thread-copying.c b/copy/multi-thread-copying.c
index a7aaa7d..2593ff7 100644
--- a/copy/multi-thread-copying.c
+++ b/copy/multi-thread-copying.c
@@ -1,5 +1,5 @@
/* NBD client library in userspace.
- * Copyright (C) 2020 Red Hat Inc.
+ * Copyright (C) 2020-2022 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -391,6 +391,7 @@ finished_read (void *vp, int *error)
bool last_is_hole = false;
uint64_t i;
struct command *newcommand;
+ int dummy = 0;
/* Iterate over whole blocks in the command, starting on a block
* boundary.
@@ -473,7 +474,7 @@ finished_read (void *vp, int *error)
/* Free the original command since it has been split into
* subcommands and the original is no longer needed.
*/
- free_command (command, &errno);
+ free_command (command, &dummy);
}
return 1; /* auto-retires the command */
@@ -498,6 +499,7 @@ static void
fill_dst_range_with_zeroes (struct command *command)
{
char *data;
+ int dummy = 0;
if (destination_is_zero)
goto free_and_return;
@@ -541,7 +543,7 @@ fill_dst_range_with_zeroes (struct command *command)
free (data);
free_and_return:
- free_command (command, &errno);
+ free_command (command, &dummy);
}
static int
--
2.31.1

View File

@ -1,163 +0,0 @@
From 8dce43a3ea7a529bc37cbe5607a8d52186cc8169 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 28 Jun 2022 18:27:58 +0100
Subject: [PATCH] copy: Store the preferred block size in the operations struct
This will be used in a subsequent commit. At the moment the preferred
block size for all sources / destinations is simply calculated and
stored.
(cherry picked from commit e6c42f8b2d447bbcc659d6dd33be67335834b2e5)
---
copy/file-ops.c | 4 +++-
copy/main.c | 29 +++++++++++++++++++++++------
copy/nbd-ops.c | 10 ++++++++++
copy/nbdcopy.h | 4 +++-
copy/null-ops.c | 1 +
copy/pipe-ops.c | 1 +
6 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/copy/file-ops.c b/copy/file-ops.c
index ab37875..34f08e5 100644
--- a/copy/file-ops.c
+++ b/copy/file-ops.c
@@ -241,13 +241,15 @@ seek_hole_supported (int fd)
struct rw *
file_create (const char *name, int fd,
- off_t st_size, bool is_block, direction d)
+ off_t st_size, uint64_t preferred,
+ bool is_block, direction d)
{
struct rw_file *rwf = calloc (1, sizeof *rwf);
if (rwf == NULL) { perror ("calloc"); exit (EXIT_FAILURE); }
rwf->rw.ops = &file_ops;
rwf->rw.name = name;
+ rwf->rw.preferred = preferred;
rwf->fd = fd;
rwf->is_block = is_block;
diff --git a/copy/main.c b/copy/main.c
index cc379e9..19ec384 100644
--- a/copy/main.c
+++ b/copy/main.c
@@ -512,10 +512,26 @@ open_local (const char *filename, direction d)
fprintf (stderr, "%s: %s: %m\n", prog, filename);
exit (EXIT_FAILURE);
}
- if (S_ISBLK (stat.st_mode) || S_ISREG (stat.st_mode))
- return file_create (filename, fd, stat.st_size, S_ISBLK (stat.st_mode), d);
- else {
- /* Probably stdin/stdout, a pipe or a socket. */
+ if (S_ISREG (stat.st_mode)) /* Regular file. */
+ return file_create (filename, fd,
+ stat.st_size, (uint64_t) stat.st_blksize, false, d);
+ else if (S_ISBLK (stat.st_mode)) { /* Block device. */
+ unsigned int blkioopt;
+
+#ifdef BLKIOOPT
+ if (ioctl (fd, BLKIOOPT, &blkioopt) == -1) {
+ fprintf (stderr, "warning: cannot get optimal I/O size: %s: %m",
+ filename);
+ blkioopt = 4096;
+ }
+#else
+ blkioopt = 4096;
+#endif
+
+ return file_create (filename, fd,
+ stat.st_size, (uint64_t) blkioopt, true, d);
+ }
+ else { /* Probably stdin/stdout, a pipe or a socket. */
synchronous = true; /* Force synchronous mode for pipes. */
return pipe_create (filename, fd);
}
@@ -528,8 +544,9 @@ print_rw (struct rw *rw, const char *prefix, FILE *fp)
char buf[HUMAN_SIZE_LONGEST];
fprintf (fp, "%s: %s \"%s\"\n", prefix, rw->ops->ops_name, rw->name);
- fprintf (fp, "%s: size=%" PRIi64 " (%s)\n",
- prefix, rw->size, human_size (buf, rw->size, NULL));
+ fprintf (fp, "%s: size=%" PRIi64 " (%s), preferred block size=%" PRIu64 "\n",
+ prefix, rw->size, human_size (buf, rw->size, NULL),
+ rw->preferred);
}
/* Default implementation of rw->ops->get_extents for backends which
diff --git a/copy/nbd-ops.c b/copy/nbd-ops.c
index 3bc26ba..0988634 100644
--- a/copy/nbd-ops.c
+++ b/copy/nbd-ops.c
@@ -112,12 +112,22 @@ open_one_nbd_handle (struct rw_nbd *rwn)
* the same way.
*/
if (rwn->handles.len == 0) {
+ int64_t block_size;
+
rwn->can_zero = nbd_can_zero (nbd) > 0;
+
rwn->rw.size = nbd_get_size (nbd);
if (rwn->rw.size == -1) {
fprintf (stderr, "%s: %s: %s\n", prog, rwn->rw.name, nbd_get_error ());
exit (EXIT_FAILURE);
}
+
+ block_size = nbd_get_block_size (nbd, LIBNBD_SIZE_PREFERRED);
+ if (block_size == -1) {
+ fprintf (stderr, "%s: %s: %s\n", prog, rwn->rw.name, nbd_get_error ());
+ exit (EXIT_FAILURE);
+ }
+ rwn->rw.preferred = block_size == 0 ? 4096 : block_size;
}
if (handles_append (&rwn->handles, nbd) == -1) {
diff --git a/copy/nbdcopy.h b/copy/nbdcopy.h
index 19797df..9438cce 100644
--- a/copy/nbdcopy.h
+++ b/copy/nbdcopy.h
@@ -43,6 +43,7 @@ struct rw {
struct rw_ops *ops; /* Operations. */
const char *name; /* Printable name, for error messages etc. */
int64_t size; /* May be -1 for streams. */
+ uint64_t preferred; /* Preferred block size. */
/* Followed by private data for the particular subtype. */
};
@@ -53,7 +54,8 @@ typedef enum { READING, WRITING } direction;
/* Create subtypes. */
extern struct rw *file_create (const char *name, int fd,
- off_t st_size, bool is_block, direction d);
+ off_t st_size, uint64_t preferred,
+ bool is_block, direction d);
extern struct rw *nbd_rw_create_uri (const char *name,
const char *uri, direction d);
extern struct rw *nbd_rw_create_subprocess (const char **argv, size_t argc,
diff --git a/copy/null-ops.c b/copy/null-ops.c
index 1218a62..99cc9a7 100644
--- a/copy/null-ops.c
+++ b/copy/null-ops.c
@@ -45,6 +45,7 @@ null_create (const char *name)
rw->rw.ops = &null_ops;
rw->rw.name = name;
rw->rw.size = INT64_MAX;
+ rw->rw.preferred = 4096;
return &rw->rw;
}
diff --git a/copy/pipe-ops.c b/copy/pipe-ops.c
index 3c8b6c2..3815f82 100644
--- a/copy/pipe-ops.c
+++ b/copy/pipe-ops.c
@@ -43,6 +43,7 @@ pipe_create (const char *name, int fd)
rwp->rw.ops = &pipe_ops;
rwp->rw.name = name;
rwp->rw.size = -1;
+ rwp->rw.preferred = 4096;
rwp->fd = fd;
return &rwp->rw;
}
--
2.31.1

View File

@ -0,0 +1,318 @@
From 1b0b732e6a9b4979fccf6a09eb6704264edf675d Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 3 Feb 2022 14:25:58 -0600
Subject: [PATCH] copy: CVE-2022-0485: Fail nbdcopy if NBD read or write fails
nbdcopy has a nasty bug when performing multi-threaded copies using
asynchronous nbd calls - it was blindly treating the completion of an
asynchronous command as successful, rather than checking the *error
parameter. This can result in the silent creation of a corrupted
image in two different ways: when a read fails, we blindly wrote
garbage to the destination; when a write fails, we did not flag that
the destination was not written.
Since nbdcopy already calls exit() on a synchronous read or write
failure to a file, doing the same for an asynchronous op to an NBD
server is the simplest solution. A nicer solution, but more invasive
to code and thus not done here, might be to allow up to N retries of
the transaction (in case the read or write failure was transient), or
even having a mode where as much data is copied as possible (portions
of the copy that failed would be logged on stderr, and nbdcopy would
still fail with a non-zero exit status, but this would copy more than
just stopping at the first error, as can be done with rsync or
ddrescue).
Note that since we rely on auto-retiring and do NOT call
nbd_aio_command_completed, our completion callbacks must always return
1 (if they do not exit() first), even when acting on *error, so as not
leave the command allocated until nbd_close. As such, there is no
sane way to return an error to a manual caller of the callback, and
therefore we can drop dead code that calls perror() and exit() if the
callback "failed". It is also worth documenting the contract on when
we must manually call the callback during the asynch_zero callback, so
that we do not leak or double-free the command; thankfully, all the
existing code paths were correct.
The added testsuite script demonstrates several scenarios, some of
which fail without the rest of this patch in place, and others which
showcase ways in which sparse images can bypass errors.
Once backports are complete, a followup patch on the main branch will
edit docs/libnbd-security.pod with the mailing list announcement of
the stable branch commit ids and release versions that incorporate
this fix.
Reported-by: Nir Soffer <nsoffer@redhat.com>
Fixes: bc896eec4d ("copy: Implement multi-conn, multiple threads, multiple requests in flight.", v1.5.6)
Fixes: https://bugzilla.redhat.com/2046194
Message-Id: <20220203202558.203013-6-eblake@redhat.com>
Acked-by: Richard W.M. Jones <rjones@redhat.com>
Acked-by: Nir Soffer <nsoffer@redhat.com>
[eblake: fix error message per Nir, tweak requires lines in unit test per Rich]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit 8d444b41d09a700c7ee6f9182a649f3f2d325abb)
Conflicts:
copy/nbdcopy.h - copyright context
copy/null-ops.c - no backport of 0b16205e "copy: Implement "null:"
destination."
copy/copy-nbd-error.sh - no backport of d5f65e56 ("copy: Do not use
trim for zeroing"), so one test needed an additional error-trim-rate;
no backport of 4ff9e62d (copy: Add --request-size option") and friends, so
this version uses larger transactions, so change error rate of 0.5 to 1;
no backport of 0b16205e "copy: Implement "null:" destination.", so use
nbdkit null instead
Note that while the use of NBD_CMD_TRIM can create data corruption, it is
not as severe as what this patch fixes, since trim corruption will only
expose what had previously been on the disk, compared to this patch fixing
a potential leak of nbdcopy heap contents into the destination.
(cherry picked from commit 6c8f2f859926b82094fb5e85c446ea099700fa10)
---
TODO | 1 +
copy/Makefile.am | 4 +-
copy/copy-nbd-error.sh | 81 +++++++++++++++++++++++++++++++++++++
copy/file-ops.c | 17 +++-----
copy/multi-thread-copying.c | 13 ++++++
copy/nbdcopy.h | 7 ++--
6 files changed, 107 insertions(+), 16 deletions(-)
create mode 100755 copy/copy-nbd-error.sh
diff --git a/TODO b/TODO
index 510c219..19c21d4 100644
--- a/TODO
+++ b/TODO
@@ -35,6 +35,7 @@ nbdcopy:
- Better page cache usage, see nbdkit-file-plugin options
fadvise=sequential cache=none.
- Consider io_uring if there are performance bottlenecks.
+ - Configurable retries in response to read or write failures.
nbdfuse:
- If you write beyond the end of the virtual file, it returns EIO.
diff --git a/copy/Makefile.am b/copy/Makefile.am
index d318388..3406cd8 100644
--- a/copy/Makefile.am
+++ b/copy/Makefile.am
@@ -1,5 +1,5 @@
# nbd client library in userspace
-# Copyright (C) 2020 Red Hat Inc.
+# Copyright (C) 2020-2022 Red Hat Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,7 @@ EXTRA_DIST = \
copy-nbd-to-small-nbd-error.sh \
copy-nbd-to-sparse-file.sh \
copy-nbd-to-stdout.sh \
+ copy-nbd-error.sh \
copy-progress-bar.sh \
copy-sparse.sh \
copy-sparse-allocated.sh \
@@ -105,6 +106,7 @@ TESTS += \
copy-nbd-to-sparse-file.sh \
copy-stdin-to-nbd.sh \
copy-nbd-to-stdout.sh \
+ copy-nbd-error.sh \
copy-progress-bar.sh \
copy-sparse.sh \
copy-sparse-allocated.sh \
diff --git a/copy/copy-nbd-error.sh b/copy/copy-nbd-error.sh
new file mode 100755
index 0000000..bba71db
--- /dev/null
+++ b/copy/copy-nbd-error.sh
@@ -0,0 +1,81 @@
+#!/usr/bin/env bash
+# nbd client library in userspace
+# Copyright (C) 2022 Red Hat Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Tests several scenarios of handling NBD server errors
+# Serves as a regression test for the CVE-2022-0485 fix.
+
+. ../tests/functions.sh
+
+set -e
+set -x
+
+requires nbdkit --exit-with-parent --version
+requires nbdkit --filter=noextents null --version
+requires nbdkit --filter=error pattern --version
+requires nbdkit --filter=nozero memory --version
+
+fail=0
+
+# Failure to get block status should not be fatal, but merely downgrade to
+# reading the entire image as if data
+echo "Testing extents failures on source"
+$VG nbdcopy -- [ nbdkit --exit-with-parent -v --filter=error pattern 5M \
+ error-extents-rate=1 ] [ nbdkit --exit-with-parent -v null 5M ] || fail=1
+
+# Failure to read should be fatal
+echo "Testing read failures on non-sparse source"
+$VG nbdcopy -- [ nbdkit --exit-with-parent -v --filter=error pattern 5M \
+ error-pread-rate=1 ] [ nbdkit --exit-with-parent -v null 5M ] && fail=1
+
+# However, reliable block status on a sparse image can avoid the need to read
+echo "Testing read failures on sparse source"
+$VG nbdcopy -- [ nbdkit --exit-with-parent -v --filter=error null 5M \
+ error-pread-rate=1 ] [ nbdkit --exit-with-parent -v null 5M ] || fail=1
+
+# Failure to write data should be fatal
+echo "Testing write data failures on arbitrary destination"
+$VG nbdcopy -- [ nbdkit --exit-with-parent -v pattern 5M ] \
+ [ nbdkit --exit-with-parent -v --filter=error --filter=noextents \
+ memory 5M error-pwrite-rate=1 ] && fail=1
+
+# However, writing zeroes can bypass the need for normal writes
+echo "Testing write data failures from sparse source"
+$VG nbdcopy -- [ nbdkit --exit-with-parent -v null 5M ] \
+ [ nbdkit --exit-with-parent -v --filter=error --filter=noextents \
+ memory 5M error-pwrite-rate=1 ] || fail=1
+
+# Failure to write zeroes should be fatal
+echo "Testing write zero failures on arbitrary destination"
+$VG nbdcopy -- [ nbdkit --exit-with-parent -v null 5M ] \
+ [ nbdkit --exit-with-parent -v --filter=error memory 5M \
+ error-trim-rate=1 error-zero-rate=1 ] && fail=1
+
+# However, assuming/learning destination is zero can skip need to write
+echo "Testing write failures on pre-zeroed destination"
+$VG nbdcopy --destination-is-zero -- \
+ [ nbdkit --exit-with-parent -v null 5M ] \
+ [ nbdkit --exit-with-parent -v --filter=error memory 5M \
+ error-pwrite-rate=1 error-zero-rate=1 ] || fail=1
+
+# Likewise, when write zero is not advertised, fallback to normal write works
+echo "Testing write zeroes to destination without zero support"
+$VG nbdcopy -- [ nbdkit --exit-with-parent -v null 5M ] \
+ [ nbdkit --exit-with-parent -v --filter=nozero --filter=error memory 5M \
+ error-zero-rate=1 ] || fail=1
+
+exit $fail
diff --git a/copy/file-ops.c b/copy/file-ops.c
index cc312b4..b19af04 100644
--- a/copy/file-ops.c
+++ b/copy/file-ops.c
@@ -162,10 +162,8 @@ file_asynch_read (struct rw *rw,
file_synch_read (rw, slice_ptr (command->slice),
command->slice.len, command->offset);
- if (cb.callback (cb.user_data, &dummy) == -1) {
- perror (rw->name);
- exit (EXIT_FAILURE);
- }
+ /* file_synch_read called exit() on error */
+ cb.callback (cb.user_data, &dummy);
}
static void
@@ -177,10 +175,8 @@ file_asynch_write (struct rw *rw,
file_synch_write (rw, slice_ptr (command->slice),
command->slice.len, command->offset);
- if (cb.callback (cb.user_data, &dummy) == -1) {
- perror (rw->name);
- exit (EXIT_FAILURE);
- }
+ /* file_synch_write called exit() on error */
+ cb.callback (cb.user_data, &dummy);
}
static bool
@@ -206,10 +202,7 @@ file_asynch_zero (struct rw *rw, struct command *command,
if (!file_synch_zero (rw, command->offset, command->slice.len))
return false;
- if (cb.callback (cb.user_data, &dummy) == -1) {
- perror (rw->name);
- exit (EXIT_FAILURE);
- }
+ cb.callback (cb.user_data, &dummy);
return true;
}
diff --git a/copy/multi-thread-copying.c b/copy/multi-thread-copying.c
index 2593ff7..28749ae 100644
--- a/copy/multi-thread-copying.c
+++ b/copy/multi-thread-copying.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include <assert.h>
#include <sys/stat.h>
+#include <inttypes.h>
#include <pthread.h>
@@ -374,6 +375,12 @@ finished_read (void *vp, int *error)
{
struct command *command = vp;
+ if (*error) {
+ fprintf (stderr, "read at offset %" PRId64 " failed: %s\n",
+ command->offset, strerror (*error));
+ exit (EXIT_FAILURE);
+ }
+
if (allocated || sparse_size == 0) {
/* If sparseness detection (see below) is turned off then we write
* the whole command.
@@ -552,6 +559,12 @@ free_command (void *vp, int *error)
struct command *command = vp;
struct buffer *buffer = command->slice.buffer;
+ if (*error) {
+ fprintf (stderr, "write at offset %" PRId64 " failed: %s\n",
+ command->offset, strerror (*error));
+ exit (EXIT_FAILURE);
+ }
+
if (buffer != NULL) {
if (--buffer->refs == 0) {
free (buffer->data);
diff --git a/copy/nbdcopy.h b/copy/nbdcopy.h
index 3dcc6df..9626a52 100644
--- a/copy/nbdcopy.h
+++ b/copy/nbdcopy.h
@@ -1,5 +1,5 @@
/* NBD client library in userspace.
- * Copyright (C) 2020 Red Hat Inc.
+ * Copyright (C) 2020-2022 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -134,7 +134,8 @@ struct rw_ops {
bool (*synch_zero) (struct rw *rw, uint64_t offset, uint64_t count);
/* Asynchronous I/O operations. These start the operation and call
- * 'cb' on completion.
+ * 'cb' on completion. 'cb' will return 1, for auto-retiring with
+ * asynchronous libnbd calls.
*
* The file_ops versions are actually implemented synchronously, but
* still call 'cb'.
@@ -156,7 +157,7 @@ struct rw_ops {
nbd_completion_callback cb);
/* Asynchronously zero. command->slice.buffer is not used. If not possible,
- * returns false.
+ * returns false. 'cb' must be called only if returning true.
*/
bool (*asynch_zero) (struct rw *rw, struct command *command,
nbd_completion_callback cb);
--
2.31.1

View File

@ -1,457 +0,0 @@
From c8626acc63c4ae1c6cf5d1505e0209ac10f44e81 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 28 Jun 2022 21:58:55 +0100
Subject: [PATCH] copy: Use preferred block size for copying
You're not supposed to read or write NBD servers at a granularity less
than the advertised minimum block size. nbdcopy has ignored this
requirement, and this is usually fine because the NBD servers we care
about support 512-byte sector granularity, and never advertise sizes /
extents less granular than sectors (even if it's a bit suboptimal in a
few cases).
However there is one new case where we do care: When writing to a
compressed qcow2 file, qemu advertises a minimum and preferred block
size of 64K, and it really means it. You cannot write blocks smaller
than this because of the way qcow2 compression is implemented.
This commit attempts to do the least work possible to fix this.
The previous multi-thread-copying loop was driven by the extent map
received from the source. I have modified the loop so that it
iterates over request_size blocks. request_size is set from the
command line (--request-size) but will be adjusted upwards if either
the source or destination preferred block size is larger. So this
will always copy blocks which are at least the preferred block size
(except for the very last block of the disk).
While copying these blocks we consult the source extent map. If it
contains only zero regions covering the whole block (only_zeroes
function) then we can skip straight to zeroing the target
(fill_dst_range_with_zeroes), else we do read + write as before.
I only modified the multi-thread-copying loop, not the synchronous
loop. That should be updated in the same way later.
One side effect of this change is it always makes larger requests,
even for regions we know are sparse. This is clear in the
copy-sparse.sh and copy-sparse-allocated.sh tests which were
previously driven by the 32K sparse map granularity of the source.
Without changing these tests, they would make make 256K reads & writes
(and also read from areas of the disk even though we know they are
sparse). I adjusted these tests to use --request-size=32768 to force
the existing behaviour.
Note this doesn't attempt to limit the maximum block size when reading
or writing. That is for future work.
This is a partial fix for https://bugzilla.redhat.com/2047660.
Further changes will be required in virt-v2v.
Link: https://lists.gnu.org/archive/html/qemu-block/2022-01/threads.html#00729
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2047660
(cherry picked from commit 4058fe1ff03fb41156b67302ba1006b9d06b0218)
---
TODO | 4 +-
copy/Makefile.am | 6 +-
copy/copy-file-to-qcow2-compressed.sh | 64 +++++++++++
copy/copy-sparse-allocated.sh | 4 +-
copy/copy-sparse.sh | 7 +-
copy/main.c | 13 +++
copy/multi-thread-copying.c | 149 +++++++++++++++++++-------
copy/nbdcopy.pod | 5 +-
8 files changed, 202 insertions(+), 50 deletions(-)
create mode 100755 copy/copy-file-to-qcow2-compressed.sh
diff --git a/TODO b/TODO
index 7c9c15e..bc38d70 100644
--- a/TODO
+++ b/TODO
@@ -28,7 +28,9 @@ Performance: Chart it over various buffer sizes and threads, as that
Examine other fuzzers: https://gitlab.com/akihe/radamsa
nbdcopy:
- - Minimum/preferred/maximum block size.
+ - Enforce maximum block size.
+ - Synchronous loop should be adjusted to take into account
+ the NBD preferred block size, as was done for multi-thread loop.
- Benchmark.
- Better page cache usage, see nbdkit-file-plugin options
fadvise=sequential cache=none.
diff --git a/copy/Makefile.am b/copy/Makefile.am
index e729f86..25f75c5 100644
--- a/copy/Makefile.am
+++ b/copy/Makefile.am
@@ -23,6 +23,7 @@ EXTRA_DIST = \
copy-file-to-nbd.sh \
copy-file-to-null.sh \
copy-file-to-qcow2.sh \
+ copy-file-to-qcow2-compressed.sh \
copy-nbd-to-block.sh \
copy-nbd-to-file.sh \
copy-nbd-to-hexdump.sh \
@@ -142,7 +143,10 @@ TESTS += \
$(NULL)
if HAVE_QEMU_NBD
-TESTS += copy-file-to-qcow2.sh
+TESTS += \
+ copy-file-to-qcow2.sh \
+ copy-file-to-qcow2-compressed.sh \
+ $(NULL)
endif
if HAVE_GNUTLS
diff --git a/copy/copy-file-to-qcow2-compressed.sh b/copy/copy-file-to-qcow2-compressed.sh
new file mode 100755
index 0000000..dfe4fa5
--- /dev/null
+++ b/copy/copy-file-to-qcow2-compressed.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+# nbd client library in userspace
+# Copyright (C) 2020-2022 Red Hat Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+. ../tests/functions.sh
+
+set -e
+set -x
+
+requires $QEMU_NBD --version
+requires nbdkit --exit-with-parent --version
+requires nbdkit sparse-random --dump-plugin
+requires qemu-img --version
+requires stat --version
+
+file1=copy-file-to-qcow2-compressed.file1
+file2=copy-file-to-qcow2-compressed.file2
+rm -f $file1 $file2
+cleanup_fn rm -f $file1 $file2
+
+size=1G
+seed=$RANDOM
+
+# Create a compressed qcow2 file1.
+#
+# sparse-random files should compress easily because by default each
+# block uses repeated bytes.
+qemu-img create -f qcow2 $file1 $size
+nbdcopy -- [ nbdkit --exit-with-parent sparse-random $size seed=$seed ] \
+ [ $QEMU_NBD --image-opts driver=compress,file.driver=qcow2,file.file.driver=file,file.file.filename=$file1 ]
+
+ls -l $file1
+
+# Create an uncompressed qcow2 file2 with the same data.
+qemu-img create -f qcow2 $file2 $size
+nbdcopy -- [ nbdkit --exit-with-parent sparse-random $size seed=$seed ] \
+ [ $QEMU_NBD --image-opts driver=qcow2,file.driver=file,file.filename=$file2 ]
+
+ls -l $file2
+
+# file1 < file2 (shows the compression is having some effect).
+size1="$( stat -c %s $file1 )"
+size2="$( stat -c %s $file2 )"
+if [ $size1 -ge $size2 ]; then
+ echo "$0: qcow2 compression did not make the file smaller"
+ exit 1
+fi
+
+# Logical content of the files should be identical.
+qemu-img compare -f qcow2 $file1 -F qcow2 $file2
diff --git a/copy/copy-sparse-allocated.sh b/copy/copy-sparse-allocated.sh
index 203c3b9..465e347 100755
--- a/copy/copy-sparse-allocated.sh
+++ b/copy/copy-sparse-allocated.sh
@@ -17,8 +17,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# Adapted from copy-sparse.sh.
-#
-# This test depends on the nbdkit default sparse block size (32K).
. ../tests/functions.sh
@@ -33,7 +31,7 @@ requires nbdkit eval --version
out=copy-sparse-allocated.out
cleanup_fn rm -f $out
-$VG nbdcopy --allocated -- \
+$VG nbdcopy --allocated --request-size=32768 -- \
[ nbdkit --exit-with-parent data data='
1
@1073741823 1
diff --git a/copy/copy-sparse.sh b/copy/copy-sparse.sh
index 1a6da86..7912a21 100755
--- a/copy/copy-sparse.sh
+++ b/copy/copy-sparse.sh
@@ -16,8 +16,6 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-# This test depends on the nbdkit default sparse block size (32K).
-
. ../tests/functions.sh
set -e
@@ -34,8 +32,9 @@ cleanup_fn rm -f $out
# Copy from a sparse data disk to an nbdkit-eval-plugin instance which
# is logging everything. This allows us to see exactly what nbdcopy
# is writing, to ensure it is writing and zeroing the target as
-# expected.
-$VG nbdcopy -S 0 -- \
+# expected. Force request size to match nbdkit default sparse
+# allocator block size (32K).
+$VG nbdcopy -S 0 --request-size=32768 -- \
[ nbdkit --exit-with-parent data data='
1
@1073741823 1
diff --git a/copy/main.c b/copy/main.c
index 19ec384..0e27db8 100644
--- a/copy/main.c
+++ b/copy/main.c
@@ -40,6 +40,7 @@
#include "ispowerof2.h"
#include "human-size.h"
+#include "minmax.h"
#include "version.h"
#include "nbdcopy.h"
@@ -379,10 +380,22 @@ main (int argc, char *argv[])
if (threads < connections)
connections = threads;
+ /* request_size must always be at least as large as the preferred
+ * size of source & destination.
+ */
+ request_size = MAX (request_size, src->preferred);
+ request_size = MAX (request_size, dst->preferred);
+
/* Adapt queue to size to request size if needed. */
if (request_size > queue_size)
queue_size = request_size;
+ /* Sparse size (if using) must not be smaller than the destination
+ * preferred size, otherwise we end up creating too small requests.
+ */
+ if (sparse_size > 0 && sparse_size < dst->preferred)
+ sparse_size = dst->preferred;
+
/* Truncate the destination to the same size as the source. Only
* has an effect on regular files.
*/
diff --git a/copy/multi-thread-copying.c b/copy/multi-thread-copying.c
index 06cdb8e..9267545 100644
--- a/copy/multi-thread-copying.c
+++ b/copy/multi-thread-copying.c
@@ -166,6 +166,62 @@ decrease_queue_size (struct worker *worker, size_t len)
worker->queue_size -= len;
}
+/* Using the extents map 'exts', check if the region
+ * [offset..offset+len-1] intersects only with zero extents.
+ *
+ * The invariant for '*i' is always an extent which starts before or
+ * equal to the current offset.
+ */
+static bool
+only_zeroes (const extent_list exts, size_t *i,
+ uint64_t offset, unsigned len)
+{
+ size_t j;
+
+ /* Invariant. */
+ assert (*i < exts.len);
+ assert (exts.ptr[*i].offset <= offset);
+
+ /* Update the invariant. Search for the last possible extent in the
+ * list which is <= offset.
+ */
+ for (j = *i + 1; j < exts.len; ++j) {
+ if (exts.ptr[j].offset <= offset)
+ *i = j;
+ else
+ break;
+ }
+
+ /* Check invariant again. */
+ assert (*i < exts.len);
+ assert (exts.ptr[*i].offset <= offset);
+
+ /* If *i is not the last extent, then the next extent starts
+ * strictly beyond our current offset.
+ */
+ assert (*i == exts.len - 1 || exts.ptr[*i + 1].offset > offset);
+
+ /* Search forward, look for any non-zero extents overlapping the region. */
+ for (j = *i; j < exts.len; ++j) {
+ uint64_t start, end;
+
+ /* [start..end-1] is the current extent. */
+ start = exts.ptr[j].offset;
+ end = exts.ptr[j].offset + exts.ptr[j].length;
+
+ assert (end > offset);
+
+ if (start >= offset + len)
+ break;
+
+ /* Non-zero extent covering this region => test failed. */
+ if (!exts.ptr[j].zero)
+ return false;
+ }
+
+ return true;
+}
+
/* There are 'threads' worker threads, each copying work ranges from
* src to dst until there are no more work ranges.
*/
@@ -177,7 +233,10 @@ worker_thread (void *wp)
extent_list exts = empty_vector;
while (get_next_offset (&offset, &count)) {
- size_t i;
+ struct command *command;
+ size_t extent_index;
+ bool is_zeroing = false;
+ uint64_t zeroing_start = 0; /* initialized to avoid bogus GCC warning */
assert (0 < count && count <= THREAD_WORK_SIZE);
if (extents)
@@ -185,52 +244,64 @@ worker_thread (void *wp)
else
default_get_extents (src, w->index, offset, count, &exts);
- for (i = 0; i < exts.len; ++i) {
- struct command *command;
- size_t len;
+ extent_index = 0; // index into extents array used to optimize only_zeroes
+ while (count) {
+ const size_t len = MIN (count, request_size);
- if (exts.ptr[i].zero) {
+ if (only_zeroes (exts, &extent_index, offset, len)) {
/* The source is zero so we can proceed directly to skipping,
- * fast zeroing, or writing zeroes at the destination.
+ * fast zeroing, or writing zeroes at the destination. Defer
+ * zeroing so we can send it as a single large command.
*/
- command = create_command (exts.ptr[i].offset, exts.ptr[i].length,
- true, w);
- fill_dst_range_with_zeroes (command);
+ if (!is_zeroing) {
+ is_zeroing = true;
+ zeroing_start = offset;
+ }
}
-
else /* data */ {
- /* As the extent might be larger than permitted for a single
- * command, we may have to split this into multiple read
- * requests.
- */
- while (exts.ptr[i].length > 0) {
- len = exts.ptr[i].length;
- if (len > request_size)
- len = request_size;
-
- command = create_command (exts.ptr[i].offset, len,
- false, w);
-
- wait_for_request_slots (w);
-
- /* NOTE: Must increase the queue size after waiting. */
- increase_queue_size (w, len);
-
- /* Begin the asynch read operation. */
- src->ops->asynch_read (src, command,
- (nbd_completion_callback) {
- .callback = finished_read,
- .user_data = command,
- });
-
- exts.ptr[i].offset += len;
- exts.ptr[i].length -= len;
+ /* If we were in the middle of deferred zeroing, do it now. */
+ if (is_zeroing) {
+ /* Note that offset-zeroing_start can never exceed
+ * THREAD_WORK_SIZE, so there is no danger of overflowing
+ * size_t.
+ */
+ command = create_command (zeroing_start, offset-zeroing_start,
+ true, w);
+ fill_dst_range_with_zeroes (command);
+ is_zeroing = false;
}
+
+ /* Issue the asynchronous read command. */
+ command = create_command (offset, len, false, w);
+
+ wait_for_request_slots (w);
+
+ /* NOTE: Must increase the queue size after waiting. */
+ increase_queue_size (w, len);
+
+ /* Begin the asynch read operation. */
+ src->ops->asynch_read (src, command,
+ (nbd_completion_callback) {
+ .callback = finished_read,
+ .user_data = command,
+ });
}
- offset += count;
- count = 0;
- } /* for extents */
+ offset += len;
+ count -= len;
+ } /* while (count) */
+
+ /* If we were in the middle of deferred zeroing, do it now. */
+ if (is_zeroing) {
+ /* Note that offset-zeroing_start can never exceed
+ * THREAD_WORK_SIZE, so there is no danger of overflowing
+ * size_t.
+ */
+ command = create_command (zeroing_start, offset - zeroing_start,
+ true, w);
+ fill_dst_range_with_zeroes (command);
+ is_zeroing = false;
+ }
}
/* Wait for in flight NBD requests to finish. */
diff --git a/copy/nbdcopy.pod b/copy/nbdcopy.pod
index fd10f7c..f06d112 100644
--- a/copy/nbdcopy.pod
+++ b/copy/nbdcopy.pod
@@ -182,8 +182,9 @@ Set the maximum number of requests in flight per NBD connection.
=item B<--sparse=>N
Detect all zero blocks of size N (bytes) and make them sparse on the
-output. You can also turn off sparse detection using S<I<-S 0>>.
-The default is 4096 bytes.
+output. You can also turn off sparse detection using S<I<-S 0>>. The
+default is 4096 bytes, or the destination preferred block size,
+whichever is larger.
=item B<--synchronous>
--
2.31.1

View File

@ -1,29 +0,0 @@
From 5d21b00dbdd1e1a04317bf16afb8f4d2ceaa470f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 2 Jul 2022 17:12:46 +0100
Subject: [PATCH] dump: Add another example to the manual
(cherry picked from commit be3768b077c9542aba34eb821016c36f31d234af)
---
dump/nbddump.pod | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/dump/nbddump.pod b/dump/nbddump.pod
index 5d7864d..656a965 100644
--- a/dump/nbddump.pod
+++ b/dump/nbddump.pod
@@ -57,6 +57,11 @@ For example, to dump out a qcow2 file as raw data:
nbddump -- [ qemu-nbd -r -f qcow2 file.qcow2 ]
+To dump out an empty floppy disk created by L<nbdkit-floppy-plugin(1)>:
+
+ mkdir /var/tmp/empty
+ nbddump -- [ nbdkit floppy /var/tmp/empty ]
+
Note that S<C<[ ... ]>> are separate parameters, and must be
surrounded by spaces. C<--> separates nbddump parameters from
subprocess parameters.
--
2.31.1

View File

@ -1,93 +0,0 @@
From a432e773e0cdc24cb27ccdda4111744ea2c3b819 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 27 Jul 2022 17:08:14 +0100
Subject: [PATCH] lib/crypto: Use GNUTLS_NO_SIGNAL if available
libnbd has long used MSG_NOSIGNAL to avoid receiving SIGPIPE if we
accidentally write on a closed socket, which is a nice alternative to
using a SIGPIPE signal handler. However with TLS connections, gnutls
did not use this flag and so programs using libnbd + TLS would receive
SIGPIPE in some situations, notably if the server closed the
connection abruptly while we were trying to write something.
GnuTLS 3.4.2 introduces GNUTLS_NO_SIGNAL which does the same thing.
Use this flag if available.
RHEL 7 has an older gnutls which lacks this flag. To avoid qemu-nbd
interop tests failing (rarely, but more often with a forthcoming
change to TLS shutdown behaviour), register a SIGPIPE signal handler
in the test if the flag is missing.
---
configure.ac | 15 +++++++++++++++
interop/interop.c | 10 ++++++++++
lib/crypto.c | 7 ++++++-
3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 49ca8ab..6bd9e1b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,6 +179,21 @@ AS_IF([test "$GNUTLS_LIBS" != ""],[
gnutls_session_set_verify_cert \
gnutls_transport_is_ktls_enabled \
])
+ AC_MSG_CHECKING([if gnutls has GNUTLS_NO_SIGNAL])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([
+ #include <gnutls/gnutls.h>
+ gnutls_session_t session;
+ ], [
+ gnutls_init(&session, GNUTLS_CLIENT|GNUTLS_NO_SIGNAL);
+ ])
+ ], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_GNUTLS_NO_SIGNAL], [1],
+ [GNUTLS_NO_SIGNAL found at compile time])
+ ], [
+ AC_MSG_RESULT([no])
+ ])
LIBS="$old_LIBS"
])
diff --git a/interop/interop.c b/interop/interop.c
index b41f3ca..036545b 100644
--- a/interop/interop.c
+++ b/interop/interop.c
@@ -84,6 +84,16 @@ main (int argc, char *argv[])
REQUIRES
#endif
+ /* Ignore SIGPIPE. We only need this for GnuTLS < 3.4.2, since
+ * newer GnuTLS has the GNUTLS_NO_SIGNAL flag which adds
+ * MSG_NOSIGNAL to each write call.
+ */
+#if !HAVE_GNUTLS_NO_SIGNAL
+#if TLS
+ signal (SIGPIPE, SIG_IGN);
+#endif
+#endif
+
/* Create a large sparse temporary file. */
#ifdef NEEDS_TMPFILE
int fd = mkstemp (TMPFILE);
diff --git a/lib/crypto.c b/lib/crypto.c
index 1272888..ca9520e 100644
--- a/lib/crypto.c
+++ b/lib/crypto.c
@@ -588,7 +588,12 @@ nbd_internal_crypto_create_session (struct nbd_handle *h,
gnutls_psk_client_credentials_t pskcreds = NULL;
gnutls_certificate_credentials_t xcreds = NULL;
- err = gnutls_init (&session, GNUTLS_CLIENT|GNUTLS_NONBLOCK);
+ err = gnutls_init (&session,
+ GNUTLS_CLIENT | GNUTLS_NONBLOCK
+#if HAVE_GNUTLS_NO_SIGNAL
+ | GNUTLS_NO_SIGNAL
+#endif
+ );
if (err < 0) {
set_error (errno, "gnutls_init: %s", gnutls_strerror (err));
return NULL;
--
2.31.1

View File

@ -1,100 +0,0 @@
From 8bbee9c0ff052cf8ab5ba81fd1b67e3c45e7012a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 27 Jul 2022 16:07:37 +0100
Subject: [PATCH] lib/crypto.c: Ignore TLS premature termination after write
shutdown
qemu-nbd doesn't call gnutls_bye to cleanly shut down the connection
after we send NBD_CMD_DISC. When copying from a qemu-nbd server (or
any operation which calls nbd_shutdown) you will see errors like this:
$ nbdcopy nbds://foo?tls-certificates=/var/tmp/pki null:
nbds://foo?tls-certificates=/var/tmp/pki: nbd_shutdown: gnutls_record_recv: The TLS connection was non-properly terminated.
Relatedly you may also see:
nbd_shutdown: gnutls_record_recv: Error in the pull function.
This commit suppresses the error in the case where we know that we
have shut down writes (which happens after NBD_CMD_DISC has been sent
on the wire).
---
interop/interop.c | 9 ---------
lib/crypto.c | 17 +++++++++++++++++
lib/internal.h | 1 +
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/interop/interop.c b/interop/interop.c
index 036545b..cce9407 100644
--- a/interop/interop.c
+++ b/interop/interop.c
@@ -226,19 +226,10 @@ main (int argc, char *argv[])
/* XXX In future test more operations here. */
-#if !TLS
- /* XXX qemu doesn't shut down the connection nicely (using
- * gnutls_bye) and because of this the following call will fail
- * with:
- *
- * nbd_shutdown: gnutls_record_recv: The TLS connection was
- * non-properly terminated.
- */
if (nbd_shutdown (nbd, 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
-#endif
nbd_close (nbd);
diff --git a/lib/crypto.c b/lib/crypto.c
index ca9520e..aa5d820 100644
--- a/lib/crypto.c
+++ b/lib/crypto.c
@@ -187,6 +187,22 @@ tls_recv (struct nbd_handle *h, struct socket *sock, void *buf, size_t len)
errno = EAGAIN;
return -1;
}
+ if (h->tls_shut_writes &&
+ (r == GNUTLS_E_PULL_ERROR || r == GNUTLS_E_PREMATURE_TERMINATION)) {
+ /* qemu-nbd doesn't call gnutls_bye to cleanly shut down the
+ * connection after we send NBD_CMD_DISC, instead it simply
+ * closes the connection. On the client side we see
+ * "gnutls_record_recv: The TLS connection was non-properly
+ * terminated" or "gnutls_record_recv: Error in the pull
+ * function.".
+ *
+ * If we see these errors after we shut down the write side
+ * (h->tls_shut_writes), which happens after we have sent
+ * NBD_CMD_DISC on the wire, downgrade them to a debug message.
+ */
+ debug (h, "gnutls_record_recv: %s", gnutls_strerror (r));
+ return 0; /* EOF */
+ }
set_error (0, "gnutls_record_recv: %s", gnutls_strerror (r));
errno = EIO;
return -1;
@@ -234,6 +250,7 @@ tls_shut_writes (struct nbd_handle *h, struct socket *sock)
return false;
if (r != 0)
debug (h, "ignoring gnutls_bye failure: %s", gnutls_strerror (r));
+ h->tls_shut_writes = true;
return sock->u.tls.oldsock->ops->shut_writes (h, sock->u.tls.oldsock);
}
diff --git a/lib/internal.h b/lib/internal.h
index 6aaced3..f1b4c63 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -307,6 +307,7 @@ struct nbd_handle {
struct command *reply_cmd;
bool disconnect_request; /* True if we've queued NBD_CMD_DISC */
+ bool tls_shut_writes; /* Used by lib/crypto.c to track disconnect. */
};
struct meta_context {
--
2.31.1

View File

@ -6,7 +6,7 @@ set -e
# directory. Use it like this:
# ./copy-patches.sh
rhel_version=9.1
rhel_version=8.6
# Check we're in the right directory.
if [ ! -f libnbd.spec ]; then

View File

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmLhNK4RHHJpY2hAYW5u
ZXhpYS5vcmcACgkQkXOPc+G3aKDzmxAArFrR/cOyqyGZXuYORFRVi7AobCjum4dP
A93R43shnSXXB1CTww5O+LjIghSLs4TEQAOcmcsjsE98X2cz0BuW6gIfGxTpN3WP
fGPDlvezLXGo5zX5WGFkP6oQY97TuGHXKNxStZtWRtDNfrWPWJQuwlm5GSIHdYYr
dFssmDNtIoh/zQz2www9JKspMfehFbTGZswtRjfDwa2Pl69cMy3pH/k4EZZnDx9n
tguzQHOapJJx8RkIwUwFirCBOwdVNbLX+KrGroLcB6MjO6Uhh2C/iYUQDM/xX2r6
1SugssAmXwZ4/RIDtwBLdQdEoNjSAV7OW1yizTl5P9qFkiPr+Lpnpt4gci9bTZKK
oIy0RtgJOgW5R2tuRlMXkx/7kcGjhUb3Zbux7d7dgrYq16FUPC1dFgub7WSPSqWe
+17iUD+n3NO2MHtR215nKDjuPR59wnvATO6QS+InOb4imyf47Ic7TeEvVuDhb+M3
+DvIor2WyXWX9kO165Fx9jAicgZJt2L1UvKM1GzGjwBdL0GYbCFltzzhyi4Pd/7x
ijV2QYbyOLXYEpsgmKYrT6MwwXUAye2PkXSv8MaOs3IiFz0bVy3Bfgx4UYNbKo1x
zwVGtIBz39tXpgyS7+F9rvQILVmENGmyTx+GXrv/lE1mFmTt/EEyf+iHMSN1lIkt
59o9LBpOajI=
=idnt
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAl/3RFQRHHJpY2hAYW5u
ZXhpYS5vcmcACgkQkXOPc+G3aKD9aw/+Pfg3owjJmhTcCyFvuH2lgiiBb+qL2An+
hsoax6dM5JxzV6x1Ikgn3C8z2+dLRMowo2FrRgpzTwfaS+ngLDipSC04hKl9MhFN
7OPLCm+L7wcP7KUk4cC0qTSHpHkApo2SP3/bD7vVBYZMYSjgUVFcRoqZlRl3N9RF
7XNsxA2YG9bV4Ln3KbB+k2uxIKNUZIVjmEpretVbb+NTKW9C23ZHicSHYB+Eok1M
iTN6j66rYFn0Xb+L2v7jty19tSdYOMbkdSn0KpniURAWevjjVWGqcojMqW4YuAZ5
h2MpRfyKFyusbsbtX5bjICTu6+AgFFUALKH7ReDs1RY1cEph9XdBLVulXTggxY05
E3I1Nns1YmjRlV6ky2Abl2e+Doc44mycINRlwL2q8+Q3TqlVVPFXoVTWxIJ6/Uae
tqnEwWIa2wGv3KU1KLNbWTn1z6I8NM/Nj+7pMKDNnxJzFmHEjL94tmG+iNmHsF34
vWBZ1q7h9EezxHLOPFYDjlpS+IxeuXakbpuTX2jXvi3zSAbr5WmRR1uO8dAiwu9b
RwOHRmVQOFLAAICYTZDmxl42DpWs5Z2aP7eRwpe8/MOSRiAVepjhUD/bsdaFwmBR
8Z7CGNzyTtt+sy5l7cPBYZ+4RdxWgFEBceBbHs06zdlD/Pui288UQVB/0e9AXYOc
wluyWT1v7sA=
=BaN1
-----END PGP SIGNATURE-----

View File

@ -1,6 +1,3 @@
# Do this until the feature is fixed in Fedora.
%undefine _package_note_flags
# If we should verify tarball signature with GPGv2.
%global verify_tarball_signature 1
@ -8,15 +5,15 @@
%global patches_touch_autotools 1
# The source directory.
%global source_directory 1.12-stable
%global source_directory 1.6-stable
Name: libnbd
Version: 1.12.6
Release: 1%{?dist}
Version: 1.6.0
Release: 5%{?dist}
Summary: NBD client library in userspace
License: LGPLv2+
URL: https://gitlab.com/nbdkit/libnbd
URL: https://github.com/libguestfs/libnbd
Source0: http://libguestfs.org/download/libnbd/%{source_directory}/%{name}-%{version}.tar.gz
Source1: http://libguestfs.org/download/libnbd/%{source_directory}/%{name}-%{version}.tar.gz.sig
@ -28,20 +25,17 @@ Source2: libguestfs.keyring
# Maintainer script which helps with handling patches.
Source3: copy-patches.sh
# Patches are stored in the upstream repository:
# https://gitlab.com/nbdkit/libnbd/-/commits/rhel-9.1/
# Patches come from this upstream branch:
# https://github.com/libguestfs/libnbd/tree/rhel-8.6
# Patches.
Patch0001: 0001-Add-nbddump-tool.patch
Patch0002: 0002-dump-Visually-separate-columns-0-7-and-8-15.patch
Patch0003: 0003-dump-Fix-build-on-i686.patch
Patch0004: 0004-dump-Fix-tests-on-Debian-10.patch
Patch0005: 0005-dump-dump-data.sh-Test-requires-nbdkit-1.22.patch
Patch0006: 0006-copy-Store-the-preferred-block-size-in-the-operation.patch
Patch0007: 0007-copy-Use-preferred-block-size-for-copying.patch
Patch0008: 0008-dump-Add-another-example-to-the-manual.patch
Patch0009: 0009-lib-crypto-Use-GNUTLS_NO_SIGNAL-if-available.patch
Patch0010: 0010-lib-crypto.c-Ignore-TLS-premature-termination-after-.patch
Patch0001: 0001-copy-copy-nbd-to-sparse-file.sh-Skip-test-unless-nbd.patch
Patch0002: 0002-generator-Refactor-CONNECT.START-state.patch
Patch0003: 0003-generator-Print-a-better-error-message-if-connect-2-.patch
Patch0004: 0004-opt_go-Tolerate-unplanned-server-death.patch
Patch0005: 0005-security-Document-assignment-of-CVE-2021-20286.patch
Patch0006: 0006-copy-Pass-in-dummy-variable-rather-than-errno-to-cal.patch
Patch0007: 0007-copy-CVE-2022-0485-Fail-nbdcopy-if-NBD-read-or-write.patch
%if 0%{patches_touch_autotools}
BuildRequires: autoconf, automake, libtool
@ -53,13 +47,12 @@ BuildRequires: gnupg2
# For the core library.
BuildRequires: gcc
BuildRequires: make
BuildRequires: /usr/bin/pod2man
BuildRequires: gnutls-devel
BuildRequires: libxml2-devel
# For nbdfuse.
BuildRequires: fuse3, fuse3-devel
BuildRequires: fuse, fuse-devel
# For the Python 3 bindings.
BuildRequires: python3-devel
@ -79,28 +72,20 @@ BuildRequires: bash-completion
BuildRequires: coreutils
BuildRequires: gcc-c++
BuildRequires: gnutls-utils
BuildRequires: iproute
BuildRequires: jq
%if !0%{?rhel}
BuildRequires: nbd
%endif
BuildRequires: util-linux
# On RHEL, maybe even in Fedora in future, we do not build qemu-img or
# nbdkit for i686. These are only needed for the test suite so make
# them optional. This reduces our test exposure on 32 bit platforms,
# although there is still Fedora/armv7 and some upstream testing.
#BuildRequires: jq
%ifnarch %{ix86}
BuildRequires: qemu-img
BuildRequires: nbdkit
BuildRequires: nbdkit-data-plugin
BuildRequires: nbdkit-eval-plugin
#BuildRequires: nbdkit-eval-plugin
BuildRequires: nbdkit-memory-plugin
BuildRequires: nbdkit-null-plugin
BuildRequires: nbdkit-pattern-plugin
BuildRequires: nbdkit-sh-plugin
BuildRequires: nbdkit-sparse-random-plugin
#BuildRequires: nbdkit-sparse-random-plugin
#BuildRequires: nbd
BuildRequires: qemu-img
%endif
BuildRequires: util-linux
%description
@ -172,7 +157,6 @@ python3-%{name} contains Python 3 bindings for %{name}.
Summary: FUSE support for %{name}
License: LGPLv2+ and BSD
Requires: %{name}%{?_isa} = %{version}-%{release}
Recommends: fuse3
%description -n nbdfuse
@ -195,7 +179,8 @@ for %{name}.
%prep
%if 0%{verify_tarball_signature}
%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
tmphome="$(mktemp -d)"
gpgv2 --homedir "$tmphome" --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0}
%endif
%autosetup -p1
%if 0%{patches_touch_autotools}
@ -227,36 +212,28 @@ rm $RPM_BUILD_ROOT%{_mandir}/man3/libnbd-golang.3*
%check
function skip_test ()
{
for f in "$@"; do
rm -f "$f"
echo 'exit 77' > "$f"
chmod +x "$f"
done
}
# interop/structured-read.sh fails with the old qemu-nbd in Fedora 29,
# so disable it there.
%if 0%{?fedora} <= 29
skip_test interop/structured-read.sh
%endif
# interop/interop-qemu-storage-daemon.sh fails in RHEL 9 because of
# this bug in qemu:
# https://lists.nongnu.org/archive/html/qemu-devel/2021-03/threads.html#03544
%if 0%{?rhel}
skip_test interop/interop-qemu-storage-daemon.sh
rm interop/structured-read.sh
touch interop/structured-read.sh
chmod +x interop/structured-read.sh
%endif
# All fuse tests fail in Koji with:
# fusermount: entry for fuse/test-*.d not found in /etc/mtab
# for unknown reasons but probably related to the Koji environment.
skip_test fuse/test-*.sh
for f in fuse/test-*.sh; do
rm $f
touch $f
chmod +x $f
done
# IPv6 loopback connections fail in Koji.
make -C tests connect-tcp6 ||:
skip_test tests/connect-tcp6
# info/info-map-base-allocation-json.sh fails because of a bug in
# jq 1.5 in RHEL 8 (fixed in later versions).
rm info/info-map-base-allocation-json.sh
touch info/info-map-base-allocation-json.sh
chmod +x info/info-map-base-allocation-json.sh
make %{?_smp_mflags} check || {
for f in $(find -name test-suite.log); do
@ -272,11 +249,9 @@ make %{?_smp_mflags} check || {
%doc README
%license COPYING.LIB
%{_bindir}/nbdcopy
%{_bindir}/nbddump
%{_bindir}/nbdinfo
%{_libdir}/libnbd.so.*
%{_mandir}/man1/nbdcopy.1*
%{_mandir}/man1/nbddump.1*
%{_mandir}/man1/nbdinfo.1*
@ -331,288 +306,50 @@ make %{?_smp_mflags} check || {
%files bash-completion
%dir %{_datadir}/bash-completion/completions
%{_datadir}/bash-completion/completions/nbdcopy
%{_datadir}/bash-completion/completions/nbddump
%{_datadir}/bash-completion/completions/nbdfuse
%{_datadir}/bash-completion/completions/nbdinfo
%{_datadir}/bash-completion/completions/nbdsh
%changelog
* Thu Jul 28 2022 Richard W.M. Jones <rjones@redhat.com> - 1.12.6-1
- Rebase to new stable branch version 1.12.6
resolves: rhbz#2059288
- New tool: nbddump
- nbdcopy: Use preferred block size for copying
related: rhbz#2047660
- Fix remote TLS failures
resolves: rhbz#2111524
(and 2111813)
* Mon Feb 7 2022 Richard W.M. Jones <rjones@redhat.com> - 1.6.0-5.el8
- Fix CVE-2022-0485: Fail nbdcopy if NBD read or write fails
resolves: rhbz#2045718
* Thu Feb 10 2022 Richard W.M. Jones <rjones@redhat.com> - 1.10.5-1
- Rebase to new stable branch version 1.10.5
resolves: rhbz#2011708
- Map uint32_t to OCaml int64 to avoid signedness problems
resolves: rhbz#2040610
- CVE-2022-0485 nbdcopy destination image corruption
- New upstream API to control initialization of pread buffer
resolves: rhbz#2046194
* Thu Sep 2 2021 Danilo C. L. de Paula <ddepaula@redhat.com> - 1.6.0-4.el8
- Resolves: bz#2000225
(Rebase virt:rhel module:stream based on AV-8.6)
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.8.2-3
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Mon Jul 13 2020 Danilo C. L. de Paula <ddepaula@redhat.com> - 1.2.2
- Resolves: bz#1844296
(Upgrade components in virt:rhel module:stream for RHEL-8.3 release)
* Fri Jul 30 2021 Richard W.M. Jones <rjones@redhat.com> - 1.8.2-2
- Fix nbdcopy progress bar.
- Add nbdinfo --map --totals and --can/--is options.
resolves: rhbz#1950630
* Wed Feb 5 2020 Richard W.M. Jones <rjones@redhat.com> - 1.2.2-1
- New stable release 1.2.2.
* Sat Jul 03 2021 Richard W.M. Jones <rjones@redhat.com> - 1.8.2-1
- New upstream stable version 1.8.2.
* Wed Jun 23 2021 Richard W.M. Jones <rjones@redhat.com> - 1.8.1-2
- Bump and rebuild
resolves: rhbz#1975316
* Fri Jun 11 2021 Richard W.M. Jones <rjones@redhat.com> - 1.8.1-1
- New upstream stable version 1.8.1.
* Mon Jun 07 2021 Richard W.M. Jones <rjones@redhat.com> - 1.8.0-1
- New upstream version 1.8.0.
* Fri Jun 04 2021 Python Maint <python-maint@redhat.com> - 1.7.12-2
- Rebuilt for Python 3.10
* Sat May 29 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.12-1
- New upstream version 1.7.12.
* Thu May 20 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.11-1
- New upstream version 1.7.11.
* Fri May 14 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.10-1
- New upstream version 1.7.10.
* Thu Apr 29 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.9-1
- New upstream version 1.7.9.
- Switch to fuse3.
- Make nbdfuse package recommend fuse3 (to get fusermount3).
* Sat Apr 24 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.8-1
- New upstream development version 1.7.8.
* Sat Apr 10 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.7-1
- New upstream development version 1.7.7.
- +BR iproute
- Add skip_test helper function.
- Skip connect-tcp6 test which fails under Koji.
* Thu Apr 08 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.6-1
- New upstream development version 1.7.6.
* Sat Apr 03 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.5-1
- New upstream development version 1.7.5.
* Mon Mar 15 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.4-1
- New upstream development version 1.7.4.
* Mon Mar 15 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.3-3
- Update documentation for CVE-2021-20286.
- Workaround broken interop/interop-qemu-storage-daemon.sh test in RHEL 9.
* Thu Mar 4 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.3-2
- Add fix for nbdkit test suite.
* Tue Mar 2 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.3-1
- New upstream version 1.7.3.
* Mon Mar 1 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.2-3
- OCaml 4.12.0 build
* Wed Feb 24 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.2-2
- Disable nbd BR on RHEL.
* Mon Feb 22 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.2-1
- New upstream version 1.7.2.
* Fri Jan 29 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.1-6
- Disable BR qemu-img on i686.
* Thu Jan 28 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.1-3
- Disable BR nbdkit on i686 because it breaks ELN/RHEL 9.
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Wed Jan 20 2021 Richard W.M. Jones <rjones@redhat.com> - 1.7.1-1
- New upstream development version 1.7.1.
* Thu Jan 07 2021 Richard W.M. Jones <rjones@redhat.com> - 1.6.0-1
- New upstream stable version 1.6.0.
* Tue Dec 08 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.9-1
- New upstream development version 1.5.9.
* Thu Dec 03 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.8-1
- New upstream development version 1.5.8.
- Unify Fedora and RHEL spec files.
* Wed Nov 25 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.7-1
- New upstream development version 1.5.7.
- Add some more test suite buildrequires lines.
- Fix bogus date in changelog.
* Thu Nov 12 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.6-1
- New upstream development version 1.5.6.
* Mon Nov 02 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.5-1
- New upstream development version 1.5.5.
* Mon Oct 05 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.4-1
- New upstream development version 1.5.4.
- More OCaml man pages.
* Sat Sep 26 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.3-1
- New upstream development version 1.5.3.
* Thu Sep 10 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.2-1
- New upstream development version 1.5.2.
* Tue Sep 08 2020 Richard W.M. Jones <rjones@redhat.com> - 1.5.1-1
- New upstream development version 1.5.1.
* Tue Sep 01 2020 Richard W.M. Jones <rjones@redhat.com> - 1.4.0-2
- OCaml 4.11.1 rebuild
* Tue Aug 25 2020 Richard W.M. Jones <rjones@redhat.com> - 1.4.0-1
- New stable release 1.4.0.
* Fri Aug 21 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.12-3
- Bump release and rebuild.
* Fri Aug 21 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.12-2
- OCaml 4.11.0 rebuild
* Thu Aug 20 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.12-1
- New upstream version 1.3.12.
* Thu Aug 6 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.11-1
- New upstream version 1.3.11.
* Tue Aug 4 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.10-1
- New upstream version 1.3.10.
* Wed Jul 29 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.9-3
- Bump and rebuild.
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.9-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jul 21 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.9-1
- New upstream version 1.3.9.
- New tool: nbdinfo.
* Fri Jul 17 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.8-2
- New upstream version 1.3.8.
- New tool: nbdcopy
- Add upstream patch to fix compilation with glibc from Rawhide.
* Tue May 26 2020 Miro Hrončok <mhroncok@redhat.com> - 1.3.7-3
- Rebuilt for Python 3.9
* Mon May 04 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.7-2
- OCaml 4.11.0+dev2-2020-04-22 rebuild
* Thu Apr 23 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.7-1
- New upstream version 1.3.7.
* Tue Apr 21 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.6-5
- OCaml 4.11.0 pre-release attempt 2
* Fri Apr 17 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.6-4
- OCaml 4.11.0 pre-release
- Add upstream patch to fix one of the tests that fails on slow machines.
* Thu Apr 02 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.6-2
- Update all OCaml dependencies for RPM 4.16.
* Tue Mar 31 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.6-1
- New upstream development version 1.3.6.
- Golang bindings are contained in this release but not distributed.
* Wed Mar 11 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.5-2
- Fix bogus runtime Requires of new bash-completion package.
* Tue Mar 10 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.5-1
- New upstream development version 1.3.5.
- Add new bash-completion subpackage.
* Sat Feb 29 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.4-1
- New upstream development version 1.3.4.
* Wed Feb 26 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.3-2
- OCaml 4.10.0 final.
* Wed Feb 05 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.3-1
- New upstream development version 1.3.3.
* Thu Jan 30 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.2-1
- New upstream development version 1.3.2.
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.1-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Sun Jan 19 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.1-4
- Bump release and rebuild.
* Sun Jan 19 2020 Richard W.M. Jones <rjones@redhat.com> - 1.3.1-3
- OCaml 4.10.0+beta1 rebuild.
* Thu Dec 12 2019 Richard W.M. Jones <rjones@redhat.com> - 1.3.1-2
- Rebuild for OCaml 4.09.0.
* Tue Dec 03 2019 Richard W.M. Jones <rjones@redhat.com> - 1.3.1-1
- New upstream development version 1.3.1.
* Wed Nov 27 2019 Richard W.M. Jones <rjones@redhat.com> - 1.2.0-2
- Use gpgverify macro instead of explicit gpgv2 command.
* Tue Dec 3 2019 Richard W.M. Jones <rjones@redhat.com> - 1.2.1-1
- New stable release 1.2.1.
* Thu Nov 14 2019 Richard W.M. Jones <rjones@redhat.com> - 1.2.0-1
- New stable release 1.2.0
- New stable release 1.2.0.
* Sat Nov 09 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.9-1
- New upstream version 1.1.9.
- Add new nbdkit-release-notes-1.2(1) man page.
* Wed Nov 06 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.8-1
- New upstream version 1.1.8.
* Thu Oct 24 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.7-1
- New upstream version 1.1.7.
* Sat Oct 19 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.6-1
- New upstream version 1.1.6.
* Sat Oct 12 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.5-1
- New upstream version 1.1.5.
- New tool and subpackage nbdfuse.
* Wed Oct 9 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.4-1
- New upstream version 1.1.4.
* Wed Oct 9 2019 Richard W.M. Jones <rjones@redhat.com> - 1.0.3-1
- New upstream version 1.0.3.
- Contains fix for remote code execution vulnerability.
- Add new libnbd-security(3) man page.
* Tue Oct 1 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.3-1
- New upstream version 1.1.3.
* Tue Sep 17 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.2-1
- New upstream version 1.1.2.
* Tue Sep 17 2019 Richard W.M. Jones <rjones@redhat.com> - 1.0.2-1
- New upstream version 1.0.2.
- Remove patches which are upstream.
- Contains fix for NBD Protocol Downgrade Attack (CVE-2019-14842).
- Fix previous commit message.
* Thu Sep 12 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.1-2
* Thu Sep 12 2019 Richard W.M. Jones <rjones@redhat.com> - 1.0.1-2
- Add upstream patch to fix nbdsh (for nbdkit tests).
- Fix interop tests on slow machines.
* Sun Sep 08 2019 Richard W.M. Jones <rjones@redhat.com> - 1.1.1-1
- New development version 1.1.1.
* Sun Sep 08 2019 Richard W.M. Jones <rjones@redhat.com> - 1.0.1-1
- New stable version 1.0.1.
* Wed Aug 28 2019 Richard W.M. Jones <rjones@redhat.com> - 1.0.0-1
- New upstream version 1.0.0.