aboutsummaryrefslogtreecommitdiffstats
path: root/main/asterisk/AST-2018-007.patch
blob: 1b641af13484c09742b8b1650de54780a58b92d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
From 380b5ae0a1e4a68bfb098319a7ab86d3d34c2fcb Mon Sep 17 00:00:00 2001
From: Sean Bright <sean.bright@gmail.com>
Date: Mon, 16 Apr 2018 15:13:58 -0400
Subject: [PATCH 1/1] AST-2018-007: iostreams potential DoS when client
 connection closed prematurely

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 | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/main/iostream.c b/main/iostream.c
index 4cddd43b6b..20188cb7a0 100644
--- a/main/iostream.c
+++ b/main/iostream.c
@@ -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;
-- 
2.19.0