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