]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_websocket: Fix buffer overrun when processing TEXT websocket frames.
authorGeorge Joseph <gjoseph@sangoma.com>
Tue, 19 Aug 2025 15:46:39 +0000 (09:46 -0600)
committerAsterisk Development Team <asteriskteam@digium.com>
Wed, 10 Sep 2025 20:18:53 +0000 (20:18 +0000)
ast_websocket_read() receives data into a fixed 64K buffer then continually
reallocates a final buffer that, after all continuation frames have been
received, is the exact length of the data received and returns that to the
caller.  process_text_message() in chan_websocket was attempting to set a
NULL terminator on the received payload assuming the payload buffer it
received was the large 64K buffer.  The assumption was incorrect so when it
tried to set a NULL terminator on the payload, it could, depending on the
state of the heap at the time, cause heap corruption.

process_text_message() now allocates its own payload_len + 1 sized buffer,
copies the payload received from ast_websocket_read() into it then NULL
terminates it prevent the possibility of the overrun and corruption.

Resolves: #1384
(cherry picked from commit 09802fbef2c90fabcda5de0b55584002be2cfd09)

channels/chan_websocket.c

index 1600871842d093fe1e0cc916d637d9f2ad5230a6..2f28b82d8fe224aecfcb56318332d04d85d05f62 100644 (file)
@@ -421,12 +421,14 @@ static int process_text_message(struct websocket_pvt *instance,
        }
 
        /*
-        * This is safe because the payload buffer is always >= 8K
-        * even with LOW_MEMORY defined and we've already made sure the
-        * command is less than 128 bytes.
+        * Unfortunately, payload is not NULL terminated even when it's
+        * a TEXT frame so we need to allocate a new buffer, copy
+        * the data into it, and NULL terminate it.
         */
-       payload[payload_len] = '\0';
-       command = ast_strip(ast_strdupa(payload));
+       command = ast_alloca(payload_len + 1);
+       memcpy(command, payload, payload_len); /* Safe */
+       command[payload_len] = '\0';
+       command = ast_strip(command);
 
        ast_debug(4, "%s: WebSocket %s command received\n",
                ast_channel_name(instance->channel), command);