summaryrefslogtreecommitdiff
path: root/res/res_http_websocket.c
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-06-12 21:08:40 +0000
committerDavid M. Lee <dlee@digium.com>2013-06-12 21:08:40 +0000
commit1e9faaf78a9caa4f03f456bf027aa139c31783f2 (patch)
tree0719a55f806e2c2ec352738f8b8181c193d07ad1 /res/res_http_websocket.c
parent272dd008d08b93c96cbab94fd2bcd607152681f7 (diff)
Fix segfault for certain invalid WebSocket input.
The WebSocket code would allocate, on the stack, a string large enough to hold a key provided by the client, and the WEBSOCKET_GUID. If the key is NULL, this causes a segfault. If the key is too large, it could overflow the stack. This patch checks the key for NULL and checks the length of the key to avoid stack smashing nastiness. (closes issue ASTERISK-21825) Reported by: Alfred Farrugia Tested by: Alfred Farrugia, David M. Lee Patches: issueA21825_check_if_key_is_sent.patch uploaded by Walter Doekes (license 5674) ........ Merged revisions 391560 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@391561 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_http_websocket.c')
-rw-r--r--res/res_http_websocket.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index d96564af8..077c2126a 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -577,9 +577,18 @@ int ast_websocket_uri_cb(struct ast_tcptls_session_instance *ser, const struct a
/* Version 7 defined in specification http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07 */
/* Version 8 defined in specification http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10 */
/* Version 13 defined in specification http://tools.ietf.org/html/rfc6455 */
- char combined[strlen(key) + strlen(WEBSOCKET_GUID) + 1], base64[64];
+ char *combined, base64[64];
+ unsigned combined_length;
uint8_t sha[20];
+ combined_length = (key ? strlen(key) : 0) + strlen(WEBSOCKET_GUID) + 1;
+ if (!key || combined_length > 8192) { /* no stack overflows please */
+ fputs("HTTP/1.1 400 Bad Request\r\n"
+ "Sec-WebSocket-Version: 7, 8, 13\r\n\r\n", ser->f);
+ ao2_ref(protocol_handler, -1);
+ return 0;
+ }
+
if (!(session = ao2_alloc(sizeof(*session), session_destroy_fn))) {
ast_log(LOG_WARNING, "WebSocket connection from '%s' could not be accepted\n",
ast_sockaddr_stringify(&ser->remote_address));
@@ -589,7 +598,8 @@ int ast_websocket_uri_cb(struct ast_tcptls_session_instance *ser, const struct a
return 0;
}
- snprintf(combined, sizeof(combined), "%s%s", key, WEBSOCKET_GUID);
+ combined = ast_alloca(combined_length);
+ snprintf(combined, combined_length, "%s%s", key, WEBSOCKET_GUID);
ast_sha1_hash_uint(sha, combined);
ast_base64encode(base64, (const unsigned char*)sha, 20, sizeof(base64));