[libsoup/read-after-free] WebSockets: fix read after free in send_message()



commit 2580f3a2a0f9c1c7616d633a6d038ec81a1f7f45
Author: Claudio Saavedra <csaavedra igalia com>
Date:   Fri Aug 30 16:01:47 2019 +0300

    WebSockets: fix read after free in send_message()
    
    g_byte_array_append() can reallocate its data, so make sure that we
    don't rely on any pointer pointing to it after calling it.

 libsoup/soup-websocket-connection.c | 13 ++++++-------
 meson.build                         |  1 +
 2 files changed, 7 insertions(+), 7 deletions(-)
---
diff --git a/libsoup/soup-websocket-connection.c b/libsoup/soup-websocket-connection.c
index b5f1455f..0d0ea34d 100644
--- a/libsoup/soup-websocket-connection.c
+++ b/libsoup/soup-websocket-connection.c
@@ -153,6 +153,7 @@ struct _SoupWebsocketConnectionPrivate {
 
 #define MAX_INCOMING_PAYLOAD_SIZE_DEFAULT   128 * 1024
 #define READ_BUFFER_SIZE 1024
+#define MASK_LENGTH 4
 
 G_DEFINE_TYPE_WITH_PRIVATE (SoupWebsocketConnection, soup_websocket_connection, G_TYPE_OBJECT)
 
@@ -470,8 +471,7 @@ send_message (SoupWebsocketConnection *self,
        GByteArray *bytes;
        gsize frame_len;
        guint8 *outer;
-       guint8 *mask = 0;
-       guint at;
+       guint8 mask_offset;
        GBytes *filtered_bytes;
        GList *l;
        GError *error = NULL;
@@ -543,16 +543,15 @@ send_message (SoupWebsocketConnection *self,
        if (self->pv->connection_type == SOUP_WEBSOCKET_CONNECTION_CLIENT) {
                guint32 rnd = g_random_int ();
                outer[1] |= 0x80;
-               mask = outer + bytes->len;
-               memcpy (mask, &rnd, sizeof (rnd));
-               bytes->len += 4;
+               mask_offset = bytes->len;
+               memcpy (outer + mask_offset, &rnd, sizeof (rnd));
+               bytes->len += MASK_LENGTH;
        }
 
-       at = bytes->len;
        g_byte_array_append (bytes, data, length);
 
        if (self->pv->connection_type == SOUP_WEBSOCKET_CONNECTION_CLIENT)
-               xor_with_mask (mask, bytes->data + at, length);
+               xor_with_mask (bytes->data + mask_offset, bytes->data + mask_offset + MASK_LENGTH, length);
 
        frame_len = bytes->len;
        queue_frame (self, flags, g_byte_array_free (bytes, FALSE),
diff --git a/meson.build b/meson.build
index 1eaa2016..e33fe539 100644
--- a/meson.build
+++ b/meson.build
@@ -360,6 +360,7 @@ subdir('examples')
 
 if get_option('tests')
   subdir('tests')
+  subdir('tests/autobahn')
  endif
 
 if get_option('gtk_doc')


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]