import libnbd-1.6.0-5.module+el8.6.0+14480+c0a3aa0f

This commit is contained in:
CentOS Sources 2022-05-10 03:02:51 -04:00 committed by Stepan Oksanichenko
parent 414cf8d093
commit c05826a118
13 changed files with 871 additions and 29 deletions

2
.gitignore vendored
View File

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

View File

@ -1,2 +1,2 @@
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
68e213e85346cc7b9c390e2a4916c7b3f30345e1 SOURCES/libnbd-1.2.2.tar.gz
b14ac9349d324df71d26cf3de9fb606c56f18cb0 SOURCES/libnbd-1.6.0.tar.gz

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

@ -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

@ -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

@ -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

@ -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

@ -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

55
SOURCES/copy-patches.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/bash -
set -e
# Maintainer script to copy patches from the git repo to the current
# directory. Use it like this:
# ./copy-patches.sh
rhel_version=8.6
# Check we're in the right directory.
if [ ! -f libnbd.spec ]; then
echo "$0: run this from the directory containing 'libnbd.spec'"
exit 1
fi
git_checkout=$HOME/d/libnbd-rhel-$rhel_version
if [ ! -d $git_checkout ]; then
echo "$0: $git_checkout does not exist"
echo "This script is only for use by the maintainer when preparing a"
echo "libnbd release on RHEL."
exit 1
fi
# Get the base version of libnbd.
version=`grep '^Version:' libnbd.spec | awk '{print $2}'`
tag="v$version"
# Remove any existing patches.
git rm -f [0-9]*.patch ||:
rm -f [0-9]*.patch
# Get the patches.
(cd $git_checkout; rm -f [0-9]*.patch; git format-patch -N $tag)
mv $git_checkout/[0-9]*.patch .
# Remove any not to be applied.
rm -f *NOT-FOR-RPM*.patch
# Add the patches.
git add [0-9]*.patch
# Print out the patch lines.
echo
echo "--- Copy the following text into libnbd.spec file"
echo
echo "# Patches."
for f in [0-9]*.patch; do
n=`echo $f | awk -F- '{print $1}'`
echo "Patch$n: $f"
done
echo
echo "--- End of text"

View File

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAl46yJwRHHJpY2hAYW5u
ZXhpYS5vcmcACgkQkXOPc+G3aKBNsBAAi+GGHQZ/2VZ/LiqO+kc5hzAsbxfCUb6e
epLTmHry0sFdDFGeVwaYZxvnALu61nybMvaHsASW8FlWDbtgaqx6tUApgeV46oXb
yvT1EzmxR4+U8cwb9IEDRBjB1WWqYv+TYltljkV5nmO1DADOZr9AV5yRp872SWsP
oshiuuxwIw+ugQfXkyhUPgyO2FzjxntmWCjD13nQhDeD42UQUE+0mxAgXiGfsOj4
eArCsa4Us/ZWpg9QkoXomzpN1xzMoTEQ9a+7PVTn54bfCCgThdodVN5rNxuNhSKU
yYHl6hUW1gnZaQ17FfqZrOcEFjvVnDYDlkoHF9Vp4AOTNMCd/w008NjKt+yR90WW
yeiJ21mRpkA/6pK5irHEBMFmk9cf/5IIhgF9Xtl5erqKYQu6W5NqXr4BCTdDS4BL
auHV+I8Dqi9IEH8bhZYxErS/eba6N6ZJWkwHqbdwtfZBBSqEcZXrTXviXw0BpCsy
lPGx2xXXmGPB5/BojOmFOEzfPMtiLsLrVW5DwlBoeT90kFEhi7+bGB5gJ24NxL1y
/2XcTxRhv79FMBdLx+6O7/js/tMrOxmKRkUcInU4rjOg+VGmwx6+LeJ2P0au8ufx
8Rvk7DHUF0ZazsbJ4IkL0XP4jWIgB2xMJqjIq+E2duLO+c1sDUBxoU43BgCLYUV9
92Ap8fwsbvA=
=zo1m
-----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

