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