Blame SOURCES/0010-lib-crypto.c-Ignore-TLS-premature-termination-after-.patch

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