@ -2,14 +2,14 @@
%global verify_tarball_signature 1
# If there are patches which touch autotools files, set this to 1.
%global patches_touch_autotools %{nil}
%global patches_touch_autotools 1
# The source directory.
%global source_directory 1.2-stable
%global source_directory 1.6-stable
Name: libnbd
Version: 1.2.2
Release: 1%{?dist}
Version: 1.6.0
Release: 5%{?dist}
Summary: NBD client library in userspace
License: LGPLv2+
@ -22,6 +22,21 @@ Source1: http://libguestfs.org/download/libnbd/%{source_directory}/%{name
# https://pgp.key-server.io/pks/lookup?search=rjones%40redhat.com&fingerprint=on&op=vindex
Source2: libguestfs.keyring
# Maintainer script which helps with handling patches.
Source3: copy-patches.sh
# Patches come from this upstream branch:
# https://github.com/libguestfs/libnbd/tree/rhel-8.6
# Patches.
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
%endif
@ -45,21 +60,32 @@ BuildRequires: python3-devel
# For the OCaml bindings.
BuildRequires: ocaml
BuildRequires: ocaml-findlib-devel
BuildRequires: ocaml-ocamldoc
# Only for building the examples.
BuildRequires: glib2-devel
# For bash-completion.
BuildRequires: bash-completion
# Only for running the test suite.
BuildRequires: coreutils
BuildRequires: gcc-c++
BuildRequires: gnutls-utils
#BuildRequires: jq
%ifnarch %{ix86}
BuildRequires: nbdkit
#BuildRequires: nbdkit-memory-plugin
#BuildRequires: nbdkit-null-plugin
#BuildRequires: nbdkit-pattern-plugin
#BuildRequires: nbdkit-sh-plugin
BuildRequires: nbdkit-data-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: nbd
BuildRequires: qemu-img
%endif
BuildRequires: gcc-c++
BuildRequires: util-linux
%description
@ -137,6 +163,20 @@ Requires: %{name}%{?_isa} = %{version}-%{release}
This package contains FUSE support for %{name}.
%package bash-completion
Summary: Bash tab-completion for %{name}
BuildArch: noarch
Requires: bash-completion >= 2.0
# Don't use _isa here because it's a noarch package. This dependency
# is just to ensure that the subpackage is updated along with libnbd.
Requires: %{name} = %{version}-%{release}
%description bash-completion
Install this package if you want intelligent bash tab-completion
for %{name}.
%prep
%if 0%{verify_tarball_signature}
tmphome="$(mktemp -d)"
@ -155,7 +195,8 @@ autoreconf -i
PYTHON=%{__python3} \
--enable-python \
--enable-ocaml \
--enable-fuse
--enable-fuse \
--disable-golang
make %{?_smp_mflags}
@ -166,6 +207,9 @@ make %{?_smp_mflags}
# Delete libtool crap.
find $RPM_BUILD_ROOT -name '*.la' -delete
# Delete the golang man page since we're not distributing the bindings.
rm $RPM_BUILD_ROOT%{_mandir}/man3/libnbd-golang.3*
%check
# interop/structured-read.sh fails with the old qemu-nbd in Fedora 29,
@ -185,6 +229,12 @@ for f in fuse/test-*.sh; do
chmod +x $f
done
# 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
echo
@ -198,7 +248,11 @@ make %{?_smp_mflags} check || {
%files
%doc README
%license COPYING.LIB
%{_bindir}/nbdcopy
%{_bindir}/nbdinfo
%{_libdir}/libnbd.so.*
%{_mandir}/man1/nbdcopy.1*
%{_mandir}/man1/nbdinfo.1*
%files devel
@ -231,6 +285,8 @@ make %{?_smp_mflags} check || {
%{_libdir}/ocaml/nbd/*.cmx
%{_libdir}/ocaml/nbd/*.mli
%{_mandir}/man3/libnbd-ocaml.3*
%{_mandir}/man3/NBD.3*
%{_mandir}/man3/NBD.*.3*
%files -n python3-%{name}
@ -247,7 +303,23 @@ make %{?_smp_mflags} check || {
%{_mandir}/man1/nbdfuse.1*
%files bash-completion
%dir %{_datadir}/bash-completion/completions
%{_datadir}/bash-completion/completions/nbdcopy
%{_datadir}/bash-completion/completions/nbdfuse
%{_datadir}/bash-completion/completions/nbdinfo
%{_datadir}/bash-completion/completions/nbdsh
%changelog
* 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 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 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)