From 076423aa18808e2a4fff1259cd927b1f562081c0 Mon Sep 17 00:00:00 2001 From: George Joseph Date: Tue, 19 Aug 2025 09:46:39 -0600 Subject: [PATCH] chan_websocket: Fix buffer overrun when processing TEXT websocket frames. 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 --- channels/chan_websocket.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/channels/chan_websocket.c b/channels/chan_websocket.c index 1600871842..2f28b82d8f 100644 --- a/channels/chan_websocket.c +++ b/channels/chan_websocket.c @@ -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);