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