[Pkg-voip-commits] [asterisk] 05/06: AST-2014-019.patch: fixes websocket issue

tzafrir at debian.org tzafrir at debian.org
Tue Dec 16 11:08:38 UTC 2014


This is an automated email from the git hooks/post-receive script.

tzafrir pushed a commit to branch jessie
in repository asterisk.

commit 3e31c98cd7a151544020aa0e2a648ae7b0fa6867
Author: Tzafrir Cohen <tzafrir at debian.org>
Date:   Tue Dec 16 13:00:45 2014 +0200

    AST-2014-019.patch: fixes websocket issue
    
    Remote Crash Vulnerability in WebSocket Server (Closes: #773230).
---
 debian/changelog                  |  2 +
 debian/patches/AST-2014-019.patch | 99 +++++++++++++++++++++++++++++++++++++++
 debian/patches/series             |  1 +
 3 files changed, 102 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 93da007..df0b7f9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -8,6 +8,8 @@ asterisk (1:11.13.1~dfsg-2) unstable; urgency=medium
     - AST-2014-014: High call load may result in hung channels in ConfBridge
     - AST-2014-017: Mark CONFBRIDGE as a sensitive function for external APIs
     - AST-2014-018: Mark DB as a sensitive function for external APIs
+  * AST-2014-019.patch (CVE-2014-9374): Remote Crash Vulnerability in
+    WebSocket Server (Closes: #773230).
   * sanity check to avoid changing the ABI hash
 
  -- Tzafrir Cohen <tzafrir at debian.org>  Wed, 10 Dec 2014 06:44:45 +0200
diff --git a/debian/patches/AST-2014-019.patch b/debian/patches/AST-2014-019.patch
new file mode 100644
index 0000000..0e3e696
--- /dev/null
+++ b/debian/patches/AST-2014-019.patch
@@ -0,0 +1,99 @@
+From 029aa170547847860608f194f1040bdf8f910460 Mon Sep 17 00:00:00 2001
+From: Joshua Colp <jcolp at digium.com>
+Date: Wed, 10 Dec 2014 13:30:22 +0000
+Subject: Remote Crash Vulnerability in WebSocket Server
+CVE: CVE-2014-9374
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=429270
+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-24472
+
+Frames with a payload length of 0 were incorrectly handled in
+res_http_websocket. Provided a frame with a payload had been received
+prior it was possible for a double free to occur. The realloc operation
+would succeed (thus freeing the payload) but be treated as an error.
+When the session was then torn down the payload would be freed again
+causing a crash. The read function now takes this into account.
+
+This change also fixes assumptions made by users of res_http_websocket.
+There is no guarantee that a frame received from it will be NULL
+terminated.
+
+In the default configuration, the websocket server is not used.
+
+Review: https://reviewboard.asterisk.org/r/4220/
+Review: https://reviewboard.asterisk.org/r/4219/
+See Also: http://downloads.asterisk.org/pub/security/AST-2014-019.html
+---
+ channels/chan_sip.c      |  6 +++++-
+ res/res_http_websocket.c | 27 ++++++++++++++++-----------
+ 2 files changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/channels/chan_sip.c b/channels/chan_sip.c
+index 8ac9aae..5c6a8437 100644
+--- a/channels/chan_sip.c
++++ b/channels/chan_sip.c
+@@ -2596,12 +2596,16 @@ static void sip_websocket_callback(struct ast_websocket *session, struct ast_var
+ 
+ 		if (opcode == AST_WEBSOCKET_OPCODE_TEXT || opcode == AST_WEBSOCKET_OPCODE_BINARY) {
+ 			struct sip_request req = { 0, };
++			char data[payload_len + 1];
+ 
+ 			if (!(req.data = ast_str_create(payload_len + 1))) {
+ 				goto end;
+ 			}
+ 
+-			if (ast_str_set(&req.data, -1, "%s", payload) == AST_DYNSTR_BUILD_FAILED) {
++			strncpy(data, payload, payload_len);
++			data[payload_len] = '\0';
++
++			if (ast_str_set(&req.data, -1, "%s", data) == AST_DYNSTR_BUILD_FAILED) {
+ 				deinit_req(&req);
+ 				goto end;
+ 			}
+diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
+index 5258a5f..81fa83d 100644
+--- a/res/res_http_websocket.c
++++ b/res/res_http_websocket.c
+@@ -462,14 +462,6 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
+ 			}
+ 		}
+ 
+-		if (!(new_payload = ast_realloc(session->payload, (session->payload_len + *payload_len)))) {
+-			ast_log(LOG_WARNING, "Failed allocation: %p, %zu, %"PRIu64"\n",
+-				session->payload, session->payload_len, *payload_len);
+-			*payload_len = 0;
+-			ast_websocket_close(session, 1009);
+-			return 0;
+-		}
+-
+ 		/* Per the RFC for PING we need to send back an opcode with the application data as received */
+ 		if ((*opcode == AST_WEBSOCKET_OPCODE_PING) && (ast_websocket_write(session, AST_WEBSOCKET_OPCODE_PONG, *payload, *payload_len))) {
+ 			*payload_len = 0;
+@@ -477,9 +469,22 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
+ 			return 0;
+ 		}
+ 
+-		session->payload = new_payload;
+-		memcpy((session->payload + session->payload_len), (*payload), (*payload_len));
+-		session->payload_len += *payload_len;
++		if (*payload_len) {
++			if (!(new_payload = ast_realloc(session->payload, (session->payload_len + *payload_len)))) {
++				ast_log(LOG_WARNING, "Failed allocation: %p, %zu, %"PRIu64"\n",
++					session->payload, session->payload_len, *payload_len);
++				*payload_len = 0;
++				ast_websocket_close(session, 1009);
++				return 0;
++			}
++
++			session->payload = new_payload;
++			memcpy((session->payload + session->payload_len), (*payload), (*payload_len));
++			session->payload_len += *payload_len;
++		} else if (!session->payload_len && session->payload) {
++			ast_free(session->payload);
++			session->payload = NULL;
++		}
+ 
+ 		if (!fin && session->reconstruct && (session->payload_len < session->reconstruct)) {
+ 			/* If this is not a final message we need to defer returning it until later */
+-- 
+2.1.3
+
diff --git a/debian/patches/series b/debian/patches/series
index 7257b80..ef501eb 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -38,3 +38,4 @@ AST-2014-012.patch
 AST-2014-014.patch
 AST-2014-017.patch
 AST-2014-018.patch
+AST-2014-019.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/asterisk.git



More information about the Pkg-voip-commits mailing list