From db943f43a60d1b5b1277e4b5317e8f288e7a0a3a Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 17 Jan 2020 17:39:19 +0000 Subject: [PATCH] Detect EOF while reading in libssl 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 Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/10882) --- crypto/bio/bss_sock.c | 5 +++++ crypto/err/openssl.txt | 1 + include/openssl/bio.h | 1 + include/openssl/sslerr.h | 3 ++- ssl/record/rec_layer_s3.c | 6 ++++++ ssl/ssl_err.c | 4 +++- 6 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c index da818ca90e..3ad989adf2 100644 --- a/crypto/bio/bss_sock.c +++ b/crypto/bio/bss_sock.c @@ -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; diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index f4a14ccb82..10444a17f9 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -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 diff --git a/include/openssl/bio.h b/include/openssl/bio.h index e1fddfb796..9e2bcddc3e 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -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; diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index 3d6850dea3..b6cac4f5f5 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -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 diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 9e23b4fb3b..d5d511f48a 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -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); diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 4b12ed1485..a0c7b79659 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -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"}, -- GitLab