Richard W.M. Jones
2022-Jul-28 14:19 UTC
[Libguestfs] [PATCH libnbd v2 1/3] lib/crypto: Use GNUTLS_NO_SIGNAL if available
libnbd has long used MSG_NOSIGNAL to avoid receiving SIGPIPE if we accidentally write on a closed socket, which is a nice alternative to using a SIGPIPE signal handler. However with TLS connections, gnutls did not use this flag and so programs using libnbd + TLS would receive SIGPIPE in some situations, notably if the server closed the connection abruptly while we were trying to write something. GnuTLS 3.4.2 introduces GNUTLS_NO_SIGNAL which does the same thing. Use this flag if available. RHEL 7 has an older gnutls which lacks this flag. To avoid qemu-nbd interop tests failing (rarely, but more often with a forthcoming change to TLS shutdown behaviour), register a SIGPIPE signal handler in the test if the flag is missing. --- interop/interop.c | 8 ++++++++ lib/crypto.c | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/interop/interop.c b/interop/interop.c index f3437d7dea..bd5dc2e196 100644 --- a/interop/interop.c +++ b/interop/interop.c @@ -84,6 +84,14 @@ main (int argc, char *argv[]) REQUIRES #endif + /* Ignore SIGPIPE. We only need this for GnuTLS that lacks the + * GNUTLS_NO_SIGNAL flag, either because it predates GnuTLS 3.4.2 or + * because the OS lacks MSG_NOSIGNAL support. + */ +#if TLS && !defined(HAVE_GNUTLS_NO_SIGNAL) + signal (SIGPIPE, SIG_IGN); +#endif + /* Create a large sparse temporary file. */ #ifdef NEEDS_TMPFILE int fd = mkstemp (TMPFILE); diff --git a/lib/crypto.c b/lib/crypto.c index 9d6332c6c9..7ff83c2314 100644 --- a/lib/crypto.c +++ b/lib/crypto.c @@ -606,8 +606,13 @@ nbd_internal_crypto_create_session (struct nbd_handle *h, gnutls_session_t session; gnutls_psk_client_credentials_t pskcreds = NULL; gnutls_certificate_credentials_t xcreds = NULL; + gnutls_init_flags_t init_flags; - err = gnutls_init (&session, GNUTLS_CLIENT|GNUTLS_NONBLOCK); + init_flags = GNUTLS_CLIENT | GNUTLS_NONBLOCK; +#ifdef GNUTLS_NO_SIGNAL + init_flags |= GNUTLS_NO_SIGNAL; +#endif + err = gnutls_init (&session, init_flags); if (err < 0) { set_error (errno, "gnutls_init: %s", gnutls_strerror (err)); return NULL; -- 2.37.0.rc2
Eric Blake
2022-Jul-28 17:12 UTC
[Libguestfs] [PATCH libnbd v2 1/3] lib/crypto: Use GNUTLS_NO_SIGNAL if available
On Thu, Jul 28, 2022 at 03:19:08PM +0100, Richard W.M. Jones wrote:> libnbd has long used MSG_NOSIGNAL to avoid receiving SIGPIPE if we > accidentally write on a closed socket, which is a nice alternative to > using a SIGPIPE signal handler. However with TLS connections, gnutls > did not use this flag and so programs using libnbd + TLS would receive > SIGPIPE in some situations, notably if the server closed the > connection abruptly while we were trying to write something. > > GnuTLS 3.4.2 introduces GNUTLS_NO_SIGNAL which does the same thing. > Use this flag if available. > > RHEL 7 has an older gnutls which lacks this flag. To avoid qemu-nbd > interop tests failing (rarely, but more often with a forthcoming > change to TLS shutdown behaviour), register a SIGPIPE signal handler > in the test if the flag is missing.Stale comment in the parenthesis?> --- > interop/interop.c | 8 ++++++++ > lib/crypto.c | 7 ++++++- > 2 files changed, 14 insertions(+), 1 deletion(-)Reviewed-by: Eric Blake <eblake at redhat.com> -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org