mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-09 12:25:48 +01:00
GDBusMessage: Validate UTF-8 strings when serializing from blob
Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
parent
e62bc8e8f6
commit
5bd34a820e
@ -728,6 +728,7 @@ read_string (GMemoryInputStream *mis,
|
|||||||
gsize remaining;
|
gsize remaining;
|
||||||
guchar nul;
|
guchar nul;
|
||||||
GError *local_error;
|
GError *local_error;
|
||||||
|
const gchar *end_valid;
|
||||||
|
|
||||||
s = g_string_new (NULL);
|
s = g_string_new (NULL);
|
||||||
|
|
||||||
@ -767,13 +768,30 @@ read_string (GMemoryInputStream *mis,
|
|||||||
g_propagate_error (error, local_error);
|
g_propagate_error (error, local_error);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (!g_utf8_validate (s->str, -1, &end_valid))
|
||||||
|
{
|
||||||
|
gint offset;
|
||||||
|
gchar *valid_str;
|
||||||
|
offset = (gint) (end_valid - s->str);
|
||||||
|
valid_str = g_strndup (s->str, offset);
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
_("Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). "
|
||||||
|
"The valid UTF-8 string up until that that point was `%s'"),
|
||||||
|
offset,
|
||||||
|
(gint) s->len,
|
||||||
|
valid_str);
|
||||||
|
g_free (valid_str);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
if (nul != '\0')
|
if (nul != '\0')
|
||||||
{
|
{
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
_("Expected NUL byte after the string `%s' but found `%c' (%d)"),
|
_("Expected NUL byte after the string `%s' but found byte %d"),
|
||||||
s->str, nul, nul);
|
s->str, nul);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,7 +1069,7 @@ parse_value_from_blob (GMemoryInputStream *mis,
|
|||||||
g_set_error (&local_error,
|
g_set_error (&local_error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
_("Encountered array of length %u bytes. Maximum length is 2<<26 bytes."),
|
_("Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)."),
|
||||||
array_len);
|
array_len);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -703,6 +703,93 @@ message_serialize_complex (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static void
|
||||||
|
message_serialize_invalid (void)
|
||||||
|
{
|
||||||
|
guint n;
|
||||||
|
|
||||||
|
/* Here we're relying on libdbus-1's DBusMessage type not checking
|
||||||
|
* anything. If that were to change, we'd need to do our own
|
||||||
|
* thing.
|
||||||
|
*
|
||||||
|
* Other things we could check (note that GDBus _does_ check for all
|
||||||
|
* these things - we just don't have test-suit coverage for it)
|
||||||
|
*
|
||||||
|
* - array exceeding 64 MiB (2^26 bytes) - unfortunately libdbus-1 checks
|
||||||
|
* this, e.g.
|
||||||
|
*
|
||||||
|
* process 19620: arguments to dbus_message_iter_append_fixed_array() were incorrect,
|
||||||
|
* assertion "n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type)"
|
||||||
|
* failed in file dbus-message.c line 2344.
|
||||||
|
* This is normally a bug in some application using the D-Bus library.
|
||||||
|
* D-Bus not built with -rdynamic so unable to print a backtrace
|
||||||
|
* Aborted (core dumped)
|
||||||
|
*
|
||||||
|
* - message exceeding 128 MiB (2^27 bytes)
|
||||||
|
*
|
||||||
|
* - endianness, message type, flags, protocol version
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (n = 0; n < 3; n++)
|
||||||
|
{
|
||||||
|
GDBusMessage *message;
|
||||||
|
GError *error;
|
||||||
|
DBusMessage *dbus_message;
|
||||||
|
char *blob;
|
||||||
|
int blob_len;
|
||||||
|
const gchar *invalid_utf8_str = "this is invalid\xff";
|
||||||
|
const gchar *invalid_object_path = "/this/is/not a valid object path";
|
||||||
|
const gchar *invalid_signature = "not valid signature";
|
||||||
|
|
||||||
|
dbus_message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
|
||||||
|
dbus_message_set_serial (dbus_message, 0x41);
|
||||||
|
dbus_message_set_path (dbus_message, "/foo/bar");
|
||||||
|
dbus_message_set_member (dbus_message, "Member");
|
||||||
|
switch (n)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
/* invalid UTF-8 */
|
||||||
|
dbus_message_append_args (dbus_message,
|
||||||
|
DBUS_TYPE_STRING, &invalid_utf8_str,
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
/* invalid object path */
|
||||||
|
dbus_message_append_args (dbus_message,
|
||||||
|
DBUS_TYPE_OBJECT_PATH, &invalid_object_path,
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
/* invalid signature */
|
||||||
|
dbus_message_append_args (dbus_message,
|
||||||
|
DBUS_TYPE_SIGNATURE, &invalid_signature,
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dbus_message_marshal (dbus_message, &blob, &blob_len);
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
message = g_dbus_message_new_from_blob ((guchar *) blob,
|
||||||
|
blob_len,
|
||||||
|
G_DBUS_CAPABILITY_FLAGS_NONE,
|
||||||
|
&error);
|
||||||
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
|
||||||
|
g_error_free (error);
|
||||||
|
g_assert (message == NULL);
|
||||||
|
|
||||||
|
dbus_free (blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -714,6 +801,7 @@ main (int argc,
|
|||||||
|
|
||||||
g_test_add_func ("/gdbus/message-serialize-basic", message_serialize_basic);
|
g_test_add_func ("/gdbus/message-serialize-basic", message_serialize_basic);
|
||||||
g_test_add_func ("/gdbus/message-serialize-complex", message_serialize_complex);
|
g_test_add_func ("/gdbus/message-serialize-complex", message_serialize_complex);
|
||||||
|
g_test_add_func ("/gdbus/message-serialize-invalid", message_serialize_invalid);
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user