Detect EOF while reading in libssl
authorMatt Caswell <matt@openssl.org>
Fri, 17 Jan 2020 17:39:19 +0000 (17:39 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 20 Feb 2020 17:02:30 +0000 (17:02 +0000)
If we hit an EOF while reading in libssl then we will report an error
back to the application (SSL_ERROR_SYSCALL) but errno will be 0. We add
an error to the stack (which means we instead return SSL_ERROR_SSL) and
therefore give a hint as to what went wrong.

Contains a partial fix for #10880

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/10882)

crypto/bio/bss_sock.c
crypto/err/openssl.txt
include/openssl/bio.h
include/openssl/sslerr.h
ssl/record/rec_layer_s3.c
ssl/ssl_err.c

index da818ca90e813cf6737395eecc709dc0c124c997..3ad989adf21f134ec783f02ef2da721fe0b18629 100644 (file)
@@ -101,6 +101,8 @@ static int sock_read(BIO *b, char *out, int outl)
         if (ret <= 0) {
             if (BIO_sock_should_retry(ret))
                 BIO_set_retry_read(b);
+            else if (ret == 0)
+                b->flags |= BIO_FLAGS_IN_EOF;
         }
     }
     return ret;
@@ -151,6 +153,9 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
     case BIO_CTRL_FLUSH:
         ret = 1;
         break;
+    case BIO_CTRL_EOF:
+        ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
+        break;
     default:
         ret = 0;
         break;
index f4a14ccb82247bb153c222254ad2f66257219ee5..10444a17f90c6e6985531e5873d7ad6c688325f9 100644 (file)
@@ -2851,6 +2851,7 @@ SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES:242:unable to load ssl3 md5 routines
 SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines
 SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message
 SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data
+SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading
 SSL_R_UNEXPECTED_MESSAGE:244:unexpected message
 SSL_R_UNEXPECTED_RECORD:245:unexpected record
 SSL_R_UNINITIALIZED:276:uninitialized
index e1fddfb7969d6e1eb6013902e521769e6c3e768b..9e2bcddc3e19d8e97e99ce37467e0de169a5fe1a 100644 (file)
@@ -169,6 +169,7 @@ extern "C" {
  */
 # define BIO_FLAGS_MEM_RDONLY    0x200
 # define BIO_FLAGS_NONCLEAR_RST  0x400
+# define BIO_FLAGS_IN_EOF        0x800
 
 typedef union bio_addr_st BIO_ADDR;
 typedef struct bio_addrinfo_st BIO_ADDRINFO;
index 3d6850dea36e26bd02646ca04effefcd7cb21acc..b6cac4f5f55b18b7309a9f6b9864f8990d0bebb7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -733,6 +733,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES          243
 # define SSL_R_UNEXPECTED_CCS_MESSAGE                     262
 # define SSL_R_UNEXPECTED_END_OF_EARLY_DATA               178
+# define SSL_R_UNEXPECTED_EOF_WHILE_READING               294
 # define SSL_R_UNEXPECTED_MESSAGE                         244
 # define SSL_R_UNEXPECTED_RECORD                          245
 # define SSL_R_UNINITIALIZED                              276
index 9e23b4fb3b5b9e3b7eddf91597a60ee2e2e3e8f4..d5d511f48af73b23f4ef0e48d5fe93ce1457049a 100644 (file)
@@ -296,6 +296,12 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold,
             ret = BIO_read(s->rbio, pkt + len + left, max - left);
             if (ret >= 0)
                 bioread = ret;
+            if (ret <= 0
+                    && !BIO_should_retry(s->rbio)
+                    && BIO_eof(s->rbio)) {
+                SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_READ_N,
+                         SSL_R_UNEXPECTED_EOF_WHILE_READING);
+            }
         } else {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_N,
                      SSL_R_READ_BIO_NOT_SET);
index 4b12ed1485d985360ad5b50b90f4618333055471..a0c7b79659d4d7f06b6cb7a68d64331777d967b8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -1205,6 +1205,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
     "unexpected ccs message"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_END_OF_EARLY_DATA),
     "unexpected end of early data"},
+    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_EOF_WHILE_READING),
+    "unexpected eof while reading"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_MESSAGE), "unexpected message"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_RECORD), "unexpected record"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNINITIALIZED), "uninitialized"},