summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2022-01-25 14:51:54 +0000
committertb <>2022-01-25 14:51:54 +0000
commit56f1827674a9cecf117e0379d088fef1b23cf017 (patch)
tree683f235762f0b56515db57db8fb805b022b9c1a2 /src
parentbe0df1ec7b55ec791e94f3cfe98ac567d5dba1ee (diff)
downloadopenbsd-56f1827674a9cecf117e0379d088fef1b23cf017.tar.gz
openbsd-56f1827674a9cecf117e0379d088fef1b23cf017.tar.bz2
openbsd-56f1827674a9cecf117e0379d088fef1b23cf017.zip
Avoid an infinite loop in SSL_shutdown()
If the peer closed the write side of the connection and we have not yet received the close_notify, SSL_shutdown() makes an extra read to try and read the peer's close_notify from the pipe. In that situation, we receive EOF. The legacy stack will return -1 while the TLSv1.3 stack will end up returning 0. Since the documentation is not super explicit about what should be done if SSL_shutdown() returns 0, some applications will enter an infinite loop. The code and documentation indicate that SSL_shutdown() should only be called once more if it returned 0. Newer versions of the OpenSSL documentation explicitly say that one should call SSL_read() if SSL_shutdown() returns 0 in order to retrieve the close_notify. Doing this would also have avoided this infinite loop. Reported by Carsten Arzig and bluhm with a test case extracted from the syslogd tests using IO::Socket::SSL, which has such an infinite loop. ok bluhm jsing
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/tls13_legacy.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/lib/libssl/tls13_legacy.c b/src/lib/libssl/tls13_legacy.c
index e54db03e3c..7327311c7b 100644
--- a/src/lib/libssl/tls13_legacy.c
+++ b/src/lib/libssl/tls13_legacy.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls13_legacy.c,v 1.33 2021/12/16 06:32:56 tb Exp $ */ 1/* $OpenBSD: tls13_legacy.c,v 1.34 2022/01/25 14:51:54 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -507,7 +507,7 @@ tls13_legacy_shutdown(SSL *ssl)
507 } else if (!ctx->close_notify_recv) { 507 } else if (!ctx->close_notify_recv) {
508 /* 508 /*
509 * If there is no application data pending, attempt to read more 509 * If there is no application data pending, attempt to read more
510 * data in order to receive a close notify. This should trigger 510 * data in order to receive a close-notify. This should trigger
511 * a record to be read from the wire, which may be application 511 * a record to be read from the wire, which may be application
512 * handshake or alert data. Only one attempt is made to match 512 * handshake or alert data. Only one attempt is made to match
513 * previous semantics. 513 * previous semantics.
@@ -516,6 +516,8 @@ tls13_legacy_shutdown(SSL *ssl)
516 if ((ret = tls13_read_application_data(ctx->rl, buf, 516 if ((ret = tls13_read_application_data(ctx->rl, buf,
517 sizeof(buf))) < 0) 517 sizeof(buf))) < 0)
518 return tls13_legacy_return_code(ssl, ret); 518 return tls13_legacy_return_code(ssl, ret);
519 if (!ctx->close_notify_recv)
520 return -1;
519 } 521 }
520 } 522 }
521 523