]> jfr.im git - irc/weechat/weechat.git/commitdiff
relay: fix crash when decoding a malformed websocket frame
authorSébastien Helleu <redacted>
Sat, 4 Sep 2021 09:39:22 +0000 (11:39 +0200)
committerSébastien Helleu <redacted>
Sat, 4 Sep 2021 09:39:22 +0000 (11:39 +0200)
ChangeLog.adoc
src/plugins/relay/relay-websocket.c
version.sh

index 9b5d42476e5d4ccfb0ff7c8c9bcdfa94ea4087e3..511b20f87d3821cd97a57a680dcedf3eb84ccb83 100644 (file)
@@ -15,6 +15,13 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
 (file _ReleaseNotes.adoc_ in sources).
 
 
+[[v3.2.1]]
+== Version 3.2.1 (under dev)
+
+Bug fixes::
+
+  * relay: fix crash when decoding a malformed websocket frame
+
 [[v3.2]]
 == Version 3.2 (2021-06-13)
 
index c5a7df324b1c92b375726574a91145b6a7ea5170..7cbbaa30874a1a50e9c6a6a6867da012f14ea20d 100644 (file)
@@ -278,7 +278,7 @@ relay_websocket_decode_frame (const unsigned char *buffer,
     index_buffer = 0;
 
     /* loop to decode all frames in message */
-    while (index_buffer + 2 <= buffer_length)
+    while (index_buffer + 1 < buffer_length)
     {
         opcode = buffer[index_buffer] & 15;
 
@@ -293,10 +293,12 @@ relay_websocket_decode_frame (const unsigned char *buffer,
         length_frame_size = 1;
         length_frame = buffer[index_buffer + 1] & 127;
         index_buffer += 2;
+        if (index_buffer >= buffer_length)
+            return 0;
         if ((length_frame == 126) || (length_frame == 127))
         {
             length_frame_size = (length_frame == 126) ? 2 : 8;
-            if (buffer_length < 1 + length_frame_size)
+            if (index_buffer + length_frame_size > buffer_length)
                 return 0;
             length_frame = 0;
             for (i = 0; i < length_frame_size; i++)
@@ -306,10 +308,9 @@ relay_websocket_decode_frame (const unsigned char *buffer,
             index_buffer += length_frame_size;
         }
 
-        if (buffer_length < 1 + length_frame_size + 4 + length_frame)
-            return 0;
-
         /* read masks (4 bytes) */
+        if (index_buffer + 4 > buffer_length)
+            return 0;
         int masks[4];
         for (i = 0; i < 4; i++)
         {
@@ -333,6 +334,11 @@ relay_websocket_decode_frame (const unsigned char *buffer,
         *decoded_length += 1;
 
         /* decode data using masks */
+        if ((length_frame > buffer_length)
+            || (index_buffer + length_frame > buffer_length))
+        {
+            return 0;
+        }
         for (i = 0; i < length_frame; i++)
         {
             decoded[*decoded_length + i] = (int)((unsigned char)buffer[index_buffer + i]) ^ masks[i % 4];
index e5a7b995922538d3bc9a9a46a7baf77daa8de9ab..6c88cdc74cb2bd7752b2a4872b7a5613f5644f0f 100755 (executable)
@@ -33,8 +33,8 @@
 #
 
 WEECHAT_STABLE=3.2
-WEECHAT_DEVEL=3.2
-WEECHAT_DEVEL_FULL=3.2
+WEECHAT_DEVEL=3.2.1
+WEECHAT_DEVEL_FULL=3.2.1-dev
 
 if [ $# -lt 1 ]; then
     echo >&2 "Syntax: $0 stable|devel|devel-full|devel-major|devel-minor|devel-patch"