diff options
| author | tb <> | 2022-01-25 14:51:54 +0000 |
|---|---|---|
| committer | tb <> | 2022-01-25 14:51:54 +0000 |
| commit | 56f1827674a9cecf117e0379d088fef1b23cf017 (patch) | |
| tree | 683f235762f0b56515db57db8fb805b022b9c1a2 /src | |
| parent | be0df1ec7b55ec791e94f3cfe98ac567d5dba1ee (diff) | |
| download | openbsd-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.c | 6 |
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 | ||
