libsoup: fix CVE-2025-32049

Refer:
https://gitlab.gnome.org/GNOME/libsoup/-/issues/390

(From OE-Core rev: 3c2f2b6f7af2bb743655859b64faae4786080cb9)

Signed-off-by: Changqing Li <changqing.li@windriver.com>
Signed-off-by: Fabien Thomas <fabien.thomas@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
Changqing Li
2026-04-29 14:15:31 +08:00
committed by Paul Barker
parent ad166a6de2
commit 95cfdc68bf
5 changed files with 693 additions and 0 deletions

View File

@@ -0,0 +1,229 @@
From 176cb31003252a69d3fc7908e8f505c0ee006b7a Mon Sep 17 00:00:00 2001
From: Ignacio Casal Quinteiro <qignacio@amazon.com>
Date: Wed, 24 Jul 2024 15:20:35 +0200
Subject: [PATCH 1/4] websocket: add a way to restrict the total message size
Otherwise a client could send small packages smaller than
total-incoming-payload-size but still to break the server
with a big allocation
Fixes: #390
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libsoup/-/commit/db87805ab565d67533dfed2cb409dbfd63c7fdce]
CVE: CVE-2025-32049
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
libsoup/websocket/soup-websocket-connection.c | 107 +++++++++++++++++-
libsoup/websocket/soup-websocket-connection.h | 7 ++
2 files changed, 110 insertions(+), 4 deletions(-)
diff --git a/libsoup/websocket/soup-websocket-connection.c b/libsoup/websocket/soup-websocket-connection.c
index 5eb8150..19bdd39 100644
--- a/libsoup/websocket/soup-websocket-connection.c
+++ b/libsoup/websocket/soup-websocket-connection.c
@@ -84,7 +84,7 @@ enum {
PROP_MAX_INCOMING_PAYLOAD_SIZE,
PROP_KEEPALIVE_INTERVAL,
PROP_EXTENSIONS,
-
+ PROP_MAX_TOTAL_MESSAGE_SIZE,
LAST_PROPERTY
};
@@ -126,6 +126,7 @@ typedef struct {
char *origin;
char *protocol;
guint64 max_incoming_payload_size;
+ guint64 max_total_message_size;
guint keepalive_interval;
gushort peer_close_code;
@@ -156,6 +157,7 @@ typedef struct {
} SoupWebsocketConnectionPrivate;
#define MAX_INCOMING_PAYLOAD_SIZE_DEFAULT 128 * 1024
+#define MAX_TOTAL_MESSAGE_SIZE_DEFAULT 128 * 1024
#define READ_BUFFER_SIZE 1024
#define MASK_LENGTH 4
@@ -670,8 +672,8 @@ bad_data_error_and_close (SoupWebsocketConnection *self)
}
static void
-too_big_error_and_close (SoupWebsocketConnection *self,
- guint64 payload_len)
+too_big_incoming_payload_error_and_close (SoupWebsocketConnection *self,
+ guint64 payload_len)
{
SoupWebsocketConnectionPrivate *priv = soup_websocket_connection_get_instance_private (self);
GError *error;
@@ -687,6 +689,24 @@ too_big_error_and_close (SoupWebsocketConnection *self,
emit_error_and_close (self, error, TRUE);
}
+static void
+too_big_message_error_and_close (SoupWebsocketConnection *self,
+ guint64 len)
+{
+ SoupWebsocketConnectionPrivate *priv = soup_websocket_connection_get_instance_private (self);
+ GError *error;
+
+ error = g_error_new_literal (SOUP_WEBSOCKET_ERROR,
+ SOUP_WEBSOCKET_CLOSE_TOO_BIG,
+ priv->connection_type == SOUP_WEBSOCKET_CONNECTION_SERVER ?
+ "Received WebSocket payload from the client larger than configured max-total-message-size" :
+ "Received WebSocket payload from the server larger than configured max-total-message-size");
+ g_debug ("%s received message of size %" G_GUINT64_FORMAT " or greater, but max supported size is %" G_GUINT64_FORMAT,
+ priv->connection_type == SOUP_WEBSOCKET_CONNECTION_SERVER ? "server" : "client",
+ len, priv->max_total_message_size);
+ emit_error_and_close (self, error, TRUE);
+}
+
static void
close_connection (SoupWebsocketConnection *self,
gushort code,
@@ -918,6 +938,12 @@ process_contents (SoupWebsocketConnection *self,
switch (priv->message_opcode) {
case 0x01:
case 0x02:
+ /* Safety valve */
+ if (priv->max_total_message_size > 0 &&
+ (priv->message_data->len + payload_len) > priv->max_total_message_size) {
+ too_big_message_error_and_close (self, (priv->message_data->len + payload_len));
+ return;
+ }
g_byte_array_append (priv->message_data, payload, payload_len);
break;
default:
@@ -1056,7 +1082,7 @@ process_frame (SoupWebsocketConnection *self)
/* Safety valve */
if (priv->max_incoming_payload_size > 0 &&
payload_len > priv->max_incoming_payload_size) {
- too_big_error_and_close (self, payload_len);
+ too_big_incoming_payload_error_and_close (self, payload_len);
return FALSE;
}
@@ -1363,6 +1389,10 @@ soup_websocket_connection_get_property (GObject *object,
g_value_set_pointer (value, priv->extensions);
break;
+ case PROP_MAX_TOTAL_MESSAGE_SIZE:
+ g_value_set_uint64 (value, priv->max_total_message_size);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1416,6 +1446,10 @@ soup_websocket_connection_set_property (GObject *object,
priv->extensions = g_value_get_pointer (value);
break;
+ case PROP_MAX_TOTAL_MESSAGE_SIZE:
+ priv->max_total_message_size = g_value_get_uint64 (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1628,6 +1662,26 @@ soup_websocket_connection_class_init (SoupWebsocketConnectionClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ /**
+ * SoupWebsocketConnection:max-total-message-size:
+ *
+ * The total message size for incoming packets.
+ *
+ * The protocol expects or 0 to not limit it.
+ *
+ * Since: 3.8
+ */
+ properties[PROP_MAX_TOTAL_MESSAGE_SIZE] =
+ g_param_spec_uint64 ("max-total-message-size",
+ "Max total message size",
+ "Max total message size ",
+ 0,
+ G_MAXUINT64,
+ MAX_TOTAL_MESSAGE_SIZE_DEFAULT,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (gobject_class, LAST_PROPERTY, properties);
/**
@@ -2111,6 +2165,51 @@ soup_websocket_connection_set_max_incoming_payload_size (SoupWebsocketConnection
}
}
+/**
+ * soup_websocket_connection_get_max_total_message_size:
+ * @self: the WebSocket
+ *
+ * Gets the maximum total message size allowed for packets.
+ *
+ * Returns: the maximum total message size.
+ *
+ * Since: 3.8
+ */
+guint64
+soup_websocket_connection_get_max_total_message_size (SoupWebsocketConnection *self)
+{
+ SoupWebsocketConnectionPrivate *priv = soup_websocket_connection_get_instance_private (self);
+
+ g_return_val_if_fail (SOUP_IS_WEBSOCKET_CONNECTION (self), MAX_TOTAL_MESSAGE_SIZE_DEFAULT);
+
+ return priv->max_total_message_size;
+}
+
+/**
+ * soup_websocket_connection_set_max_total_message_size:
+ * @self: the WebSocket
+ * @max_total_message_size: the maximum total message size
+ *
+ * Sets the maximum total message size allowed for packets.
+ *
+ * It does not limit the outgoing packet size.
+ *
+ * Since: 3.8
+ */
+void
+soup_websocket_connection_set_max_total_message_size (SoupWebsocketConnection *self,
+ guint64 max_total_message_size)
+{
+ SoupWebsocketConnectionPrivate *priv = soup_websocket_connection_get_instance_private (self);
+
+ g_return_if_fail (SOUP_IS_WEBSOCKET_CONNECTION (self));
+
+ if (priv->max_total_message_size != max_total_message_size) {
+ priv->max_total_message_size = max_total_message_size;
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MAX_TOTAL_MESSAGE_SIZE]);
+ }
+}
+
/**
* soup_websocket_connection_get_keepalive_interval:
* @self: the WebSocket
diff --git a/libsoup/websocket/soup-websocket-connection.h b/libsoup/websocket/soup-websocket-connection.h
index eeb093d..922de56 100644
--- a/libsoup/websocket/soup-websocket-connection.h
+++ b/libsoup/websocket/soup-websocket-connection.h
@@ -88,6 +88,13 @@ SOUP_AVAILABLE_IN_ALL
void soup_websocket_connection_set_max_incoming_payload_size (SoupWebsocketConnection *self,
guint64 max_incoming_payload_size);
+SOUP_AVAILABLE_IN_3_0
+guint64 soup_websocket_connection_get_max_total_message_size (SoupWebsocketConnection *self);
+
+SOUP_AVAILABLE_IN_3_0
+void soup_websocket_connection_set_max_total_message_size (SoupWebsocketConnection *self,
+ guint64 max_total_message_size);
+
SOUP_AVAILABLE_IN_ALL
guint soup_websocket_connection_get_keepalive_interval (SoupWebsocketConnection *self);
--
2.34.1

View File

@@ -0,0 +1,34 @@
From 81eb7cf7422878f0b78b833a3b741f734502921f Mon Sep 17 00:00:00 2001
From: Ignacio Casal Quinteiro <qignacio@amazon.com>
Date: Fri, 20 Sep 2024 12:12:38 +0200
Subject: [PATCH 2/4] websocket-test: set the total message size
This is required when sending a big amount of data
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libsoup/-/commit/4904a46a2d9a014efa6be01a186ac353dbf5047b]
CVE: CVE-2025-32049
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
tests/websocket-test.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index a0b8334..827b041 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -567,6 +567,11 @@ test_send_big_packets (Test *test,
soup_websocket_connection_set_max_incoming_payload_size (test->server, 1000 * 1000 + 1);
g_assert (soup_websocket_connection_get_max_incoming_payload_size (test->server) == (1000 * 1000 + 1));
+ soup_websocket_connection_set_max_total_message_size (test->client, 1000 * 1000 + 1);
+ g_assert (soup_websocket_connection_get_max_total_message_size (test->client) == (1000 * 1000 + 1));
+ soup_websocket_connection_set_max_total_message_size (test->server, 1000 * 1000 + 1);
+ g_assert (soup_websocket_connection_get_max_total_message_size (test->server) == (1000 * 1000 + 1));
+
sent = g_bytes_new_take (g_strnfill (1000 * 1000, '?'), 1000 * 1000);
soup_websocket_connection_send_text (test->server, g_bytes_get_data (sent, NULL));
WAIT_UNTIL (received != NULL);
--
2.34.1

View File

@@ -0,0 +1,134 @@
From 25616e1a958bc1503cc24d6845a6e80ffc287727 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Thu, 8 May 2025 16:16:25 -0500
Subject: [PATCH] Set message size limit in SoupServer rather than
SoupWebsocketConnection
We're not sure about the compatibility implications of having a default
size limit for clients.
Also not sure whether the server limit is actually set appropriately,
but there is probably very little server usage of
SoupWebsocketConnection in the wild, so it's not so likely to break
things.
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libsoup/-/commit/2df34d9544cabdbfdedd3b36f098cf69233b1df7]
CVE: CVE-2025-32049
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
libsoup/server/soup-server.c | 24 +++++++++++++----
libsoup/websocket/soup-websocket-connection.c | 26 +++++++++++++------
2 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/libsoup/server/soup-server.c b/libsoup/server/soup-server.c
index 6b486f5..c779f7d 100644
--- a/libsoup/server/soup-server.c
+++ b/libsoup/server/soup-server.c
@@ -186,6 +186,16 @@ static GParamSpec *properties[LAST_PROPERTY] = { NULL, };
G_DEFINE_TYPE_WITH_PRIVATE (SoupServer, soup_server, G_TYPE_OBJECT)
+/* SoupWebsocketConnection by default limits only maximum packet size. But a
+ * message may consist of multiple packets, so SoupServer additionally restricts
+ * total message size to mitigate denial of service attacks on the server.
+ * SoupWebsocketConnection does not do this by default because I don't know
+ * whether that would or would not cause compatibility problems for websites.
+ *
+ * This size is in bytes and it is arbitrary.
+ */
+#define MAX_TOTAL_MESSAGE_SIZE_DEFAULT 128 * 1024
+
static void request_finished (SoupServerMessage *msg,
SoupMessageIOCompletion completion,
SoupServer *server);
@@ -937,11 +947,15 @@ complete_websocket_upgrade (SoupServer *server,
g_object_ref (msg);
stream = soup_server_message_steal_connection (msg);
- conn = soup_websocket_connection_new (stream, uri,
- SOUP_WEBSOCKET_CONNECTION_SERVER,
- soup_message_headers_get_one_common (soup_server_message_get_request_headers (msg), SOUP_HEADER_ORIGIN),
- soup_message_headers_get_one_common (soup_server_message_get_response_headers (msg), SOUP_HEADER_SEC_WEBSOCKET_PROTOCOL),
- handler->websocket_extensions);
+ conn = SOUP_WEBSOCKET_CONNECTION (g_object_new (SOUP_TYPE_WEBSOCKET_CONNECTION,
+ "io-stream", stream,
+ "uri", uri,
+ "connection-type", SOUP_WEBSOCKET_CONNECTION_SERVER,
+ "origin", soup_message_headers_get_one_common (soup_server_message_get_request_headers (msg), SOUP_HEADER_ORIGIN),
+ "protocol", soup_message_headers_get_one_common (soup_server_message_get_response_headers (msg), SOUP_HEADER_SEC_WEBSOCKET_PROTOCOL),
+ "extensions", handler->websocket_extensions,
+ "max-total-message-size", (guint64)MAX_TOTAL_MESSAGE_SIZE_DEFAULT,
+ NULL));
handler->websocket_extensions = NULL;
g_object_unref (stream);
diff --git a/libsoup/websocket/soup-websocket-connection.c b/libsoup/websocket/soup-websocket-connection.c
index 26476df..cbb1b72 100644
--- a/libsoup/websocket/soup-websocket-connection.c
+++ b/libsoup/websocket/soup-websocket-connection.c
@@ -149,7 +149,6 @@ typedef struct {
} SoupWebsocketConnectionPrivate;
#define MAX_INCOMING_PAYLOAD_SIZE_DEFAULT 128 * 1024
-#define MAX_TOTAL_MESSAGE_SIZE_DEFAULT 128 * 1024
#define READ_BUFFER_SIZE 1024
#define MASK_LENGTH 4
@@ -1612,9 +1611,10 @@ soup_websocket_connection_class_init (SoupWebsocketConnectionClass *klass)
/**
* SoupWebsocketConnection:max-incoming-payload-size:
*
- * The maximum payload size for incoming packets.
- *
- * The protocol expects or 0 to not limit it.
+ * The maximum payload size for incoming packets, or 0 to not limit it.
+ *
+ * Each message may consist of multiple packets, so also refer to
+ * [property@WebSocketConnection:max-total-message-size].
*/
properties[PROP_MAX_INCOMING_PAYLOAD_SIZE] =
g_param_spec_uint64 ("max-incoming-payload-size",
@@ -1662,9 +1662,19 @@ soup_websocket_connection_class_init (SoupWebsocketConnectionClass *klass)
/**
* SoupWebsocketConnection:max-total-message-size:
*
- * The total message size for incoming packets.
+ * The maximum size for incoming messages.
+ *
+ * Set to a value to limit the total message size, or 0 to not
+ * limit it.
+ *
+ * [method@Server.add_websocket_handler] will set this to a nonzero
+ * default value to mitigate denial of service attacks. Clients must
+ * choose their own default if they need to mitigate denial of service
+ * attacks. You also need to set your own default if creating your own
+ * server SoupWebsocketConnection without using SoupServer.
*
- * The protocol expects or 0 to not limit it.
+ * Each message may consist of multiple packets, so also refer to
+ * [property@WebSocketConnection:max-incoming-payload-size].
*
* Since: 3.8
*/
@@ -1674,7 +1684,7 @@ soup_websocket_connection_class_init (SoupWebsocketConnectionClass *klass)
"Max total message size ",
0,
G_MAXUINT64,
- MAX_TOTAL_MESSAGE_SIZE_DEFAULT,
+ 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS);
@@ -2164,7 +2174,7 @@ soup_websocket_connection_get_max_total_message_size (SoupWebsocketConnection *s
{
SoupWebsocketConnectionPrivate *priv = soup_websocket_connection_get_instance_private (self);
- g_return_val_if_fail (SOUP_IS_WEBSOCKET_CONNECTION (self), MAX_TOTAL_MESSAGE_SIZE_DEFAULT);
+ g_return_val_if_fail (SOUP_IS_WEBSOCKET_CONNECTION (self), 0);
return priv->max_total_message_size;
}
--
2.34.1

View File

@@ -0,0 +1,292 @@
From 3c87790a4ba141125e6ba165c478f0440e8e693e Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Fri, 16 May 2025 16:55:40 -0500
Subject: [PATCH 4/4] Add tests for max-incoming-packet-size and
max-total-message-size
An even better test would verify that it's possible to send big messages
containing small packets, but libsoup doesn't offer control over packet
size, and I don't want to take the time to learn how WebSockets work to
figure out how to do that manually. Instead, I just check that both
limits work, for both client and server.
I didn't add deflate variants of these tests because I doubt that would
add valuable coverage.
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libsoup/-/commit/4d00b45b7eebdcfa0706b58e34c40b8a0a16015b]
CVE: CVE-2025-32049
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
tests/websocket-test.c | 214 +++++++++++++++++++++++++++++++++++++----
1 file changed, 197 insertions(+), 17 deletions(-)
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index 827b041..ec1324c 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -543,16 +543,9 @@ test_send_big_packets (Test *test,
{
GBytes *sent = NULL;
GBytes *received = NULL;
+ gulong signal_id;
- g_signal_connect (test->client, "message", G_CALLBACK (on_text_message), &received);
-
- sent = g_bytes_new_take (g_strnfill (400, '!'), 400);
- soup_websocket_connection_send_text (test->server, g_bytes_get_data (sent, NULL));
- WAIT_UNTIL (received != NULL);
- g_assert (g_bytes_equal (sent, received));
- g_bytes_unref (sent);
- g_bytes_unref (received);
- received = NULL;
+ signal_id = g_signal_connect (test->client, "message", G_CALLBACK (on_text_message), &received);
sent = g_bytes_new_take (g_strnfill (100 * 1000, '?'), 100 * 1000);
soup_websocket_connection_send_text (test->server, g_bytes_get_data (sent, NULL));
@@ -563,23 +556,174 @@ test_send_big_packets (Test *test,
received = NULL;
soup_websocket_connection_set_max_incoming_payload_size (test->client, 1000 * 1000 + 1);
- g_assert (soup_websocket_connection_get_max_incoming_payload_size (test->client) == (1000 * 1000 + 1));
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->client), ==, 1000 * 1000 + 1);
soup_websocket_connection_set_max_incoming_payload_size (test->server, 1000 * 1000 + 1);
- g_assert (soup_websocket_connection_get_max_incoming_payload_size (test->server) == (1000 * 1000 + 1));
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->server), ==, 1000 * 1000 + 1);
soup_websocket_connection_set_max_total_message_size (test->client, 1000 * 1000 + 1);
- g_assert (soup_websocket_connection_get_max_total_message_size (test->client) == (1000 * 1000 + 1));
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->client), ==, 1000 * 1000 + 1);
soup_websocket_connection_set_max_total_message_size (test->server, 1000 * 1000 + 1);
- g_assert (soup_websocket_connection_get_max_total_message_size (test->server) == (1000 * 1000 + 1));
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->server), ==, 1000 * 1000 + 1);
sent = g_bytes_new_take (g_strnfill (1000 * 1000, '?'), 1000 * 1000);
soup_websocket_connection_send_text (test->server, g_bytes_get_data (sent, NULL));
WAIT_UNTIL (received != NULL);
g_assert (g_bytes_equal (sent, received));
+ g_bytes_unref (received);
+ received = NULL;
+
+ /* Reverse the test and send the big message to the server. */
+ g_signal_handler_disconnect (test->client, signal_id);
+ g_signal_connect (test->server, "message", G_CALLBACK (on_text_message), &received);
+
+ soup_websocket_connection_send_text (test->client, g_bytes_get_data (sent, NULL));
+ WAIT_UNTIL (received != NULL);
+ g_assert_true (g_bytes_equal (sent, received));
g_bytes_unref (sent);
g_bytes_unref (received);
}
+static void
+test_send_big_packets_direct (Test *test,
+ gconstpointer data)
+{
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->client), ==, 128 * 1024);
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->client), ==, 0);
+
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->server), ==, 128 * 1024);
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->server), ==, 0);
+
+ test_send_big_packets (test, data);
+}
+
+static void
+test_send_big_packets_soup (Test *test,
+ gconstpointer data)
+{
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->client), ==, 128 * 1024);
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->client), ==, 0);
+
+ /* Max total message size defaults to 0 (unlimited), but SoupServer applies its own limit by default. */
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->server), ==, 128 * 1024);
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->server), ==, 128 * 1024);
+
+ test_send_big_packets (test, data);
+}
+
+static void
+test_send_exceeding_client_max_payload_size (Test *test,
+ gconstpointer data)
+{
+ GBytes *sent = NULL;
+ GBytes *received = NULL;
+ gboolean close_event = FALSE;
+ GError *error = NULL;
+
+ g_signal_connect (test->server, "error", G_CALLBACK (on_error_copy), &error);
+ g_signal_connect (test->client, "closed", G_CALLBACK (on_close_set_flag), &close_event);
+
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->client), ==, 128 * 1024);
+
+ soup_websocket_connection_set_max_incoming_payload_size (test->server, 0);
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->server), ==, 0);
+
+ /* The message to the client is dropped due to the client's limit. */
+ sent = g_bytes_new_take (g_strnfill (1000 * 1000, '?'), 1000 * 1000);
+ soup_websocket_connection_send_text (test->server, g_bytes_get_data (sent, NULL));
+ g_bytes_unref (sent);
+ WAIT_UNTIL (close_event);
+ g_assert_null (received);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
+ g_assert_no_error (test->client_error);
+}
+
+static void
+test_send_exceeding_server_max_payload_size (Test *test,
+ gconstpointer data)
+{
+ GBytes *sent = NULL;
+ GBytes *received = NULL;
+ gboolean close_event = FALSE;
+ GError *error = NULL;
+
+ g_signal_connect (test->client, "error", G_CALLBACK (on_error_copy), &error);
+ g_signal_connect (test->server, "closed", G_CALLBACK (on_close_set_flag), &close_event);
+
+ soup_websocket_connection_set_max_incoming_payload_size (test->client, 0);
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->client), ==, 0);
+
+ g_assert_cmpuint (soup_websocket_connection_get_max_incoming_payload_size (test->server), ==, 128 * 1024);
+
+ /* The message to the server is dropped due to the server's limit. */
+ sent = g_bytes_new_take (g_strnfill (1000 * 1000, '?'), 1000 * 1000);
+ soup_websocket_connection_send_text (test->client, g_bytes_get_data (sent, NULL));
+ g_bytes_unref (sent);
+ WAIT_UNTIL (close_event);
+ g_assert_null (received);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
+ g_assert_no_error (test->client_error);
+}
+
+static void
+test_send_exceeding_client_max_message_size (Test *test,
+ gconstpointer data)
+{
+ GBytes *sent = NULL;
+ GBytes *received = NULL;
+ gboolean close_event = FALSE;
+ GError *error = NULL;
+
+ g_signal_connect (test->server, "error", G_CALLBACK (on_error_copy), &error);
+ g_signal_connect (test->client, "closed", G_CALLBACK (on_close_set_flag), &close_event);
+
+ soup_websocket_connection_set_max_total_message_size (test->client, 128 * 1024);
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->client), ==, 128 * 1024);
+
+ soup_websocket_connection_set_max_total_message_size (test->server, 0);
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->server), ==, 0);
+
+ /* The message to the client is dropped due to the client's limit. */
+ sent = g_bytes_new_take (g_strnfill (1000 * 1000, '?'), 1000 * 1000);
+ soup_websocket_connection_send_text (test->server, g_bytes_get_data (sent, NULL));
+ g_bytes_unref (sent);
+ WAIT_UNTIL (close_event);
+ g_assert_null (received);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
+ g_assert_no_error (test->client_error);
+}
+
+static void
+test_send_exceeding_server_max_message_size (Test *test,
+ gconstpointer data)
+{
+ GBytes *sent = NULL;
+ GBytes *received = NULL;
+ gboolean close_event = FALSE;
+ GError *error = NULL;
+
+ g_signal_connect (test->client, "error", G_CALLBACK (on_error_copy), &error);
+ g_signal_connect (test->server, "closed", G_CALLBACK (on_close_set_flag), &close_event);
+
+ soup_websocket_connection_set_max_total_message_size (test->client, 0);
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->client), ==, 0);
+
+ /* Set the server message total message size manually, because its
+ * default is different for direct connection vs. soup connection.
+ */
+ soup_websocket_connection_set_max_total_message_size (test->server, 128 * 1024);
+ g_assert_cmpuint (soup_websocket_connection_get_max_total_message_size (test->server), ==, 128 * 1024);
+
+ /* The message to the server is dropped due to the server's limit. */
+ sent = g_bytes_new_take (g_strnfill (1000 * 1000, '?'), 1000 * 1000);
+ soup_websocket_connection_send_text (test->client, g_bytes_get_data (sent, NULL));
+ g_bytes_unref (sent);
+ WAIT_UNTIL (close_event);
+ g_assert_null (received);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
+ g_assert_no_error (test->client_error);
+}
+
+
static void
test_send_empty_packets (Test *test,
gconstpointer data)
@@ -2064,11 +2208,47 @@ main (int argc,
g_test_add ("/websocket/direct/send-big-packets", Test, NULL,
setup_direct_connection,
- test_send_big_packets,
+ test_send_big_packets_direct,
teardown_direct_connection);
g_test_add ("/websocket/soup/send-big-packets", Test, NULL,
setup_soup_connection,
- test_send_big_packets,
+ test_send_big_packets_soup,
+ teardown_soup_connection);
+
+ g_test_add ("/websocket/direct/send-exceeding-client-max-payload-size", Test, NULL,
+ setup_direct_connection,
+ test_send_exceeding_client_max_payload_size,
+ teardown_direct_connection);
+ g_test_add ("/websocket/soup/send-exceeding-client-max-payload-size", Test, NULL,
+ setup_soup_connection,
+ test_send_exceeding_client_max_payload_size,
+ teardown_soup_connection);
+
+ g_test_add ("/websocket/direct/send-exceeding-server-max-payload-size", Test, NULL,
+ setup_direct_connection,
+ test_send_exceeding_server_max_payload_size,
+ teardown_direct_connection);
+ g_test_add ("/websocket/soup/send-exceeding-server-max-payload-size", Test, NULL,
+ setup_soup_connection,
+ test_send_exceeding_server_max_payload_size,
+ teardown_soup_connection);
+
+ g_test_add ("/websocket/direct/send-exceeding-client-max-message-size", Test, NULL,
+ setup_direct_connection,
+ test_send_exceeding_client_max_message_size,
+ teardown_direct_connection);
+ g_test_add ("/websocket/soup/send-exceeding-client-max-message-size", Test, NULL,
+ setup_soup_connection,
+ test_send_exceeding_client_max_message_size,
+ teardown_soup_connection);
+
+ g_test_add ("/websocket/direct/send-exceeding-server-max-message-size", Test, NULL,
+ setup_direct_connection,
+ test_send_exceeding_server_max_message_size,
+ teardown_direct_connection);
+ g_test_add ("/websocket/soup/send-exceeding-server-max-message-size", Test, NULL,
+ setup_soup_connection,
+ test_send_exceeding_server_max_message_size,
teardown_soup_connection);
g_test_add ("/websocket/direct/send-empty-packets", Test, NULL,
@@ -2217,11 +2397,11 @@ main (int argc,
g_test_add ("/websocket/direct/deflate-send-big-packets", Test, NULL,
setup_direct_connection_with_extensions,
- test_send_big_packets,
+ test_send_big_packets_direct,
teardown_direct_connection);
g_test_add ("/websocket/soup/deflate-send-big-packets", Test, NULL,
setup_soup_connection_with_extensions,
- test_send_big_packets,
+ test_send_big_packets_soup,
teardown_soup_connection);
g_test_add ("/websocket/direct/deflate-send-empty-packets", Test, NULL,
--
2.34.1

View File

@@ -47,6 +47,10 @@ SRC_URI = "${GNOME_MIRROR}/libsoup/${SHRT_VER}/libsoup-${PV}.tar.xz \
file://CVE-2025-4945.patch \
file://CVE-2025-12105.patch \
file://CVE-2025-14523.patch \
file://CVE-2025-32049-1.patch \
file://CVE-2025-32049-2.patch \
file://CVE-2025-32049-3.patch \
file://CVE-2025-32049-4.patch \
"
SRC_URI[sha256sum] = "291c67725f36ed90ea43efff25064b69c5a2d1981488477c05c481a3b4b0c5aa"