From 59ae83d07eebbbad9c51038fea106cf735548f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jeremy=20Lain=C3=A9?= <jeremy.laine@m4x.org> Date: Wed, 23 Jan 2019 11:45:56 +0100 Subject: [PATCH] res_http_websocket: ensure control frames do not interfere with data Control frames (PING / PONG / CLOSE) can be received in the middle of a fragmented message. In order to ensure they do not interfere with the reassembly buffer, we exit early and do not return the payload to the caller. ASTERISK-28257 #close Change-Id: Ia5367144fe08ac6141bba3309517a48ec7f013bc --- res/res_http_websocket.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c index 2ac5541430..e8301df204 100644 --- a/res/res_http_websocket.c +++ b/res/res_http_websocket.c @@ -617,9 +617,17 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha } /* 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))) { + if (*opcode == AST_WEBSOCKET_OPCODE_PING) { + if (ast_websocket_write(session, AST_WEBSOCKET_OPCODE_PONG, *payload, *payload_len)) { + ast_websocket_close(session, 1009); + } + *payload_len = 0; + return 0; + } + + /* Stop PONG processing here */ + if (*opcode == AST_WEBSOCKET_OPCODE_PONG) { *payload_len = 0; - ast_websocket_close(session, 1009); return 0; } @@ -633,6 +641,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha return 0; } + /* Below this point we are handling TEXT, BINARY or CONTINUATION opcodes */ 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", -- GitLab