From: Sean Bright Date: Mon, 5 Feb 2018 22:46:26 +0000 (-0500) Subject: AST-2018-006: Properly handle WebSocket frames with 0 length payload. X-Git-Tag: 15.3.0-rc1~4^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1a4691741705e5426de38580b8c3d985d4e78af;p=thirdparty%2Fasterisk.git AST-2018-006: Properly handle WebSocket frames with 0 length payload. In ast_websocket_read() we were not adequately checking that the payload_len was non-zero before passing it to ws_safe_read(). Calling ws_safe_read with a len argument of 0 will result in a busy loop until the underlying socket is closed. ASTERISK-27658 #close Change-Id: I9d59f83bc563f711df1a6197c57de473f6b0663a --- diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c index 9e5506f2a7..aaaba7d130 100644 --- a/res/res_http_websocket.c +++ b/res/res_http_websocket.c @@ -495,13 +495,20 @@ const char * AST_OPTIONAL_API_NAME(ast_websocket_session_id)(struct ast_websocke * Note during the header parsing stage we try to read in small chunks just what we need, this * is buffered data anyways, no expensive syscall required most of the time ... */ -static inline int ws_safe_read(struct ast_websocket *session, char *buf, int len, enum ast_websocket_opcode *opcode) +static inline int ws_safe_read(struct ast_websocket *session, char *buf, size_t len, enum ast_websocket_opcode *opcode) { ssize_t rlen; int xlen = len; char *rbuf = buf; int sanity = 10; + ast_assert(len > 0); + + if (!len) { + errno = EINVAL; + return -1; + } + ao2_lock(session); if (!session->stream) { ao2_unlock(session); @@ -615,9 +622,12 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha return -1; } - if (ws_safe_read(session, *payload, *payload_len, opcode)) { - return -1; + if (*payload_len) { + if (ws_safe_read(session, *payload, *payload_len, opcode)) { + return -1; + } } + /* If a mask is present unmask the payload */ if (mask_present) { unsigned int pos;