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
This commit is contained in:
parent
f063ea650e
commit
6436137959
|
@ -488,13 +488,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
|
* 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 ...
|
* 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;
|
ssize_t rlen;
|
||||||
int xlen = len;
|
int xlen = len;
|
||||||
char *rbuf = buf;
|
char *rbuf = buf;
|
||||||
int sanity = 10;
|
int sanity = 10;
|
||||||
|
|
||||||
|
ast_assert(len > 0);
|
||||||
|
|
||||||
|
if (!len) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ao2_lock(session);
|
ao2_lock(session);
|
||||||
if (!session->stream) {
|
if (!session->stream) {
|
||||||
ao2_unlock(session);
|
ao2_unlock(session);
|
||||||
|
@ -608,9 +615,12 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ws_safe_read(session, *payload, *payload_len, opcode)) {
|
if (*payload_len) {
|
||||||
return -1;
|
if (ws_safe_read(session, *payload, *payload_len, opcode)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a mask is present unmask the payload */
|
/* If a mask is present unmask the payload */
|
||||||
if (mask_present) {
|
if (mask_present) {
|
||||||
unsigned int pos;
|
unsigned int pos;
|
||||||
|
|
Loading…
Reference in New Issue