[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Tue May 9 09:43:06 UTC 2017


The branch master has been updated
       via  068e3d73ce6814879832c9400c10afe2458c2004 (commit)
      from  fa3ed5b2c2b508a6444124fdf12ecbb4898007ed (commit)


- Log -----------------------------------------------------------------
commit 068e3d73ce6814879832c9400c10afe2458c2004
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Apr 26 14:00:35 2017 +0100

    Fix an s_server infinite loop
    
    Commit c4666bfa changed s_server so that it asked libssl rather than the
    underlying socket whether an error is retryable or not on the basis that
    libssl has more information. That is true unfortunately the method used
    was wrong - it only checks libssl's own internal state rather than both
    libssl and the BIO. Should use SSL_get_error() instead.
    
    This issue can cause an infinite loop because some errors could appear as
    retryable when in fact they are not.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    Reviewed-by: Tim Hudson <tjh at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3317)

-----------------------------------------------------------------------

Summary of changes:
 apps/s_server.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/apps/s_server.c b/apps/s_server.c
index e597ecb..815549b 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -2609,6 +2609,16 @@ static void close_accept_socket(void)
     }
 }
 
+static int is_retryable(SSL *con, int i)
+{
+    int err = SSL_get_error(con, i);
+
+    /* If it's not a fatal error, it must be retryable */
+    return (err != SSL_ERROR_SSL)
+           && (err != SSL_ERROR_SYSCALL)
+           && (err != SSL_ERROR_ZERO_RETURN);
+}
+
 static int init_ssl_connection(SSL *con)
 {
     int i;
@@ -2651,7 +2661,7 @@ static int init_ssl_connection(SSL *con)
         i = SSL_accept(con);
 
         if (i <= 0)
-            retry = !SSL_want_nothing(con);
+            retry = is_retryable(con, i);
 #ifdef CERT_CB_TEST_RETRY
         {
             while (i <= 0
@@ -2661,7 +2671,7 @@ static int init_ssl_connection(SSL *con)
                            "LOOKUP from certificate callback during accept\n");
                 i = SSL_accept(con);
                 if (i <= 0)
-                    retry = !SSL_want_nothing(con);
+                    retry = is_retryable(con, i);
             }
         }
 #endif
@@ -2682,7 +2692,7 @@ static int init_ssl_connection(SSL *con)
                 BIO_printf(bio_s_out, "LOOKUP not successful\n");
             i = SSL_accept(con);
             if (i <= 0)
-                retry = !SSL_want_nothing(con);
+                retry = is_retryable(con, i);
         }
 #endif
     } while (i < 0 && SSL_waiting_for_async(con));


More information about the openssl-commits mailing list