From 841d0fbe37642bc14c4bcd515cfbc91a25ba179b Mon Sep 17 00:00:00 2001 From: Matthias Dahl Date: Mon, 12 Mar 2018 15:33:45 +0100 Subject: [PATCH 1/3] Fix GnuTLS error handling * src/gnutls.c (emacs_gnutls_read): All error handling should be done in `emacs_gnutls_handle_error', move handling of GNUTLS_E_UNEXPECTED_PACKET_LENGTH accordingly. We always need to set `errno' in case of an error, since later error handling (e.g. `wait_reading_process_output') depends on it and GnuTLS does not set errno by itself. We'll otherwise have random errno values which can cause erratic behavior and hangs. (emacs_gnutls_handle_error): GNUTLS_E_UNEXPECTED_PACKET_LENGTH is only returned for premature connection termination on GnuTLS < 3.0 and is otherwise a real error and should not be gobbled up. --- src/gnutls.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/gnutls.c b/src/gnutls.c index 903393fed1..e7d0d3d845 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -708,16 +708,18 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, ptrdiff_t nbyte) rtnval = gnutls_record_recv (state, buf, nbyte); if (rtnval >= 0) return rtnval; - else if (rtnval == GNUTLS_E_UNEXPECTED_PACKET_LENGTH) - /* The peer closed the connection. */ - return 0; else if (emacs_gnutls_handle_error (state, rtnval)) - /* non-fatal error */ - return -1; - else { - /* a fatal error occurred */ - return 0; - } + { + /* non-fatal error */ + errno = EAGAIN; + return -1; + } + else + { + /* a fatal error occurred */ + errno = EPROTO; + return 0; + } } static char const * @@ -756,8 +758,10 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err) connection. */ # ifdef HAVE_GNUTLS3 if (err == GNUTLS_E_PREMATURE_TERMINATION) - level = 3; +# else + if (err == GNUTLS_E_UNEXPECTED_PACKET_LENGTH) # endif + level = 3; GNUTLS_LOG2 (level, max_log_level, "fatal error:", str); ret = false; -- 2.16.2