]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AST-2018-007: iostreams potential DoS when client connection closed prematurely
authorSean Bright <sean.bright@gmail.com>
Mon, 16 Apr 2018 19:13:58 +0000 (15:13 -0400)
committerKevin Harwell <kharwell@digium.com>
Tue, 8 May 2018 16:35:01 +0000 (11:35 -0500)
Before Asterisk sends an HTTP response (at least in the case of errors),
it attempts to read & discard the content of the request. If the client
lies about the Content-Length, or the connection is closed from the
client side before "Content-Length" bytes are sent, the request handling
thread will busy loop.

ASTERISK-27807

Change-Id: I945c5fc888ed92be625b8c35039fc6d2aa89c762

main/iostream.c

index 4cddd43b6b7cfd95190f65ad531f717a9bf430c4..20188cb7a0d04fe3fc33eb13bdc895a65c081b78 100644 (file)
@@ -197,11 +197,18 @@ static ssize_t iostream_read(struct ast_iostream *stream, void *buf, size_t size
                                        }
                                }
                                break;
+                       case SSL_ERROR_SYSCALL:
+                               /* Some non-recoverable I/O error occurred. The OpenSSL error queue may
+                                * contain more information on the error. For socket I/O on Unix systems,
+                                * consult errno for details. */
+                               ast_debug(1, "TLS non-recoverable I/O error occurred: %s, %s\n", ERR_error_string(sslerr, err),
+                                       ssl_error_to_string(sslerr, res));
+                               return -1;
                        default:
                                /* Report EOF for an undecoded SSL or transport error. */
                                ast_debug(1, "TLS transport or SSL error reading data:  %s, %s\n", ERR_error_string(sslerr, err),
                                        ssl_error_to_string(sslerr, res));
-                               return 0;
+                               return -1;
                        }
                        if (!ms) {
                                /* Report EOF for a timeout */
@@ -317,7 +324,7 @@ ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size)
 
        while (remaining) {
                ret = ast_iostream_read(stream, buf, remaining > sizeof(buf) ? sizeof(buf) : remaining);
-               if (ret < 0) {
+               if (ret <= 0) {
                        return ret;
                }
                remaining -= ret;