glib git工作目录保持clean Signed-off-by: s30029175 <shiqiwei4@huawei.com>

Signed-off-by: sqwlly <shiqiwei4@huawei.com>
Change-Id: I113074508fd3172ebb9abd811aa9a6eb599b3ffb
This commit is contained in:
sqwlly 2023-09-22 10:03:58 +08:00
parent 885cc72eed
commit fd68595ba7
64 changed files with 27556 additions and 5 deletions

35
.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
AUTHORS
CONTRIBUTING.md
COPYING
HACKING
INSTALL.in
NEWS
NEWS.pre-1-3
README
README.md
README.rationale
README.win32
README.win32.md
check-abis.sh
clang-format-diff.py
config.h
docs
fuzzing
gio
glib
glib-gettextize.in
glib.doap
glib.supp
glibmemdfx
gmodule
gobject
gthread
m4macros
meson.build
meson_options.txt
msvc_recommended_pragmas.h
po
subprojects
template-tap.test.in
template.test.in
tests

View File

@ -3,8 +3,7 @@
set -e
cd $1
# tar -zcvf patch.tar.gz *.patch
find . ! -path "*/\.*" ! \( -name patch.tar.gz -o -name glib-2.68.1.tar.xz\
find . ! -path "*/\.*" ! -path "./patch*" ! \( -name glib-2.68.1.tar.xz\
-o -name BUILD.gn\
-o -name config.gni\
-o -name install.sh\
@ -18,7 +17,6 @@ find . ! -path "*/\.*" ! \( -name patch.tar.gz -o -name glib-2.68.1.tar.xz\
-o -name CONTRIBUTING.md\
-o -name ".*" \)\
-prune -print -exec rm -rf {} \;
tar -zxvf patch.tar.gz
tar -xvf glib-2.68.1.tar.xz
mv glib-2.68.1/* .
rm -rf glib-2.68.1
@ -27,9 +25,9 @@ file="backport-patch.log"
exec < $file
while read line
do
line=${line:15}
line=${line:16}
echo $line
patch -p1 < $line --fuzz=0 --no-backup-if-mismatch
patch -p1 < patch/$line --fuzz=0 --no-backup-if-mismatch
done
echo "all file patch success!"
exit 0

View File

@ -0,0 +1,219 @@
From 34ce204fd758e2ce0ab6bf152051534f46cdb336 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 24 Sep 2021 10:57:20 +0100
Subject: [PATCH] tests: Add D-Bus object/subtree unregistration tests
These tests cover the fixes from the previous two commits.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2400
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/34ce204fd758e2ce0ab6bf152051534f46cdb336
---
gio/tests/gdbus-export.c | 180 +++++++++++++++++++++++++++++++++++++++
1 file changed, 180 insertions(+)
diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c
index aec21d7d0b..4cdc244924 100644
--- a/gio/tests/gdbus-export.c
+++ b/gio/tests/gdbus-export.c
@@ -1792,6 +1792,184 @@ test_async_properties (void)
g_object_unref (c);
}
+typedef struct
+{
+ GDBusConnection *connection; /* (owned) */
+ guint registration_id;
+ guint subtree_registration_id;
+} ThreadedUnregistrationData;
+
+static gpointer
+unregister_thread_cb (gpointer user_data)
+{
+ ThreadedUnregistrationData *data = user_data;
+
+ /* Sleeping here makes the race more likely to be hit, as it balances the
+ * time taken to set up the thread and unregister, with the time taken to
+ * make and handle the D-Bus call. This will likely change with future kernel
+ * versions, but there isnt a more deterministic synchronisation point that
+ * I can think of to use instead. */
+ usleep (330);
+
+ if (data->registration_id > 0)
+ g_assert_true (g_dbus_connection_unregister_object (data->connection, data->registration_id));
+
+ if (data->subtree_registration_id > 0)
+ g_assert_true (g_dbus_connection_unregister_subtree (data->connection, data->subtree_registration_id));
+
+ return NULL;
+}
+
+static void
+async_result_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GAsyncResult **result_out = user_data;
+
+ *result_out = g_object_ref (result);
+ g_main_context_wakeup (NULL);
+}
+
+/* Returns %TRUE if this iteration resolved the race with the unregistration
+ * first, %FALSE if the call handler was invoked first. */
+static gboolean
+test_threaded_unregistration_iteration (gboolean subtree)
+{
+ ThreadedUnregistrationData data = { NULL, 0, 0 };
+ ObjectRegistrationData object_registration_data = { 0, 0, 2 };
+ GError *local_error = NULL;
+ GThread *unregister_thread = NULL;
+ const gchar *object_path;
+ GVariant *value = NULL;
+ const gchar *value_str;
+ GAsyncResult *call_result = NULL;
+ gboolean unregistration_was_first;
+
+ data.connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error);
+ g_assert_no_error (local_error);
+ g_assert_nonnull (data.connection);
+
+ /* Register an object or a subtree */
+ if (!subtree)
+ {
+ data.registration_id = g_dbus_connection_register_object (data.connection,
+ "/foo/boss",
+ (GDBusInterfaceInfo *) &foo_interface_info,
+ &foo_vtable,
+ &object_registration_data,
+ on_object_unregistered,
+ &local_error);
+ g_assert_no_error (local_error);
+ g_assert_cmpint (data.registration_id, >, 0);
+
+ object_path = "/foo/boss";
+ }
+ else
+ {
+ data.subtree_registration_id = g_dbus_connection_register_subtree (data.connection,
+ "/foo/boss/executives",
+ &subtree_vtable,
+ G_DBUS_SUBTREE_FLAGS_NONE,
+ &object_registration_data,
+ on_subtree_unregistered,
+ &local_error);
+ g_assert_no_error (local_error);
+ g_assert_cmpint (data.subtree_registration_id, >, 0);
+
+ object_path = "/foo/boss/executives/vp0";
+ }
+
+ /* Allow the registrations to go through. */
+ g_main_context_iteration (NULL, FALSE);
+
+ /* Spawn a thread to unregister the object/subtree. This will race with
+ * the call we subsequently make. */
+ unregister_thread = g_thread_new ("unregister-object",
+ unregister_thread_cb, &data);
+
+ /* Call a method on the object (or an object in the subtree). The callback
+ * will be invoked in this main context. */
+ g_dbus_connection_call (data.connection,
+ g_dbus_connection_get_unique_name (data.connection),
+ object_path,
+ "org.example.Foo",
+ "Method1",
+ g_variant_new ("(s)", "winwinwin"),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ async_result_cb,
+ &call_result);
+
+ while (call_result == NULL)
+ g_main_context_iteration (NULL, TRUE);
+
+ value = g_dbus_connection_call_finish (data.connection, call_result, &local_error);
+
+ /* The result of the method could either be an error (that the object doesnt
+ * exist) or a valid result, depending on how the thread was scheduled
+ * relative to the call. */
+ unregistration_was_first = (value == NULL);
+ if (value != NULL)
+ {
+ g_assert_no_error (local_error);
+ g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE ("(s)")));
+ g_variant_get (value, "(&s)", &value_str);
+ g_assert_cmpstr (value_str, ==, "You passed the string 'winwinwin'. Jolly good!");
+ }
+ else
+ {
+ g_assert_null (value);
+ g_assert_error (local_error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
+ }
+
+ g_clear_pointer (&value, g_variant_unref);
+ g_clear_error (&local_error);
+
+ /* Tidy up. */
+ g_thread_join (g_steal_pointer (&unregister_thread));
+
+ g_clear_object (&call_result);
+ g_clear_object (&data.connection);
+
+ return unregistration_was_first;
+}
+
+static void
+test_threaded_unregistration (gconstpointer test_data)
+{
+ gboolean subtree = GPOINTER_TO_INT (test_data);
+ guint i;
+ guint n_iterations_unregistration_first = 0;
+ guint n_iterations_call_first = 0;
+
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2400");
+ g_test_summary ("Test that object/subtree unregistration from one thread "
+ "doesnt cause problems when racing with method callbacks "
+ "in another thread for that object or subtree");
+
+ /* Run iterations of the test until its likely weve hit the race. Limit the
+ * number of iterations so the test doesnt run forever if not. The choice of
+ * 100 is arbitrary. */
+ for (i = 0; i < 1000 && (n_iterations_unregistration_first < 100 || n_iterations_call_first < 100); i++)
+ {
+ if (test_threaded_unregistration_iteration (subtree))
+ n_iterations_unregistration_first++;
+ else
+ n_iterations_call_first++;
+ }
+
+ /* If the condition below is met, we probably failed to reproduce the race.
+ * Dont fail the test, though, as we cant always control whether we hit the
+ * race, and spurious test failures are annoying. */
+ if (n_iterations_unregistration_first < 100 ||
+ n_iterations_call_first < 100)
+ g_strdup_printf ("Failed to reproduce race (%u iterations with unregistration first, %u with call first); skipping test",
+ n_iterations_unregistration_first, n_iterations_call_first);
+}
+
/* ---------------------------------------------------------------------------------------------------- */
int
@@ -1809,6 +1987,8 @@ main (int argc,
g_test_add_func ("/gdbus/object-registration-with-closures", test_object_registration_with_closures);
g_test_add_func ("/gdbus/registered-interfaces", test_registered_interfaces);
g_test_add_func ("/gdbus/async-properties", test_async_properties);
+ g_test_add_data_func ("/gdbus/threaded-unregistration/object", GINT_TO_POINTER (FALSE), test_threaded_unregistration);
+ g_test_add_data_func ("/gdbus/threaded-unregistration/subtree", GINT_TO_POINTER (TRUE), test_threaded_unregistration);
/* TODO: check that we spit out correct introspection data */
/* TODO: check that registering a whole subtree works */
--
GitLab

View File

@ -0,0 +1,69 @@
From f43cf341511dd684a58c09e104e28c11987cbff1 Mon Sep 17 00:00:00 2001
From: Rozhuk Ivan <rozhuk.im@gmail.com>
Date: Sat, 25 Jun 2022 18:46:08 +0300
Subject: [PATCH] [PATCH] Add lock in _g_get_unix_mount_points() around
*fsent() functions
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/f43cf341511dd684a58c09e104e28c11987cbff1
---
gio/gunixmounts.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index 563bdba3b2..3005aa7af3 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -1410,17 +1410,13 @@ _g_get_unix_mount_points (void)
{
struct fstab *fstab = NULL;
GUnixMountPoint *mount_point;
- GList *return_list;
+ GList *return_list = NULL;
+ G_LOCK_DEFINE_STATIC (fsent);
#ifdef HAVE_SYS_SYSCTL_H
int usermnt = 0;
struct stat sb;
#endif
-
- if (!setfsent ())
- return NULL;
- return_list = NULL;
-
#ifdef HAVE_SYS_SYSCTL_H
#if defined(HAVE_SYSCTLBYNAME)
{
@@ -1448,7 +1444,14 @@ _g_get_unix_mount_points (void)
}
#endif
#endif
-
+
+ G_LOCK (fsent);
+ if (!setfsent ())
+ {
+ G_UNLOCK (fsent);
+ return NULL;
+ }
+
while ((fstab = getfsent ()) != NULL)
{
gboolean is_read_only = FALSE;
@@ -1482,9 +1485,10 @@ _g_get_unix_mount_points (void)
return_list = g_list_prepend (return_list, mount_point);
}
-
+
endfsent ();
-
+ G_UNLOCK (fsent);
+
return g_list_reverse (return_list);
}
/* Interix {{{2 */
--
GitLab

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
From 78da5faccb3e065116b75b3ff87ff55381da6c76 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 15 Dec 2022 13:00:39 +0000
Subject: [PATCH 1/2] =?UTF-8?q?gvariant:=20Check=20offset=20table=20doesn?=
=?UTF-8?q?=E2=80=99t=20fall=20outside=20variant=20bounds?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When dereferencing the first entry in the offset table for a tuple,
check that it doesnt fall outside the bounds of the variant first.
This prevents an out-of-bounds read from some non-normal tuples.
This bug was introduced in commit 73d0aa81c2575a5c9ae77d.
Includes a unit test, although the test will likely only catch the
original bug if run with asan enabled.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2840
oss-fuzz#54302
---
glib/gvariant-serialiser.c | 12 ++++++--
glib/tests/gvariant.c | 63 ++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index f443c2eb85..4e4a73ad17 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -984,7 +984,8 @@ gvs_tuple_get_member_bounds (GVariantSerialised value,
member_info = g_variant_type_info_member_info (value.type_info, index_);
- if (member_info->i + 1)
+ if (member_info->i + 1 &&
+ offset_size * (member_info->i + 1) <= value.size)
member_start = gvs_read_unaligned_le (value.data + value.size -
offset_size * (member_info->i + 1),
offset_size);
@@ -995,7 +996,8 @@ gvs_tuple_get_member_bounds (GVariantSerialised value,
member_start &= member_info->b;
member_start |= member_info->c;
- if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST)
+ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST &&
+ offset_size * (member_info->i + 1) <= value.size)
member_end = value.size - offset_size * (member_info->i + 1);
else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED)
@@ -1006,11 +1008,15 @@ gvs_tuple_get_member_bounds (GVariantSerialised value,
member_end = member_start + fixed_size;
}
- else /* G_VARIANT_MEMBER_ENDING_OFFSET */
+ else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET &&
+ offset_size * (member_info->i + 2) <= value.size)
member_end = gvs_read_unaligned_le (value.data + value.size -
offset_size * (member_info->i + 2),
offset_size);
+ else /* invalid */
+ member_end = G_MAXSIZE;
+
if (out_member_start != NULL)
*out_member_start = member_start;
if (out_member_end != NULL)
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index b360888e4d..98c51a1d75 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -5576,6 +5576,67 @@ test_normal_checking_tuple_offsets4 (void)
g_variant_unref (variant);
}
+/* This is a regression test that dereferencing the first element in the offset
+ * table doesnt dereference memory before the start of the GVariant. The first
+ * element in the offset table gives the offset of the final member in the
+ * tuple (the offset table is stored in reverse), and the position of this final
+ * member is needed to check that none of the tuple members overlap with the
+ * offset table
+ *
+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2840 */
+static void
+test_normal_checking_tuple_offsets5 (void)
+{
+ /* A tuple of type (sss) in normal form would have an offset table with two
+ * entries:
+ * - The first entry (lowest index in the table) gives the offset of the
+ * third `s` in the tuple, as the offset table is reversed compared to the
+ * tuple members.
+ * - The second entry (highest index in the table) gives the offset of the
+ * second `s` in the tuple.
+ * - The offset of the first `s` in the tuple is always 0.
+ *
+ * See §2.5.4 (Structures) of the GVariant specification for details, noting
+ * that the table is only layed out this way because all three members of the
+ * tuple have non-fixed sizes.
+ *
+ * Its not clear whether the 0xaa data of this variant is part of the strings
+ * in the tuple, or part of the offset table. It doesnt really matter. This
+ * is a regression test to check that the code to validate the offset table
+ * doesnt unconditionally try to access the first entry in the offset table
+ * by subtracting the table size from the end of the GVariant data.
+ *
+ * In this non-normal case, that would result in an address off the start of
+ * the GVariant data, and an out-of-bounds read, because the GVariant is one
+ * byte long, but the offset table is calculated as two bytes long (with 1B
+ * sized entries) from the tuples type.
+ */
+ const GVariantType *data_type = G_VARIANT_TYPE ("(sss)");
+ const guint8 data[] = { 0xaa };
+ gsize size = sizeof (data);
+ GVariant *variant = NULL;
+ GVariant *normal_variant = NULL;
+ GVariant *expected = NULL;
+
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2840");
+
+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL);
+ g_assert_nonnull (variant);
+
+ g_assert_false (g_variant_is_normal_form (variant));
+
+ normal_variant = g_variant_get_normal_form (variant);
+ g_assert_nonnull (normal_variant);
+
+ expected = g_variant_new_parsed ("('', '', '')");
+ g_assert_cmpvariant (expected, variant);
+ g_assert_cmpvariant (expected, normal_variant);
+
+ g_variant_unref (expected);
+ g_variant_unref (normal_variant);
+ g_variant_unref (variant);
+}
+
/* Test that an otherwise-valid serialised GVariant is considered non-normal if
* its offset table entries are too wide.
*
@@ -5827,6 +5888,8 @@ main (int argc, char **argv)
test_normal_checking_tuple_offsets3);
g_test_add_func ("/gvariant/normal-checking/tuple-offsets4",
test_normal_checking_tuple_offsets4);
+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets5",
+ test_normal_checking_tuple_offsets5);
g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized",
test_normal_checking_tuple_offsets_minimal_sized);
g_test_add_func ("/gvariant/normal-checking/empty-object-path",
--
GitLab
From 21a204147b16539b3eda3143b32844c49e29f4d4 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 15 Dec 2022 16:49:28 +0000
Subject: [PATCH 2/2] gvariant: Propagate trust when getting a child of a
serialised variant
If a variant is trusted, that means all its children are trusted, so
ensure that their checked offsets are set as such.
This allows a lot of the offset table checks to be avoided when getting
children from trusted serialised tuples, which speeds things up.
No unit test is included because this is just a performance fix. If
there are other slownesses, or regressions, in serialised `GVariant`
performance, the fuzzing setup will catch them like it did this one.
This change does reduce the time to run the oss-fuzz reproducer from 80s
to about 0.7s on my machine.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2841
oss-fuzz#54314
---
glib/gvariant-core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
index f441c4757e..4778022829 100644
--- a/glib/gvariant-core.c
+++ b/glib/gvariant-core.c
@@ -1198,8 +1198,8 @@ g_variant_get_child_value (GVariant *value,
child->contents.serialised.bytes =
g_bytes_ref (value->contents.serialised.bytes);
child->contents.serialised.data = s_child.data;
- child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to;
- child->contents.serialised.checked_offsets_up_to = s_child.checked_offsets_up_to;
+ child->contents.serialised.ordered_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.ordered_offsets_up_to;
+ child->contents.serialised.checked_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.checked_offsets_up_to;
return child;
}
--
GitLab

View File

@ -0,0 +1,26 @@
From 6ec432386ef98e26e5079b060ad823277e10f41f Mon Sep 17 00:00:00 2001
From: Loic Le Page <llepage@fluendo.com>
Date: Wed, 26 Jan 2022 14:20:08 +0100
Subject: [PATCH] Fix memory leak in gio/gdbusauthmechanismsha1.c
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/6ec432386ef98e26e5079b060ad823277e10f41f
---
gio/gdbusauthmechanismsha1.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/gdbusauthmechanismsha1.c b/gio/gdbusauthmechanismsha1.c
index a82dddf839..8137b6352d 100644
--- a/gio/gdbusauthmechanismsha1.c
+++ b/gio/gdbusauthmechanismsha1.c
@@ -909,6 +909,7 @@ keyring_generate_entry (const gchar *cookie_context,
_("(Additionally, releasing the lock for “%s” also failed: %s) "),
path,
local_error->message);
+ g_error_free (local_error);
}
}
else
--
GitLab

View File

@ -0,0 +1,68 @@
From d9ba6150909818beb05573f54f26232063492c5b Mon Sep 17 00:00:00 2001
From: Emmanuel Fleury <emmanuel.fleury@gmail.com>
Date: Mon, 1 Aug 2022 19:05:14 +0200
Subject: [PATCH] Handling collision between standard i/o file descriptors and
newly created ones
Though unlikely to happen, it may happen that newly created file
descriptor take the value 0 (stdin), 1 (stdout) or 2 (stderr) if one
of the standard ones have been dismissed in between. So, it may
confuse the program if it is unaware of this change.
The point of this patch is to avoid a reasign of standard file
descriptors on newly created ones.
Closes issue #16
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d9ba6150909818beb05573f54f26232063492c5b
---
glib/glib-unix.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/glib/glib-unix.c b/glib/glib-unix.c
index d2dea10ef0..d67b8a357a 100644
--- a/glib/glib-unix.c
+++ b/glib/glib-unix.c
@@ -108,6 +108,17 @@ g_unix_open_pipe (int *fds,
ecode = pipe2 (fds, pipe2_flags);
if (ecode == -1 && errno != ENOSYS)
return g_unix_set_error_from_errno (error, errno);
+ /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
+ else if (fds[0] < 3 || fds[1] < 3)
+ {
+ int old_fds[2] = { fds[0], fds[1] };
+ gboolean result = g_unix_open_pipe (fds, flags, error);
+ close (old_fds[0]);
+ close (old_fds[1]);
+
+ if (!result)
+ g_unix_set_error_from_errno (error, errno);
+ }
else if (ecode == 0)
return TRUE;
/* Fall through on -ENOSYS, we must be running on an old kernel */
@@ -116,6 +127,19 @@ g_unix_open_pipe (int *fds,
ecode = pipe (fds);
if (ecode == -1)
return g_unix_set_error_from_errno (error, errno);
+ /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
+ else if (fds[0] < 3 || fds[1] < 3)
+ {
+ int old_fds[2] = { fds[0], fds[1] };
+ gboolean result = g_unix_open_pipe (fds, flags, error);
+ close (old_fds[0]);
+ close (old_fds[1]);
+
+ if (!result)
+ g_unix_set_error_from_errno (error, errno);
+
+ return result;
+ }
if (flags == 0)
return TRUE;
--
GitLab

View File

@ -0,0 +1,52 @@
From a9394bd68e222377f0156bf9c213b3f3a1e340d0 Mon Sep 17 00:00:00 2001
From: Emmanuele Bassi <ebassi@gnome.org>
Date: Sat, 30 Jul 2022 20:03:42 +0100
Subject: [PATCH] Implement GFileIface.set_display_name() for resource files
Resource files cannot be renamed, and GFileIface.set_display_name() is
mandatory.
Fixes: #2705
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a9394bd68e222377f0156bf9c213b3f3a1e340d0
---
gio/gresourcefile.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/gio/gresourcefile.c b/gio/gresourcefile.c
index 340d3378b3..24f20f2903 100644
--- a/gio/gresourcefile.c
+++ b/gio/gresourcefile.c
@@ -646,6 +646,19 @@ g_resource_file_monitor_file (GFile *file,
return g_object_new (g_resource_file_monitor_get_type (), NULL);
}
+static GFile *
+g_resource_file_set_display_name (GFile *file,
+ const char *display_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Resource files cannot be renamed"));
+ return NULL;
+}
+
static void
g_resource_file_file_iface_init (GFileIface *iface)
{
@@ -664,6 +677,7 @@ g_resource_file_file_iface_init (GFileIface *iface)
iface->get_relative_path = g_resource_file_get_relative_path;
iface->resolve_relative_path = g_resource_file_resolve_relative_path;
iface->get_child_for_display_name = g_resource_file_get_child_for_display_name;
+ iface->set_display_name = g_resource_file_set_display_name;
iface->enumerate_children = g_resource_file_enumerate_children;
iface->query_info = g_resource_file_query_info;
iface->query_filesystem_info = g_resource_file_query_filesystem_info;
--
GitLab

View File

@ -0,0 +1,67 @@
From dad97d24d578dbefbebb41829b0ffb9e783cac7b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 28 Oct 2022 11:21:04 -0400
Subject: [PATCH] Revert "Handling collision between standard i/o file
descriptors and newly created ones"
g_unix_open_pipe tries to avoid the standard io fd range
when getting pipe fds. This turns out to be a bad idea because
certain buggy programs rely on it using that range.
This reverts commit d9ba6150909818beb05573f54f26232063492c5b
Closes: #2795
Reopens: #16
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/dad97d24d578dbefbebb41829b0ffb9e783cac7b
---
glib/glib-unix.c | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/glib/glib-unix.c b/glib/glib-unix.c
index 4710c51168..bc152d7663 100644
--- a/glib/glib-unix.c
+++ b/glib/glib-unix.c
@@ -108,17 +108,6 @@ g_unix_open_pipe (int *fds,
ecode = pipe2 (fds, pipe2_flags);
if (ecode == -1 && errno != ENOSYS)
return g_unix_set_error_from_errno (error, errno);
- /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
- else if (fds[0] < 3 || fds[1] < 3)
- {
- int old_fds[2] = { fds[0], fds[1] };
- gboolean result = g_unix_open_pipe (fds, flags, error);
- close (old_fds[0]);
- close (old_fds[1]);
-
- if (!result)
- g_unix_set_error_from_errno (error, errno);
- }
else if (ecode == 0)
return TRUE;
/* Fall through on -ENOSYS, we must be running on an old kernel */
@@ -127,19 +116,6 @@ g_unix_open_pipe (int *fds,
ecode = pipe (fds);
if (ecode == -1)
return g_unix_set_error_from_errno (error, errno);
- /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
- else if (fds[0] < 3 || fds[1] < 3)
- {
- int old_fds[2] = { fds[0], fds[1] };
- gboolean result = g_unix_open_pipe (fds, flags, error);
- close (old_fds[0]);
- close (old_fds[1]);
-
- if (!result)
- g_unix_set_error_from_errno (error, errno);
-
- return result;
- }
if (flags == 0)
return TRUE;
--
GitLab

View File

@ -0,0 +1,52 @@
From 9f1c59eef2e21b5a80c22d44deec2cba884cdfce Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
Date: Mon, 11 Oct 2021 15:31:01 +0300
Subject: [PATCH] add OOM handling in mimemagic
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/9f1c59eef2e21b5a80c22d44deec2cba884cdfce
---
gio/xdgmime/xdgmimemagic.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/gio/xdgmime/xdgmimemagic.c b/gio/xdgmime/xdgmimemagic.c
index c68e27bedb..08b2c6da4f 100644
--- a/gio/xdgmime/xdgmimemagic.c
+++ b/gio/xdgmime/xdgmimemagic.c
@@ -103,6 +103,8 @@ _xdg_mime_magic_matchlet_new (void)
XdgMimeMagicMatchlet *matchlet;
matchlet = malloc (sizeof (XdgMimeMagicMatchlet));
+ if (matchlet == NULL)
+ return NULL;
matchlet->indent = 0;
matchlet->offset = 0;
@@ -355,6 +357,11 @@ _xdg_mime_magic_parse_magic_line (FILE *magic_file,
return XDG_MIME_MAGIC_ERROR;
matchlet = _xdg_mime_magic_matchlet_new ();
+
+ /* OOM */
+ if (matchlet == NULL)
+ return XDG_MIME_MAGIC_ERROR;
+
matchlet->indent = indent;
matchlet->offset = _xdg_mime_magic_read_a_number (magic_file, &end_of_file);
if (end_of_file)
@@ -767,6 +774,11 @@ _xdg_mime_magic_read_magic_file (XdgMimeMagic *mime_magic,
{
case XDG_MIME_MAGIC_SECTION:
match = _xdg_mime_magic_match_new ();
+
+ /* OOM */
+ if (match == NULL)
+ return;
+
state = _xdg_mime_magic_parse_header (magic_file, match);
if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR)
_xdg_mime_magic_match_free (match);
--
GitLab

View File

@ -0,0 +1,140 @@
From 63873c0eb114faf6696874fe577912af687d67cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Wed, 21 Apr 2021 06:17:36 +0200
Subject: [PATCH] application: Unset the registered state after shutting down
An application that has been shut down is still marked as registered
even if its implementation has been already destroyed.
This may lead to unguarded crashes when calling functions that have
assumptions for being used with registered applications.
So, when an application is registered, mark it as unregistered just
before destroying its implementation and after being shut down, so that
we follow the registration process in reversed order.
Added tests
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/63873c0eb114faf6696874fe577912af687d67cf
---
gio/gapplication.c | 7 ++++
gio/tests/gapplication.c | 76 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+)
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 8e65176354..bf4a4cb650 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -2578,6 +2578,13 @@ g_application_run (GApplication *application,
if (application->priv->impl)
{
+ if (application->priv->is_registered)
+ {
+ application->priv->is_registered = FALSE;
+
+ g_object_notify (G_OBJECT (application), "is-registered");
+ }
+
g_application_impl_flush (application->priv->impl);
g_application_impl_destroy (application->priv->impl);
application->priv->impl = NULL;
diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c
index 900e7ac977..6f1a27e0f3 100644
--- a/gio/tests/gapplication.c
+++ b/gio/tests/gapplication.c
@@ -576,6 +576,81 @@ test_quit (void)
g_free (binpath);
}
+typedef struct
+{
+ gboolean shutdown;
+ GParamSpec *notify_spec; /* (owned) (nullable) */
+} RegisteredData;
+
+static void
+on_registered_shutdown (GApplication *app,
+ gpointer user_data)
+{
+ RegisteredData *registered_data = user_data;
+
+ registered_data->shutdown = TRUE;
+}
+
+static void
+on_registered_notify (GApplication *app,
+ GParamSpec *spec,
+ gpointer user_data)
+{
+ RegisteredData *registered_data = user_data;
+ registered_data->notify_spec = g_param_spec_ref (spec);
+
+ if (g_application_get_is_registered (app))
+ g_assert_false (registered_data->shutdown);
+ else
+ g_assert_true (registered_data->shutdown);
+}
+
+static void
+test_registered (void)
+{
+ char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
+ gchar *argv[] = { binpath, NULL };
+ RegisteredData registered_data = { FALSE, NULL };
+ GApplication *app;
+
+ app = g_application_new (NULL, G_APPLICATION_FLAGS_NONE);
+ g_signal_connect (app, "activate", G_CALLBACK (noappid_activate), NULL);
+ g_signal_connect (app, "shutdown", G_CALLBACK (on_registered_shutdown), &registered_data);
+ g_signal_connect (app, "notify::is-registered", G_CALLBACK (on_registered_notify), &registered_data);
+
+ g_assert_null (registered_data.notify_spec);
+
+ g_assert_true (g_application_register (app, NULL, NULL));
+ g_assert_true (g_application_get_is_registered (app));
+
+ g_assert_nonnull (registered_data.notify_spec);
+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered");
+ g_clear_pointer (&registered_data.notify_spec, g_param_spec_unref);
+
+ g_assert_false (registered_data.shutdown);
+
+ g_application_run (app, 1, argv);
+
+ g_assert_true (registered_data.shutdown);
+ g_assert_false (g_application_get_is_registered (app));
+ g_assert_nonnull (registered_data.notify_spec);
+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered");
+ g_clear_pointer (&registered_data.notify_spec, g_param_spec_unref);
+
+ /* Register it again */
+ registered_data.shutdown = FALSE;
+ g_assert_true (g_application_register (app, NULL, NULL));
+ g_assert_true (g_application_get_is_registered (app));
+ g_assert_nonnull (registered_data.notify_spec);
+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered");
+ g_clear_pointer (&registered_data.notify_spec, g_param_spec_unref);
+ g_assert_false (registered_data.shutdown);
+
+ g_object_unref (app);
+
+ g_free (binpath);
+}
+
static void
on_activate (GApplication *app)
{
@@ -1136,6 +1211,7 @@ main (int argc, char **argv)
g_test_add_func ("/gapplication/properties", properties);
g_test_add_func ("/gapplication/app-id", appid);
g_test_add_func ("/gapplication/quit", test_quit);
+ g_test_add_func ("/gapplication/registered", test_registered);
g_test_add_func ("/gapplication/local-actions", test_local_actions);
/* g_test_add_func ("/gapplication/remote-actions", test_remote_actions); */
g_test_add_func ("/gapplication/local-command-line", test_local_command_line);
--
GitLab

View File

@ -0,0 +1,28 @@
From b71117d89434db83d34bc1b981ca03d4be299576 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Thu, 8 Jul 2021 17:26:43 -0700
Subject: [PATCH] correctly use 3 parameters for close_range
libc implementation has 3 parameter e.g.
https://www.freebsd.org/cgi/man.cgi?query=close_range&sektion=2&format=html
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
glib/gspawn.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/gspawn.c b/glib/gspawn.c
index 899647c2f..3073a10a4 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -1520,7 +1520,7 @@ safe_closefrom (int lowfd)
*
* Handle ENOSYS in case its supported in libc but not the kernel; if so,
* fall back to safe_fdwalk(). */
- if (close_range (lowfd, G_MAXUINT) != 0 && errno == ENOSYS)
+ if (close_range (lowfd, G_MAXUINT, 0) != 0 && errno == ENOSYS)
#endif /* HAVE_CLOSE_RANGE */
(void) safe_fdwalk (close_func, GINT_TO_POINTER (lowfd));
#endif
--
GitLab

View File

@ -0,0 +1,34 @@
From 27203e48c91ab8b55033dcf1773cb60c0aaed3fa Mon Sep 17 00:00:00 2001
From: Sebastian Keller <skeller@gnome.org>
Date: Tue, 30 Aug 2022 21:39:36 +0200
Subject: [PATCH] documentportal: Fix small leak in add_documents with empty
URI list
When called with an empty URI list (or only inaccessible files),
g_document_portal_add_documents would not call g_variant_builder_end,
leaking the memory allocated by the variant builder.
Closes: https://gitlab.gnome.org/GNOME/glib/-/issues/2733
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/27203e48c91ab8b55033dcf1773cb60c0aaed3fa
---
gio/gdocumentportal.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/gdocumentportal.c b/gio/gdocumentportal.c
index c08c36c581..382e2aab6e 100644
--- a/gio/gdocumentportal.c
+++ b/gio/gdocumentportal.c
@@ -203,6 +203,7 @@ g_document_portal_add_documents (GList *uris,
else
{
ruris = g_list_copy_deep (uris, (GCopyFunc)g_strdup, NULL);
+ g_variant_builder_clear (&builder);
}
out:
--
GitLab

View File

@ -0,0 +1,27 @@
From df500c68a4d0741d1d6cf8ec3f8039a0d1f4b174 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= <gael@xfce.org>
Date: Tue, 1 Jun 2021 17:43:45 +0200
Subject: [PATCH] inotify: Fix a memory leak
Fixes: #2311
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/df500c68a4d0741d1d6cf8ec3f8039a0d1f4b174
---
gio/inotify/inotify-path.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/inotify/inotify-path.c b/gio/inotify/inotify-path.c
index f0528f4..e1129cd 100644
--- a/gio/inotify/inotify-path.c
+++ b/gio/inotify/inotify-path.c
@@ -208,6 +208,7 @@ ip_watched_file_free (ip_watched_file_t *file)
g_assert (file->subs == NULL);
g_free (file->filename);
g_free (file->path);
+ g_free (file);
}
static void
--
2.27.0

View File

@ -0,0 +1,46 @@
From 02d0d6497b92d05d1145d1077654ad2453938b6c Mon Sep 17 00:00:00 2001
From: Rozhuk Ivan <rozhuk.im@gmail.com>
Date: Sat, 25 Jun 2022 19:01:30 +0300
Subject: [PATCH] [PATCH] _g_get_unix_mount_points(): reduce syscalls inside
loop
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/02d0d6497b92d05d1145d1077654ad2453938b6c
---
gio/gunixmounts.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index ba08245..92ab163 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -1414,6 +1414,7 @@ _g_get_unix_mount_points (void)
GList *return_list = NULL;
G_LOCK_DEFINE_STATIC (fsent);
#ifdef HAVE_SYS_SYSCTL_H
+ uid_t uid = getuid ();
int usermnt = 0;
struct stat sb;
#endif
@@ -1466,14 +1467,13 @@ _g_get_unix_mount_points (void)
#ifdef HAVE_SYS_SYSCTL_H
if (usermnt != 0)
- {
- uid_t uid = getuid ();
- if (stat (fstab->fs_file, &sb) == 0)
- {
- if (uid == 0 || sb.st_uid == uid)
- is_user_mountable = TRUE;
- }
- }
+ {
+ if (uid == 0 ||
+ (stat (fstab->fs_file, &sb) == 0 && sb.st_uid == uid))
+ {
+ is_user_mountable = TRUE;
+ }
+ }
#endif
mount_point = create_unix_mount_point (fstab->fs_spec,

View File

@ -0,0 +1,44 @@
From 65b4bc30eb38b1484533a2ee08f7229a9e961af8 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Wed, 31 Mar 2021 11:44:23 -0500
Subject: [PATCH] gapplication: fix arguments leak in error path
If this g_return_val_if_fail() is ever hit, then we leak arguments.
This is not very important because if your code hits
g_return_val_if_fail() you are invoking undefined behavior, a rather
more serious problem, but let's replace it with g_critical() to be
robust.
This includes a small behavior change: it returns 1 rather than 0 in
this error case.
Found by Coverity.
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/65b4bc30eb38b1484533a2ee08f7229a9e961af8
---
gio/gapplication.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 5a43202a5d..8e65176354 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -2524,7 +2524,12 @@ g_application_run (GApplication *application,
context = g_main_context_default ();
acquired_context = g_main_context_acquire (context);
- g_return_val_if_fail (acquired_context, 0);
+ if (!acquired_context)
+ {
+ g_critical ("g_application_run() cannot acquire the default main context because it is already acquired by another thread!");
+ g_strfreev (arguments);
+ return 1;
+ }
if (!G_APPLICATION_GET_CLASS (application)
->local_command_line (application, &arguments, &status))
--
GitLab

View File

@ -0,0 +1,55 @@
From 374a1895b62b2504d0b6ae1c404237802e73ddb6 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann <tobias@stoeckmann.org>
Date: Tue, 18 Jan 2022 13:45:13 +0000
Subject: [PATCH] garray: Fix integer overflows in element capacity
calculations
Integer overflows in size calculations of buffers (GArray and GPtrArray)
allow subsequent buffer overflows. This happens due to conversions
between gsize and guint.
Proof of concept demonstrations of the overflows can be found in issue
2578. They are not being added as unit tests as they require too much
memory to test.
This will affect `GArray`s which are 4GB in size, or `GPtrArray`s which
are 48GB in size.
Fixes: #2578
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/374a1895b62b2504d0b6ae1c404237802e73ddb6
---
glib/garray.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/glib/garray.c b/glib/garray.c
index 3803fee037..b441562154 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -1001,7 +1001,7 @@ g_array_maybe_expand (GRealArray *array,
memset (g_array_elt_pos (array, array->elt_capacity), 0,
g_array_elt_len (array, want_len - array->elt_capacity));
- array->elt_capacity = want_alloc / array->elt_size;
+ array->elt_capacity = MIN (want_alloc / array->elt_size, G_MAXUINT);
}
}
@@ -1518,9 +1518,10 @@ g_ptr_array_maybe_expand (GRealPtrArray *array,
if ((array->len + len) > array->alloc)
{
guint old_alloc = array->alloc;
- array->alloc = g_nearest_pow (array->len + len);
- array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
- array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc);
+ gsize want_alloc = g_nearest_pow (sizeof (gpointer) * (array->len + len));
+ want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
+ array->alloc = MIN (want_alloc / sizeof (gpointer), G_MAXUINT);
+ array->pdata = g_realloc (array->pdata, want_alloc);
if (G_UNLIKELY (g_mem_gc_friendly))
for ( ; old_alloc < array->alloc; old_alloc++)
array->pdata [old_alloc] = NULL;
--
GitLab

View File

@ -0,0 +1,279 @@
From 995823b9d9e866ffb133cf3ff53e7e09da9f13d6 Mon Sep 17 00:00:00 2001
From: Mark Weaver <mark@blushingpenguin.com>
Date: Tue, 19 Oct 2021 15:38:13 +0000
Subject: [PATCH] #1331: buffer overflow fix
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/995823b9d9e866ffb133cf3ff53e7e09da9f13d6
---
glib/garray.c | 57 ++++++++++++++++++++-----------------
glib/tests/array-test.c | 62 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 25 deletions(-)
diff --git a/glib/garray.c b/glib/garray.c
index 025747ee56..d072441906 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -107,7 +107,7 @@ struct _GRealArray
{
guint8 *data;
guint len;
- guint alloc;
+ guint elt_capacity;
guint elt_size;
guint zero_terminated : 1;
guint clear : 1;
@@ -150,7 +150,7 @@ struct _GRealArray
* Returns: the element of the #GArray at the index given by @i
*/
-#define g_array_elt_len(array,i) ((array)->elt_size * (i))
+#define g_array_elt_len(array,i) ((gsize)(array)->elt_size * (i))
#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
#define g_array_elt_zero(array, pos, len) \
(memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len)))
@@ -159,7 +159,7 @@ struct _GRealArray
g_array_elt_zero ((array), (array)->len, 1); \
}G_STMT_END
-static guint g_nearest_pow (guint num) G_GNUC_CONST;
+static gsize g_nearest_pow (gsize num) G_GNUC_CONST;
static void g_array_maybe_expand (GRealArray *array,
guint len);
@@ -181,6 +181,7 @@ g_array_new (gboolean zero_terminated,
guint elt_size)
{
g_return_val_if_fail (elt_size > 0, NULL);
+ g_return_val_if_fail (elt_size <= G_MAXUINT / 2 - 1, NULL);
return g_array_sized_new (zero_terminated, clear, elt_size, 0);
}
@@ -232,7 +233,7 @@ g_array_steal (GArray *array,
rarray->data = NULL;
rarray->len = 0;
- rarray->alloc = 0;
+ rarray->elt_capacity = 0;
return segment;
}
@@ -261,12 +262,13 @@ g_array_sized_new (gboolean zero_terminated,
GRealArray *array;
g_return_val_if_fail (elt_size > 0, NULL);
+ g_return_val_if_fail (elt_size <= G_MAXUINT, NULL);
array = g_slice_new (GRealArray);
array->data = NULL;
array->len = 0;
- array->alloc = 0;
+ array->elt_capacity = 0;
array->zero_terminated = (zero_terminated ? 1 : 0);
array->clear = (clear ? 1 : 0);
array->elt_size = elt_size;
@@ -471,7 +473,7 @@ array_free (GRealArray *array,
{
array->data = NULL;
array->len = 0;
- array->alloc = 0;
+ array->elt_capacity = 0;
}
else
{
@@ -966,22 +968,22 @@ g_array_binary_search (GArray *array,
return result;
}
-/* Returns the smallest power of 2 greater than n, or n if
- * such power does not fit in a guint
+/* Returns the smallest power of 2 greater than or equal to n,
+ * or 0 if such power does not fit in a gsize
*/
-static guint
-g_nearest_pow (guint num)
+static gsize
+g_nearest_pow (gsize num)
{
- guint n = num - 1;
+ gsize n = num - 1;
- g_assert (num > 0);
+ g_assert (num > 0 && num <= G_MAXSIZE / 2);
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
-#if SIZEOF_INT == 8
+#if GLIB_SIZEOF_SIZE_T == 8
n |= n >> 32;
#endif
@@ -992,26 +994,32 @@ static void
g_array_maybe_expand (GRealArray *array,
guint len)
{
- guint want_alloc;
+ guint max_len, want_len;
+
+ /* The maximum array length is derived from following constraints:
+ * - The number of bytes must fit into a gsize / 2.
+ * - The number of elements must fit into guint.
+ * - zero terminated arrays must leave space for the terminating element
+ */
+ max_len = MIN (G_MAXSIZE / 2 / array->elt_size, G_MAXUINT) - array->zero_terminated;
/* Detect potential overflow */
- if G_UNLIKELY ((G_MAXUINT - array->len) < len)
+ if G_UNLIKELY ((max_len - array->len) < len)
g_error ("adding %u to array would overflow", len);
- want_alloc = g_array_elt_len (array, array->len + len +
- array->zero_terminated);
-
- if (want_alloc > array->alloc)
+ want_len = array->len + len + array->zero_terminated;
+ if (want_len > array->elt_capacity)
{
- want_alloc = g_nearest_pow (want_alloc);
+ gsize want_alloc = g_nearest_pow (g_array_elt_len (array, want_len));
want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
array->data = g_realloc (array->data, want_alloc);
if (G_UNLIKELY (g_mem_gc_friendly))
- memset (array->data + array->alloc, 0, want_alloc - array->alloc);
+ memset (g_array_elt_pos (array, array->elt_capacity), 0,
+ g_array_elt_len (array, want_len - array->elt_capacity));
- array->alloc = want_alloc;
+ array->elt_capacity = want_alloc / array->elt_size;
}
}
@@ -1297,7 +1305,7 @@ g_array_copy (GArray *array)
new_rarray =
(GRealArray *) g_array_sized_new (rarray->zero_terminated, rarray->clear,
- rarray->elt_size, rarray->alloc / rarray->elt_size);
+ rarray->elt_size, rarray->elt_capacity);
new_rarray->len = rarray->len;
if (rarray->len > 0)
memcpy (new_rarray->data, rarray->data, rarray->len * rarray->elt_size);
@@ -2298,7 +2306,6 @@ g_byte_array_new_take (guint8 *data,
GRealArray *real;
g_return_val_if_fail (len <= G_MAXUINT, NULL);
-
array = g_byte_array_new ();
real = (GRealArray *)array;
g_assert (real->data == NULL);
@@ -2306,7 +2313,7 @@ g_byte_array_new_take (guint8 *data,
real->data = data;
real->len = len;
- real->alloc = len;
+ real->elt_capacity = len;
return array;
}
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
index 471f6171dc..79c5c31c32 100644
--- a/glib/tests/array-test.c
+++ b/glib/tests/array-test.c
@@ -845,6 +845,45 @@ test_array_copy_sized (void)
g_array_unref (array1);
}
+static void
+array_overflow_append_vals (void)
+{
+ if (!g_test_undefined ())
+ return;
+
+ if (g_test_subprocess ())
+ {
+ GArray *array = g_array_new (TRUE, FALSE, 1);
+ /* Check for overflow should happen before data is accessed. */
+ g_array_append_vals (array, NULL, G_MAXUINT);
+ }
+ else
+ {
+ g_test_trap_subprocess (NULL, 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*");
+ }
+}
+
+static void
+array_overflow_set_size (void)
+{
+ if (!g_test_undefined ())
+ return;
+
+ if (g_test_subprocess ())
+ {
+ GArray *array = g_array_new (TRUE, FALSE, 1);
+ g_array_set_size (array, G_MAXUINT);
+ }
+ else
+ {
+ g_test_trap_subprocess (NULL, 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*");
+ }
+}
+
/* Check g_ptr_array_steal() function */
static void
pointer_array_steal (void)
@@ -1643,6 +1682,26 @@ pointer_array_steal_index (void)
g_assert_cmpuint (i4, ==, 1);
}
+static void
+byte_array_new_take_overflow (void)
+{
+#if G_MAXSIZE <= G_MAXUINT
+ g_test_skip ("Overflow test requires G_MAXSIZE > G_MAXUINT.");
+#else
+ GByteArray* arr;
+
+ if (!g_test_undefined ())
+ return;
+
+ /* Check for overflow should happen before data is accessed. */
+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+ "*assertion 'len <= G_MAXUINT' failed");
+ arr = g_byte_array_new_take (NULL, (gsize)G_MAXUINT + 1);
+ g_assert_null (arr);
+ g_test_assert_expected_messages ();
+#endif
+}
+
static void
byte_array_steal (void)
{
@@ -1998,6 +2057,8 @@ main (int argc, char *argv[])
g_test_add_func ("/array/clear-func", array_clear_func);
g_test_add_func ("/array/binary-search", test_array_binary_search);
g_test_add_func ("/array/copy-sized", test_array_copy_sized);
+ g_test_add_func ("/array/overflow-append-vals", array_overflow_append_vals);
+ g_test_add_func ("/array/overflow-set-size", array_overflow_set_size);
for (i = 0; i < G_N_ELEMENTS (array_configurations); i++)
{
@@ -2043,6 +2104,7 @@ main (int argc, char *argv[])
g_test_add_func ("/bytearray/sort", byte_array_sort);
g_test_add_func ("/bytearray/sort-with-data", byte_array_sort_with_data);
g_test_add_func ("/bytearray/new-take", byte_array_new_take);
+ g_test_add_func ("/bytearray/new-take-overflow", byte_array_new_take_overflow);
g_test_add_func ("/bytearray/free-to-bytes", byte_array_free_to_bytes);
return g_test_run ();
--
GitLab

View File

@ -0,0 +1,27 @@
From 2b29495bcb59ba00bec808c509112dae6e019fd7 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Wed, 31 Mar 2021 14:12:39 -0500
Subject: [PATCH] gdbusauth: fix error leak
local_error is leaked in the G_IO_ERROR_NOT_SUPPORTED case. Found by
Coverity.
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/2b29495bcb59ba00bec808c509112dae6e019fd7
---
gio/gdbusauth.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
index c430f0cf03..534dca2d19 100644
--- a/gio/gdbusauth.c
+++ b/gio/gdbusauth.c
@@ -1007,6 +1007,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
g_propagate_error (error, local_error);
goto out;
}
+ g_clear_error (&local_error);
}
else
{

View File

@ -0,0 +1,54 @@
From a497fdf302bf67e4df2e1474389c0ff2152f1e99 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 24 Sep 2021 08:58:42 +0100
Subject: [PATCH] gdbusconnection: Add some ownership annotations
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a497fdf302bf67e4df2e1474389c0ff2152f1e99
---
gio/gdbusconnection.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 24a50fcf20..40ce1b6fc7 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -4086,11 +4086,11 @@ typedef struct
ExportedObject *eo;
guint id;
- gchar *interface_name;
- GDBusInterfaceVTable *vtable;
- GDBusInterfaceInfo *interface_info;
+ gchar *interface_name; /* (owned) */
+ GDBusInterfaceVTable *vtable; /* (owned) */
+ GDBusInterfaceInfo *interface_info; /* (owned) */
- GMainContext *context;
+ GMainContext *context; /* (owned) */
gpointer user_data;
GDestroyNotify user_data_free_func;
} ExportedInterface;
@@ -4116,12 +4116,12 @@ exported_interface_free (ExportedInterface *ei)
struct ExportedSubtree
{
guint id;
- gchar *object_path;
- GDBusConnection *connection;
- GDBusSubtreeVTable *vtable;
+ gchar *object_path; /* (owned) */
+ GDBusConnection *connection; /* (unowned) */
+ GDBusSubtreeVTable *vtable; /* (owned) */
GDBusSubtreeFlags flags;
- GMainContext *context;
+ GMainContext *context; /* (owned) */
gpointer user_data;
GDestroyNotify user_data_free_func;
};
--
GitLab

View File

@ -0,0 +1,194 @@
From 50fbf05d61db500df9052bb682d9c01e0bf51ffb Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 24 Sep 2021 10:52:41 +0100
Subject: [PATCH] gdbusconnection: Fix race between method calls and object
unregistration
If `g_dbus_connection_unregister_object()` (or `unregister_subtree()`)
was called from one thread, while an idle callback for a method call (or
a property get or set) was being invoked in another, it was possible for
the two to race after the idle callback had checked that the
object/subtree was registered, but before it had finished dereferencing
all the data related to that object/subtree.
Unregistering the object/subtree would immediately free the data,
leading the idle callback to cause a use-after-free error.
Fix that by giving the idle callback a strong reference to the data from
inside the locked section where it checks whether the object/subtree is
still registered.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2400
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/50fbf05d61db500df9052bb682d9c01e0bf51ffb
---
gio/gdbusconnection.c | 66 +++++++++++++++++++++++++++++++++++--------
1 file changed, 54 insertions(+), 12 deletions(-)
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 71913c1ec1..e6c0b70b4e 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -4116,6 +4116,9 @@ exported_interface_unref (ExportedInterface *ei)
g_dbus_interface_info_cache_release (ei->interface_info);
g_dbus_interface_info_unref ((GDBusInterfaceInfo *) ei->interface_info);
+ /* All uses of ei->vtable from callbacks scheduled in idle functions must
+ * have completed by this call_destroy_notify() call, as language bindings
+ * may destroy function closures in this callback. */
call_destroy_notify (ei->context,
ei->user_data_free_func,
ei->user_data);
@@ -4157,6 +4160,9 @@ exported_subtree_unref (ExportedSubtree *es)
if (!g_atomic_int_dec_and_test (&es->refcount))
return;
+ /* All uses of es->vtable from callbacks scheduled in idle functions must
+ * have completed by this call_destroy_notify() call, as language bindings
+ * may destroy function closures in this callback. */
call_destroy_notify (es->context,
es->user_data_free_func,
es->user_data);
@@ -4174,30 +4180,45 @@ exported_subtree_unref (ExportedSubtree *es)
* @subtree_registration_id (if not zero) has been unregistered. If
* so, returns %TRUE.
*
+ * If not, sets @out_ei and/or @out_es to a strong reference to the relevant
+ * #ExportedInterface/#ExportedSubtree and returns %FALSE.
+ *
* May be called by any thread. Caller must *not* hold lock.
*/
static gboolean
-has_object_been_unregistered (GDBusConnection *connection,
- guint registration_id,
- guint subtree_registration_id)
+has_object_been_unregistered (GDBusConnection *connection,
+ guint registration_id,
+ ExportedInterface **out_ei,
+ guint subtree_registration_id,
+ ExportedSubtree **out_es)
{
gboolean ret;
+ ExportedInterface *ei = NULL;
+ gpointer es = NULL;
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
ret = FALSE;
CONNECTION_LOCK (connection);
- if (registration_id != 0 && g_hash_table_lookup (connection->map_id_to_ei,
- GUINT_TO_POINTER (registration_id)) == NULL)
+
+ if (registration_id != 0)
{
- ret = TRUE;
+ ei = g_hash_table_lookup (connection->map_id_to_ei, GUINT_TO_POINTER (registration_id));
+ if (ei == NULL)
+ ret = TRUE;
+ else if (out_ei != NULL)
+ *out_ei = exported_interface_ref (ei);
}
- else if (subtree_registration_id != 0 && g_hash_table_lookup (connection->map_id_to_es,
- GUINT_TO_POINTER (subtree_registration_id)) == NULL)
+ if (subtree_registration_id != 0)
{
- ret = TRUE;
+ es = g_hash_table_lookup (connection->map_id_to_es, GUINT_TO_POINTER (subtree_registration_id));
+ if (es == NULL)
+ ret = TRUE;
+ else if (out_es != NULL)
+ *out_es = exported_subtree_ref (es);
}
+
CONNECTION_UNLOCK (connection);
return ret;
@@ -4234,10 +4255,14 @@ invoke_get_property_in_idle_cb (gpointer _data)
GVariant *value;
GError *error;
GDBusMessage *reply;
+ ExportedInterface *ei = NULL;
+ ExportedSubtree *es = NULL;
if (has_object_been_unregistered (data->connection,
data->registration_id,
- data->subtree_registration_id))
+ &ei,
+ data->subtree_registration_id,
+ &es))
{
reply = g_dbus_message_new_method_error (data->message,
"org.freedesktop.DBus.Error.UnknownMethod",
@@ -4284,6 +4309,9 @@ invoke_get_property_in_idle_cb (gpointer _data)
}
out:
+ g_clear_pointer (&ei, exported_interface_unref);
+ g_clear_pointer (&es, exported_subtree_unref);
+
return FALSE;
}
@@ -4581,10 +4609,14 @@ invoke_get_all_properties_in_idle_cb (gpointer _data)
GVariantBuilder builder;
GDBusMessage *reply;
guint n;
+ ExportedInterface *ei = NULL;
+ ExportedSubtree *es = NULL;
if (has_object_been_unregistered (data->connection,
data->registration_id,
- data->subtree_registration_id))
+ &ei,
+ data->subtree_registration_id,
+ &es))
{
reply = g_dbus_message_new_method_error (data->message,
"org.freedesktop.DBus.Error.UnknownMethod",
@@ -4637,6 +4669,9 @@ invoke_get_all_properties_in_idle_cb (gpointer _data)
g_object_unref (reply);
out:
+ g_clear_pointer (&ei, exported_interface_unref);
+ g_clear_pointer (&es, exported_subtree_unref);
+
return FALSE;
}
@@ -4946,13 +4981,17 @@ call_in_idle_cb (gpointer user_data)
GDBusInterfaceVTable *vtable;
guint registration_id;
guint subtree_registration_id;
+ ExportedInterface *ei = NULL;
+ ExportedSubtree *es = NULL;
registration_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (invocation), "g-dbus-registration-id"));
subtree_registration_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (invocation), "g-dbus-subtree-registration-id"));
if (has_object_been_unregistered (g_dbus_method_invocation_get_connection (invocation),
registration_id,
- subtree_registration_id))
+ &ei,
+ subtree_registration_id,
+ &es))
{
GDBusMessage *reply;
reply = g_dbus_message_new_method_error (g_dbus_method_invocation_get_message (invocation),
@@ -4978,6 +5017,9 @@ call_in_idle_cb (gpointer user_data)
g_dbus_method_invocation_get_user_data (invocation));
out:
+ g_clear_pointer (&ei, exported_interface_unref);
+ g_clear_pointer (&es, exported_subtree_unref);
+
return FALSE;
}
--
GitLab

View File

@ -0,0 +1,62 @@
From 117b748e44e0ec930fcb9641e3f808572d4a41f2 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 24 Sep 2021 10:55:10 +0100
Subject: [PATCH] gdbusconnection: Fix race between subtree method call and
unregistration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix another variant of the previous commit, this time specific to the
idle callback of a method call on a subtree object, racing with
unregistration of that subtree.
In this case, the `process_subtree_vtable_message_in_idle_cb()` idle
callback already has a pointer to the right `ExportedSubtree` struct,
but again doesn鈥檛 have a strong reference to it.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2400
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/117b748e44e0ec930fcb9641e3f808572d4a41f2
---
gio/gdbusconnection.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index e6c0b70b4e..73b5b309a2 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -6824,14 +6824,15 @@ handle_subtree_method_invocation (GDBusConnection *connection,
typedef struct
{
- GDBusMessage *message;
- ExportedSubtree *es;
+ GDBusMessage *message; /* (owned) */
+ ExportedSubtree *es; /* (owned) */
} SubtreeDeferredData;
static void
subtree_deferred_data_free (SubtreeDeferredData *data)
{
g_object_unref (data->message);
+ exported_subtree_unref (data->es);
g_free (data);
}
@@ -6890,7 +6891,7 @@ subtree_message_func (GDBusConnection *connection,
data = g_new0 (SubtreeDeferredData, 1);
data->message = g_object_ref (message);
- data->es = es;
+ data->es = exported_subtree_ref (es);
/* defer this call to an idle handler in the right thread */
idle_source = g_idle_source_new ();
--
GitLab

View File

@ -0,0 +1,136 @@
From c8c2ed4af5cdf8d77af2cd9a2a4b4f6ac8d1fc70 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 24 Sep 2021 09:03:40 +0100
Subject: [PATCH] gdbusconnection: Make ExportedInterface/ExportedSubtree
refcounted
This is needed for an upcoming change which decouples their lifecycle
from their presence in the `map_id_to_ei` and `map_id_to_es` hash
tables.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2400
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/c8c2ed4af5cdf8d77af2cd9a2a4b4f6ac8d1fc70
---
gio/gdbusconnection.c | 42 ++++++++++++++++++++++++++++++++++++------
1 file changed, 36 insertions(+), 6 deletions(-)
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 40ce1b6fc7..71913c1ec1 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -466,7 +466,8 @@ typedef struct ExportedObject ExportedObject;
static void exported_object_free (ExportedObject *eo);
typedef struct ExportedSubtree ExportedSubtree;
-static void exported_subtree_free (ExportedSubtree *es);
+static ExportedSubtree *exported_subtree_ref (ExportedSubtree *es);
+static void exported_subtree_unref (ExportedSubtree *es);
enum
{
@@ -1096,7 +1097,7 @@ g_dbus_connection_init (GDBusConnection *connection)
connection->map_object_path_to_es = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL,
- (GDestroyNotify) exported_subtree_free);
+ (GDestroyNotify) exported_subtree_unref);
connection->map_id_to_es = g_hash_table_new (g_direct_hash,
g_direct_equal);
@@ -4085,6 +4086,8 @@ typedef struct
{
ExportedObject *eo;
+ gint refcount; /* (atomic) */
+
guint id;
gchar *interface_name; /* (owned) */
GDBusInterfaceVTable *vtable; /* (owned) */
@@ -4095,10 +4098,21 @@ typedef struct
GDestroyNotify user_data_free_func;
} ExportedInterface;
-/* called with lock held */
+static ExportedInterface *
+exported_interface_ref (ExportedInterface *ei)
+{
+ g_atomic_int_inc (&ei->refcount);
+
+ return ei;
+}
+
+/* May be called with lock held */
static void
-exported_interface_free (ExportedInterface *ei)
+exported_interface_unref (ExportedInterface *ei)
{
+ if (!g_atomic_int_dec_and_test (&ei->refcount))
+ return;
+
g_dbus_interface_info_cache_release (ei->interface_info);
g_dbus_interface_info_unref ((GDBusInterfaceInfo *) ei->interface_info);
@@ -4115,6 +4129,8 @@ exported_interface_free (ExportedInterface *ei)
struct ExportedSubtree
{
+ gint refcount; /* (atomic) */
+
guint id;
gchar *object_path; /* (owned) */
GDBusConnection *connection; /* (unowned) */
@@ -4126,9 +4142,21 @@ struct ExportedSubtree
GDestroyNotify user_data_free_func;
};
+static ExportedSubtree *
+exported_subtree_ref (ExportedSubtree *es)
+{
+ g_atomic_int_inc (&es->refcount);
+
+ return es;
+}
+
+/* May be called with lock held */
static void
-exported_subtree_free (ExportedSubtree *es)
+exported_subtree_unref (ExportedSubtree *es)
{
+ if (!g_atomic_int_dec_and_test (&es->refcount))
+ return;
+
call_destroy_notify (es->context,
es->user_data_free_func,
es->user_data);
@@ -5251,7 +5279,7 @@ g_dbus_connection_register_object (GDBusConnection *connection,
eo->map_if_name_to_ei = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL,
- (GDestroyNotify) exported_interface_free);
+ (GDestroyNotify) exported_interface_unref);
g_hash_table_insert (connection->map_object_path_to_eo, eo->object_path, eo);
}
@@ -5268,6 +5296,7 @@ g_dbus_connection_register_object (GDBusConnection *connection,
}
ei = g_new0 (ExportedInterface, 1);
+ ei->refcount = 1;
ei->id = (guint) g_atomic_int_add (&_global_registration_id, 1); /* TODO: overflow etc. */
ei->eo = eo;
ei->user_data = user_data;
@@ -6924,6 +6953,7 @@ g_dbus_connection_register_subtree (GDBusConnection *connection,
}
es = g_new0 (ExportedSubtree, 1);
+ es->refcount = 1;
es->object_path = g_strdup (object_path);
es->connection = connection;
--
GitLab

View File

@ -0,0 +1,94 @@
From 310f2c1632e05c4f32be033c009642012741d876 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 24 Sep 2021 08:28:19 +0100
Subject: [PATCH] gdbusconnection: Move ExportedSubtree definition
Move it further up the file, but make no changes to it. This will help
with a subsequent commit.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2400
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/310f2c1632e05c4f32be033c009642012741d876
---
gio/gdbusconnection.c | 54 +++++++++++++++++++++----------------------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index d730111f8b..24a50fcf20 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -4113,6 +4113,33 @@ exported_interface_free (ExportedInterface *ei)
g_free (ei);
}
+struct ExportedSubtree
+{
+ guint id;
+ gchar *object_path;
+ GDBusConnection *connection;
+ GDBusSubtreeVTable *vtable;
+ GDBusSubtreeFlags flags;
+
+ GMainContext *context;
+ gpointer user_data;
+ GDestroyNotify user_data_free_func;
+};
+
+static void
+exported_subtree_free (ExportedSubtree *es)
+{
+ call_destroy_notify (es->context,
+ es->user_data_free_func,
+ es->user_data);
+
+ g_main_context_unref (es->context);
+
+ _g_dbus_subtree_vtable_free (es->vtable);
+ g_free (es->object_path);
+ g_free (es);
+}
+
/* ---------------------------------------------------------------------------------------------------- */
/* Convenience function to check if @registration_id (if not zero) or
@@ -6401,33 +6428,6 @@ g_dbus_connection_call_with_unix_fd_list_sync (GDBusConnection *connection,
/* ---------------------------------------------------------------------------------------------------- */
-struct ExportedSubtree
-{
- guint id;
- gchar *object_path;
- GDBusConnection *connection;
- GDBusSubtreeVTable *vtable;
- GDBusSubtreeFlags flags;
-
- GMainContext *context;
- gpointer user_data;
- GDestroyNotify user_data_free_func;
-};
-
-static void
-exported_subtree_free (ExportedSubtree *es)
-{
- call_destroy_notify (es->context,
- es->user_data_free_func,
- es->user_data);
-
- g_main_context_unref (es->context);
-
- _g_dbus_subtree_vtable_free (es->vtable);
- g_free (es->object_path);
- g_free (es);
-}
-
/* called without lock held in the thread where the caller registered
* the subtree
*/
--
GitLab

View File

@ -0,0 +1,182 @@
From 1f86923766a3d1d319fe54ad24fcf6e2d75aca0d Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Wed, 22 Feb 2023 12:40:49 +0000
Subject: [PATCH 1/3] gdbusinterfaceskeleton: Remove an unnecessary helper
struct member
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The `GDBusInterfaceSkeleton` is already stored as the source object of
the `GTask` here, with a strong reference.
Storing it again in the tasks data struct is redundant, and makes it
look like the `GDBusInterfaceSkeleton` is being used without holding a
strong reference. (Theres not actually a bug there though: the strong
reference from the `GTask` outlives the data struct, so is sufficient.)
Remove the unnecessary helper struct member to clarify the code a bit.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2924
---
gio/gdbusinterfaceskeleton.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c
index 3f07d4d0b2..d28282fea3 100644
--- a/gio/gdbusinterfaceskeleton.c
+++ b/gio/gdbusinterfaceskeleton.c
@@ -461,7 +461,6 @@ dbus_interface_interface_init (GDBusInterfaceIface *iface)
typedef struct
{
gint ref_count; /* (atomic) */
- GDBusInterfaceSkeleton *interface;
GDBusInterfaceMethodCallFunc method_call_func;
GDBusMethodInvocation *invocation;
} DispatchData;
@@ -502,16 +501,17 @@ dispatch_in_thread_func (GTask *task,
GCancellable *cancellable)
{
DispatchData *data = task_data;
+ GDBusInterfaceSkeleton *interface = g_task_get_source_object (task);
GDBusInterfaceSkeletonFlags flags;
GDBusObject *object;
gboolean authorized;
- g_mutex_lock (&data->interface->priv->lock);
- flags = data->interface->priv->flags;
- object = data->interface->priv->object;
+ g_mutex_lock (&interface->priv->lock);
+ flags = interface->priv->flags;
+ object = interface->priv->object;
if (object != NULL)
g_object_ref (object);
- g_mutex_unlock (&data->interface->priv->lock);
+ g_mutex_unlock (&interface->priv->lock);
/* first check on the enclosing object (if any), then the interface */
authorized = TRUE;
@@ -519,13 +519,13 @@ dispatch_in_thread_func (GTask *task,
{
g_signal_emit_by_name (object,
"authorize-method",
- data->interface,
+ interface,
data->invocation,
&authorized);
}
if (authorized)
{
- g_signal_emit (data->interface,
+ g_signal_emit (interface,
signals[G_AUTHORIZE_METHOD_SIGNAL],
0,
data->invocation,
@@ -627,7 +627,6 @@ g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface
DispatchData *data;
data = g_slice_new0 (DispatchData);
- data->interface = interface;
data->method_call_func = method_call_func;
data->invocation = invocation;
data->ref_count = 1;
--
GitLab
From d5710deb9d621bcf0cec0ff2db0708f361490752 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Wed, 22 Feb 2023 12:47:36 +0000
Subject: [PATCH 2/3] gdbusinterfaceskeleton: Fix a use-after-free of a
GDBusMethodInvocation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This `GDBusMethodInvocation` may be shared across threads, with no
guarantee on the strong ref in one thread outlasting any refs in other
threads — so it needs a ref in this helper struct.
This should fix a use-after-free where the `GDBusMethodInvocation` is
freed from `g_value_unset()` after `g_signal_emit()` returns in
`dispatch_in_thread_func()` in one thread; but then dereferenced again
in `g_source_destroy_internal()` from another thread.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2924
---
gio/gdbusinterfaceskeleton.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c
index d28282fea3..a2a79fe3d8 100644
--- a/gio/gdbusinterfaceskeleton.c
+++ b/gio/gdbusinterfaceskeleton.c
@@ -462,14 +462,17 @@ typedef struct
{
gint ref_count; /* (atomic) */
GDBusInterfaceMethodCallFunc method_call_func;
- GDBusMethodInvocation *invocation;
+ GDBusMethodInvocation *invocation; /* (owned) */
} DispatchData;
static void
dispatch_data_unref (DispatchData *data)
{
if (g_atomic_int_dec_and_test (&data->ref_count))
- g_slice_free (DispatchData, data);
+ {
+ g_clear_object (&data->invocation);
+ g_slice_free (DispatchData, data);
+ }
}
static DispatchData *
@@ -628,7 +631,7 @@ g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface
data = g_slice_new0 (DispatchData);
data->method_call_func = method_call_func;
- data->invocation = invocation;
+ data->invocation = g_object_ref (invocation);
data->ref_count = 1;
task = g_task_new (interface, NULL, NULL, NULL);
--
GitLab
From 7b101588e924f3783a0f5075f06b3e1d698be936 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Wed, 22 Feb 2023 12:50:10 +0000
Subject: [PATCH 3/3] gdbusconnection: Make GDBusMethodInvocation transfer a
bit clearer
Add a missing steal call in `schedule_method_call()`. This introduces no
functional changes, but documents the ownership transfer more clearly.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2924
---
gio/gdbusconnection.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index d938f71b99..da6b66f2ec 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -5043,7 +5043,7 @@ schedule_method_call (GDBusConnection *connection,
g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
g_source_set_callback (idle_source,
call_in_idle_cb,
- invocation,
+ g_steal_pointer (&invocation),
g_object_unref);
g_source_set_name (idle_source, "[gio, " __FILE__ "] call_in_idle_cb");
g_source_attach (idle_source, main_context);
--
GitLab

View File

@ -0,0 +1,53 @@
From c74177337dae7b06383261b2bedabf1f12d816b5 Mon Sep 17 00:00:00 2001
From: Sebastian Wilhelmi <wilhelmi@google.com>
Date: Thu, 6 Jan 2022 20:57:49 +0000
Subject: [PATCH] gdbusmessage: Disallow zero-length elements in arrays
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
They are not allowed in the specification, and can lead to infinite
loops when parsing.
That鈥檚 a security issue if your application is accepting D-Bus messages
from untrusted peers (perhaps in a peer-to-peer connection). It鈥檚 not
exploitable when your application is connected to a bus (such as the
system or session buses), as the bus daemons (dbus-daemon or
dbus-broker) filter out such broken messages and don鈥檛 forward them.
Arrays of zero-length elements are disallowed in the D-Bus
specification: https://dbus.freedesktop.org/doc/dbus-specification.html#container-types
oss-fuzz#41428, #41435
Fixes: #2557
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/c74177337dae7b06383261b2bedabf1f12d816b5
---
gio/gdbusmessage.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index 4056bc2c4a..ecef6cd3c5 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -1839,6 +1839,16 @@ parse_value_from_blob (GMemoryBuffer *buf,
}
g_variant_builder_add_value (&builder, item);
g_variant_unref (item);
+
+ /* Array elements must not be zero-length. There are no
+ * valid zero-length serialisations of any types which
+ * can be array elements in the D-Bus wire format, so this
+ * assertion should always hold.
+ *
+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2557
+ */
+ g_assert (buf->pos > (gsize) offset);
+
offset = buf->pos;
}
}
--
GitLab

View File

@ -0,0 +1,30 @@
From 7143457076d6469f76185a2f1d7071aca40a591e Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 17 Mar 2022 19:03:15 +0000
Subject: [PATCH] gdbusmethodinvocation: Drop redundant quote from warning
message
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/7143457076d6469f76185a2f1d7071aca40a591e
---
gio/gdbusmethodinvocation.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c
index 8e7abc83c4..705af079f4 100644
--- a/gio/gdbusmethodinvocation.c
+++ b/gio/gdbusmethodinvocation.c
@@ -413,7 +413,7 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio
{
gchar *type_string = g_variant_type_dup_string (type);
- g_warning ("Type of return value is incorrect: expected '%s', got '%s''",
+ g_warning ("Type of return value is incorrect: expected '%s', got '%s'",
type_string, g_variant_get_type_string (parameters));
g_variant_type_free (type);
g_free (type_string);
--
GitLab

View File

@ -0,0 +1,66 @@
From a3b8846e54c7132056411605f815b67e831833d2 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 17 Mar 2022 19:04:42 +0000
Subject: [PATCH] gdbusmethodinvocation: Fix a leak on an early return path
When doing an early return from `g_dbus_method_invocation_return_*()`
due to passing in the wrong type (or no return value when one was
expected), the parameters were not correctly sunk and were leaked.
Fix that. A unit test will be added in a following commit.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1474536
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a3b8846e54c7132056411605f815b67e831833d2
---
gio/gdbusmethodinvocation.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c
index c22e19ef0d..c15d83ec84 100644
--- a/gio/gdbusmethodinvocation.c
+++ b/gio/gdbusmethodinvocation.c
@@ -397,14 +397,7 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio
g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
if (g_dbus_message_get_flags (invocation->message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED)
- {
- if (parameters != NULL)
- {
- g_variant_ref_sink (parameters);
- g_variant_unref (parameters);
- }
- goto out;
- }
+ goto out;
if (parameters == NULL)
parameters = g_variant_new_tuple (NULL, 0);
@@ -508,7 +501,7 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio
}
reply = g_dbus_message_new_method_reply (invocation->message);
- g_dbus_message_set_body (reply, parameters);
+ g_dbus_message_set_body (reply, g_steal_pointer (&parameters));
#ifdef G_OS_UNIX
if (fd_list != NULL)
@@ -525,6 +518,12 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio
g_object_unref (reply);
out:
+ if (parameters != NULL)
+ {
+ g_variant_ref_sink (parameters);
+ g_variant_unref (parameters);
+ }
+
g_object_unref (invocation);
}
--
GitLab

View File

@ -0,0 +1,81 @@
From 76f5460107c86a44be6387c159b34ae50aa1e623 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 17 Mar 2022 18:32:46 +0000
Subject: [PATCH] gdbusmethodinvocation: Fix dead code for type checking GetAll
`property_info` is only ever set for `Get` and `Set` calls, not for
`GetAll`, as it only represents a single property. So this code was
never reachable.
Move it out so that it is reachable.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/76f5460107c86a44be6387c159b34ae50aa1e623
---
gio/gdbusmethodinvocation.c | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c
index c15d83ec84..8e7abc83c4 100644
--- a/gio/gdbusmethodinvocation.c
+++ b/gio/gdbusmethodinvocation.c
@@ -424,7 +424,9 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio
/* property_info is only non-NULL if set that way from
* GDBusConnection, so this must be the case of async property
- * handling on either 'Get', 'Set' or 'GetAll'.
+ * handling on either 'Get' or 'Set'.
+ *
+ * property_info is NULL for 'GetAll'.
*/
if (invocation->property_info != NULL)
{
@@ -454,21 +456,6 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio
g_variant_unref (nested);
}
- else if (g_str_equal (invocation->method_name, "GetAll"))
- {
- if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})")))
- {
- g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'",
- g_variant_get_type_string (parameters));
- goto out;
- }
-
- /* Could iterate the list of properties and make sure that all
- * of them are actually on the interface and with the correct
- * types, but let's not do that for now...
- */
- }
-
else if (g_str_equal (invocation->method_name, "Set"))
{
if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT))
@@ -482,6 +469,21 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio
else
g_assert_not_reached ();
}
+ else if (g_str_equal (invocation->interface_name, "org.freedesktop.DBus.Properties") &&
+ g_str_equal (invocation->method_name, "GetAll"))
+ {
+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})")))
+ {
+ g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'",
+ g_variant_get_type_string (parameters));
+ goto out;
+ }
+
+ /* Could iterate the list of properties and make sure that all
+ * of them are actually on the interface and with the correct
+ * types, but let's not do that for now...
+ */
+ }
if (G_UNLIKELY (_g_dbus_debug_return ()))
{
--
GitLab

View File

@ -0,0 +1,43 @@
From 719484a5754cca036d123ae4c2ae3d150bacef32 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Wed, 31 Mar 2021 14:23:13 -0500
Subject: [PATCH] gdbusobjectmanagerservice: fix leak in error path
If the third g_return_val_if_fail() is hit, then we leak
orig_object_path. There is no reason we need to strdup it here.
Found by Coverity.
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/719484a5754cca036d123ae4c2ae3d150bacef32
---
gio/gdbusobjectmanagerserver.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/gio/gdbusobjectmanagerserver.c b/gio/gdbusobjectmanagerserver.c
index 39f4ed5006..0a0cea84ab 100644
--- a/gio/gdbusobjectmanagerserver.c
+++ b/gio/gdbusobjectmanagerserver.c
@@ -565,12 +565,12 @@ void
g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
GDBusObjectSkeleton *object)
{
- gchar *orig_object_path;
+ const gchar *orig_object_path;
gchar *object_path;
guint count;
gboolean modified;
- orig_object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ orig_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
g_return_if_fail (G_IS_DBUS_OBJECT (object));
@@ -602,7 +602,6 @@ g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path);
g_free (object_path);
- g_free (orig_object_path);
}

View File

@ -0,0 +1,48 @@
From 221f22b6e18fdd306e676e28a79afd3697bddd03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 2 Sep 2022 20:38:46 +0200
Subject: [PATCH] gdesktopappinfo: Unref the GDBus call results
On our GDBus call callback wrapper we were completing the gdbus call but
ignoring the returned value, that was always leaked.
Fix this.
Helps with: https://gitlab.gnome.org/GNOME/glib/-/issues/333
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/221f22b6e18fdd306e676e28a79afd3697bddd03
---
gio/gdesktopappinfo.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index af2311ca52..52d308f540 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -3283,15 +3283,19 @@ launch_uris_with_dbus_cb (GObject *object,
{
GTask *task = G_TASK (user_data);
GError *error = NULL;
+ GVariant *ret;
- g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
+ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
if (error != NULL)
{
g_dbus_error_strip_remote_error (error);
g_task_return_error (task, g_steal_pointer (&error));
}
else
- g_task_return_boolean (task, TRUE);
+ {
+ g_task_return_boolean (task, TRUE);
+ g_variant_unref (ret);
+ }
g_object_unref (task);
}
--
GitLab

View File

@ -0,0 +1,32 @@
From be57c5d14c771361482917f4cb35851a07d19a8e Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 29 Apr 2021 13:17:05 +0100
Subject: [PATCH] gdtlsconnection: Fix a check for a vfunc being implemented
It was checking the wrong vfunc; likely a copy/paste error.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/be57c5d14c771361482917f4cb35851a07d19a8e
---
gio/gdtlsconnection.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gio/gdtlsconnection.c b/gio/gdtlsconnection.c
index 4bbc88d7a7..136e317b13 100644
--- a/gio/gdtlsconnection.c
+++ b/gio/gdtlsconnection.c
@@ -1069,7 +1069,7 @@ g_dtls_connection_get_negotiated_protocol (GDtlsConnection *conn)
GDtlsConnectionInterface *iface;
iface = G_DTLS_CONNECTION_GET_INTERFACE (conn);
- if (iface->set_advertised_protocols == NULL)
+ if (iface->get_negotiated_protocol == NULL)
return NULL;
return iface->get_negotiated_protocol (conn);
--
GitLab

View File

@ -0,0 +1,29 @@
From 8bfc2998135ee9c4460520febb3af720c61438a5 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Thu, 1 Apr 2021 14:13:19 -0500
Subject: [PATCH] gfileenumerator: fix leak in error path
Found by Coverity.
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/8bfc2998135ee9c4460520febb3af720c61438a5
---
gio/gfileenumerator.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/gio/gfileenumerator.c b/gio/gfileenumerator.c
index ac2e4eb980..1f9bc24ebe 100644
--- a/gio/gfileenumerator.c
+++ b/gio/gfileenumerator.c
@@ -787,7 +787,10 @@ next_files_thread (GTask *task,
}
if (error)
- g_task_return_error (task, error);
+ {
+ g_list_free_full (files, g_object_unref);
+ g_task_return_error (task, error);
+ }
else
g_task_return_pointer (task, files, (GDestroyNotify)next_async_op_free);
}

View File

@ -0,0 +1,29 @@
From e268ff39b648e7b100d2aa50f472b4ff8ff5313a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 2 Sep 2022 21:10:05 +0200
Subject: [PATCH] gio/tests/gdbus-peer: Unref cached property GVariant value
Helps with: https://gitlab.gnome.org/GNOME/glib/-/issues/333
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/e268ff39b648e7b100d2aa50f472b4ff8ff5313a
---
gio/tests/gdbus-peer.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index 7179d089df..763689a4fd 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -843,6 +843,7 @@ do_test_peer (void)
error = NULL;
value = g_dbus_proxy_get_cached_property (proxy, "PeerProperty");
g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "ThePropertyValue");
+ g_clear_pointer (&value, g_variant_unref);
/* try invoking a method */
error = NULL;
--
GitLab

View File

@ -0,0 +1,67 @@
From 1da208cddc19cad05ccf4b798a99f7045e41ffc4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 2 Sep 2022 20:26:06 +0200
Subject: [PATCH] gio/tests/gdbus-proxy-threads: Unref GVariant's that we own
This test is leaking various GVariant's that we are supposed to unref,
leading the valgrind CI job to complain about.
Helps with: https://gitlab.gnome.org/GNOME/glib/-/issues/333
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/1da208cddc19cad05ccf4b798a99f7045e41ffc4
---
gio/tests/gdbus-proxy-threads.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/gio/tests/gdbus-proxy-threads.c b/gio/tests/gdbus-proxy-threads.c
index 76b857e731..a0a38d07cd 100644
--- a/gio/tests/gdbus-proxy-threads.c
+++ b/gio/tests/gdbus-proxy-threads.c
@@ -119,13 +119,17 @@ request_name_cb (GObject *source,
GDBusConnection *connection = G_DBUS_CONNECTION (source);
GError *error = NULL;
GVariant *var;
+ GVariant *child;
var = g_dbus_connection_call_finish (connection, res, &error);
g_assert_no_error (error);
- g_assert_cmpuint (g_variant_get_uint32 (g_variant_get_child_value (var, 0)),
+ child = g_variant_get_child_value (var, 0);
+ g_assert_cmpuint (g_variant_get_uint32 (child),
==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
release_name (connection, TRUE);
+ g_variant_unref (child);
+ g_variant_unref (var);
}
static void
@@ -154,11 +158,13 @@ release_name_cb (GObject *source,
GDBusConnection *connection = G_DBUS_CONNECTION (source);
GError *error = NULL;
GVariant *var;
+ GVariant *child;
int i;
var = g_dbus_connection_call_finish (connection, res, &error);
g_assert_no_error (error);
- g_assert_cmpuint (g_variant_get_uint32 (g_variant_get_child_value (var, 0)),
+ child = g_variant_get_child_value (var, 0);
+ g_assert_cmpuint (g_variant_get_uint32 (child),
==, DBUS_RELEASE_NAME_REPLY_RELEASED);
/* generate some rapid NameOwnerChanged signals to try to trigger crashes */
@@ -170,6 +176,8 @@ release_name_cb (GObject *source,
/* wait for dbus-daemon to catch up */
request_name (connection, TRUE);
+ g_variant_unref (child);
+ g_variant_unref (var);
}
static void
--
GitLab

View File

@ -0,0 +1,72 @@
From 49cc9b96f4c19a98ddf6e9b7417c7019ebc28ca3 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Wed, 27 Apr 2022 15:01:08 +0100
Subject: [PATCH] gio-tool: Fix a minor memory leak when using gio-set with
bytestrings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Tested using:
```sh
touch ~/foo
gio set ~/foo -t bytestring user::test "\x00\x00"
```
(it doesn鈥檛 matter that this fails; the bytestring is still decoded)
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1474407
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/49cc9b96f4c19a98ddf6e9b7417c7019ebc28ca3
---
gio/gio-tool-set.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/gio/gio-tool-set.c b/gio/gio-tool-set.c
index 4dbe1214ff..c2a9431f61 100644
--- a/gio/gio-tool-set.c
+++ b/gio/gio-tool-set.c
@@ -76,12 +76,14 @@ handle_set (int argc, char *argv[], gboolean do_help)
const char *attribute;
GFileAttributeType type;
gpointer value;
+ gpointer value_allocated = NULL;
gboolean b;
guint32 uint32;
gint32 int32;
guint64 uint64;
gint64 int64;
gchar *param;
+ int retval = 0;
g_set_prgname ("gio set");
@@ -147,7 +149,7 @@ handle_set (int argc, char *argv[], gboolean do_help)
value = argv[3];
break;
case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
- value = hex_unescape (argv[3]);
+ value = value_allocated = hex_unescape (argv[3]);
break;
case G_FILE_ATTRIBUTE_TYPE_BOOLEAN:
b = g_ascii_strcasecmp (argv[3], "true") == 0;
@@ -194,11 +196,11 @@ handle_set (int argc, char *argv[], gboolean do_help)
{
print_error ("%s", error->message);
g_error_free (error);
- g_object_unref (file);
- return 1;
+ retval = 1;
}
+ g_clear_pointer (&value_allocated, g_free);
g_object_unref (file);
- return 0;
+ return retval;
}
--
GitLab

View File

@ -0,0 +1,28 @@
From 5a032f32ea77d81c012841dde88b070f55037f25 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
Date: Mon, 11 Oct 2021 13:56:43 +0300
Subject: [PATCH] glocalfileinfo: Fix atime/mtime mix due to bad copy/paste
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/5a032f32ea77d81c012841dde88b070f55037f25
---
gio/glocalfileinfo.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c
index 3867ca684a..d3b327a19c 100644
--- a/gio/glocalfileinfo.c
+++ b/gio/glocalfileinfo.c
@@ -2650,7 +2650,7 @@ set_mtime_atime (char *filename,
{
if (lazy_stat (filename, &statbuf, &got_stat) == 0)
{
- times[0].tv_sec = statbuf.st_mtime;
+ times[0].tv_sec = statbuf.st_atime;
#if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC)
times[0].tv_usec = statbuf.st_atimensec / 1000;
#elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
--
GitLab

View File

@ -0,0 +1,33 @@
From 2401e1a090dcaac7614a8984cd3e3832a2a476ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 16 Sep 2022 15:11:47 +0200
Subject: [PATCH] glocalfileoutputstream: Do not double-close an fd on unlink
error
In case we fail unlinking a file we could close again an FD that has
been already just closed. So avoid this by unsetting it when closing.
Coverity CID: #1474462
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/2401e1a090dcaac7614a8984cd3e3832a2a476ab
---
gio/glocalfileoutputstream.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
index 78d3e85..a61d5b5 100644
--- a/gio/glocalfileoutputstream.c
+++ b/gio/glocalfileoutputstream.c
@@ -1163,6 +1163,7 @@ handle_overwrite_open (const char *filename,
if (replace_destination_set)
{
g_close (fd, NULL);
+ fd = -1;
if (g_unlink (filename) != 0)
{
--
2.33.0

View File

@ -0,0 +1,32 @@
From d01fb412801ddc55843f1e1642d0fef0afba441a Mon Sep 17 00:00:00 2001
From: John Lindgren <john@jlindgren.net>
Date: Thu, 13 Oct 2022 14:00:12 +0100
Subject: [PATCH] gmessages: Add missing trailing newline in fallback log
handler
This makes the fallback log handler match the behaviour of the default
log handlers.
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d01fb412801ddc55843f1e1642d0fef0afba441a
Spotted as part of https://gitlab.gnome.org/GNOME/glib/-/issues/2753
---
glib/gmessages.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/glib/gmessages.c b/glib/gmessages.c
index fb1297f8a8..e197f1707a 100644
--- a/glib/gmessages.c
+++ b/glib/gmessages.c
@@ -3159,6 +3159,7 @@ _g_log_fallback_handler (const gchar *log_domain,
write_string (stream, level_prefix);
write_string (stream, ": ");
write_string (stream, message);
+ write_string (stream, "\n");
}
static void
--
GitLab

View File

@ -0,0 +1,29 @@
From 9dc7475f93c5c63fff66999d228407e13a47d5d3 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
Date: Mon, 11 Oct 2021 14:00:03 +0300
Subject: [PATCH] gopenuriportal: Fix GVariantBuilder and string leakage on
g_open failure
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/9dc7475f93c5c63fff66999d228407e13a47d5d3
---
gio/gopenuriportal.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c
index be68569ed8..6ef8f037c3 100644
--- a/gio/gopenuriportal.c
+++ b/gio/gopenuriportal.c
@@ -108,6 +108,8 @@ g_openuri_portal_open_uri (const char *uri,
errsv = errno;
if (fd == -1)
{
+ g_free (path);
+ g_variant_builder_clear (&opt_builder);
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
"Failed to open '%s'", path);
return FALSE;
--
GitLab

View File

@ -0,0 +1,39 @@
From 969eb835dc2f07c34ae8ca45ddbc41590a2e2f8e Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 28 Apr 2022 10:56:10 +0100
Subject: [PATCH] gopenuriportal: Fix a use-after-free on an error path
`path` was used in building the error message after it had been freed.
Spotted by scan-build.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1767
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/969eb835dc2f07c34ae8ca45ddbc41590a2e2f8e
---
gopenuriportal.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c
index ecf6fea..2f527d8 100644
--- a/gio/gopenuriportal.c
+++ b/gio/gopenuriportal.c
@@ -108,10 +108,10 @@ g_openuri_portal_open_uri (const char *uri,
errsv = errno;
if (fd == -1)
{
- g_free (path);
- g_variant_builder_clear (&opt_builder);
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
"Failed to open '%s'", path);
+ g_free (path);
+ g_variant_builder_clear (&opt_builder);
return FALSE;
}
--
2.33.0

View File

@ -0,0 +1,38 @@
From 7329c6e09bf59ccae2d8d3e788ce43bb6af6c3db Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Wed, 9 Mar 2022 14:07:34 +0000
Subject: [PATCH] gprintf: Fix a memory leak with an invalid format in
g_vasprintf()
If using the fallback implementation of `g_vasprintf()`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1474726
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/7329c6e09bf59ccae2d8d3e788ce43bb6af6c3db
---
glib/gprintf.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/glib/gprintf.c b/glib/gprintf.c
index 555a630bc2..0e094f00fa 100644
--- a/glib/gprintf.c
+++ b/glib/gprintf.c
@@ -356,6 +356,12 @@ g_vasprintf (gchar **string,
len = _g_vsprintf (*string, format, args2);
va_end (args2);
+
+ if (len < 0)
+ {
+ g_free (*string);
+ *string = NULL;
+ }
}
#endif
--
GitLab

View File

@ -0,0 +1,47 @@
From a50e605d52534f604776e56fd181ace98b6a0166 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
Date: Mon, 11 Oct 2021 14:02:33 +0300
Subject: [PATCH] gproxyaddressenumerator: Fix string leakage on an invalid
input
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a50e605d52534f604776e56fd181ace98b6a0166
---
gio/gproxyaddressenumerator.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/gio/gproxyaddressenumerator.c b/gio/gproxyaddressenumerator.c
index d3de4940c9..654baade57 100644
--- a/gio/gproxyaddressenumerator.c
+++ b/gio/gproxyaddressenumerator.c
@@ -262,8 +262,12 @@ g_proxy_address_enumerator_next (GSocketAddressEnumerator *enumerator,
}
dest_protocol = g_uri_parse_scheme (priv->dest_uri);
- g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address),
- NULL);
+ if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address))
+ {
+ g_free (dest_hostname);
+ g_free (dest_protocol);
+ }
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address), NULL);
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
inetaddr = g_inet_socket_address_get_address (inetsaddr);
@@ -352,6 +356,11 @@ return_result (GTask *task)
}
dest_protocol = g_uri_parse_scheme (priv->dest_uri);
+ if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address))
+ {
+ g_free (dest_hostname);
+ g_free (dest_protocol);
+ }
g_return_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address));
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
--
GitLab

View File

@ -0,0 +1,117 @@
From 56d371942e43c52bc6131067e2dc2a35f6cd5a3d Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Mon, 13 Jun 2022 13:06:06 +0100
Subject: [PATCH] gsocketclient: Fix still-reachable references to cancellables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`GSocketClient` chains its internal `GCancellable` objects to ones
provided by the caller in two places using `g_cancellable_connect()`.
However, it never calls `g_cancellable_disconnect()`, instead relying
(incorrectly) on the `GCancellable` provided by the caller being
short-lived.
In the (valid) situation where a caller reuses one `GCancellable` for
multiple socket client calls, or for calls across multiple socket
clients, this will cause the internal `GCancellable` objects from those
`GSocketClient`s to accumulate, with one reference left each (which is
the reference from the `g_cancellable_connect()` closure).
These `GCancellable` instances aren't technically leaked, as they will
all be freed when the caller's `GCancellable` is disposed, but they are
no longer useful and there is no bound on the number of them which will
hang around.
For a program doing a lot of socket operations, this still-reachable
memory usage can become significant.
Fix the problem by adding paired `g_cancellable_disconnect()` calls.
It's not possible to add a unit test as we can't measure still-reachable
memory growth before the end of a unit test when everything has to be
freed.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2670
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/56d371942e43c52bc6131067e2dc2a35f6cd5a3d
---
gio/gsocketclient.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index ae80f5203c..127915b722 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -1466,6 +1466,8 @@ typedef struct
GSocketConnectable *connectable;
GSocketAddressEnumerator *enumerator;
GCancellable *enumeration_cancellable;
+ GCancellable *enumeration_parent_cancellable; /* (nullable) (owned) */
+ gulong enumeration_cancelled_id;
GSList *connection_attempts;
GSList *successful_connections;
@@ -1485,7 +1487,12 @@ g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data)
data->task = NULL;
g_clear_object (&data->connectable);
g_clear_object (&data->enumerator);
+
+ g_cancellable_disconnect (data->enumeration_parent_cancellable, data->enumeration_cancelled_id);
+ g_clear_object (&data->enumeration_parent_cancellable);
+ data->enumeration_cancelled_id = 0;
g_clear_object (&data->enumeration_cancellable);
+
g_slist_free_full (data->connection_attempts, connection_attempt_unref);
g_slist_free_full (data->successful_connections, connection_attempt_unref);
@@ -1503,6 +1510,7 @@ typedef struct
GSocketClientAsyncConnectData *data; /* unowned */
GSource *timeout_source;
GCancellable *cancellable;
+ gulong cancelled_id;
grefcount ref;
} ConnectionAttempt;
@@ -1530,6 +1538,8 @@ connection_attempt_unref (gpointer pointer)
g_clear_object (&attempt->address);
g_clear_object (&attempt->socket);
g_clear_object (&attempt->connection);
+ g_cancellable_disconnect (g_task_get_cancellable (attempt->data->task), attempt->cancelled_id);
+ attempt->cancelled_id = 0;
g_clear_object (&attempt->cancellable);
g_clear_object (&attempt->proxy_addr);
if (attempt->timeout_source)
@@ -2023,8 +2033,9 @@ g_socket_client_enumerator_callback (GObject *object,
data->connection_attempts = g_slist_append (data->connection_attempts, attempt);
if (g_task_get_cancellable (data->task))
- g_cancellable_connect (g_task_get_cancellable (data->task), G_CALLBACK (on_connection_cancelled),
- g_object_ref (attempt->cancellable), g_object_unref);
+ attempt->cancelled_id =
+ g_cancellable_connect (g_task_get_cancellable (data->task), G_CALLBACK (on_connection_cancelled),
+ g_object_ref (attempt->cancellable), g_object_unref);
g_socket_connection_set_cached_remote_address ((GSocketConnection *)attempt->connection, address);
g_debug ("GSocketClient: Starting TCP connection attempt");
@@ -2129,8 +2140,12 @@ g_socket_client_connect_async (GSocketClient *client,
data->enumeration_cancellable = g_cancellable_new ();
if (cancellable)
- g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled),
- g_object_ref (data->enumeration_cancellable), g_object_unref);
+ {
+ data->enumeration_parent_cancellable = g_object_ref (cancellable);
+ data->enumeration_cancelled_id =
+ g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled),
+ g_object_ref (data->enumeration_cancellable), g_object_unref);
+ }
enumerator_next_async (data, FALSE);
}
--
GitLab

View File

@ -0,0 +1,73 @@
From b32727d43d9d11aa017f1f29648ad5019376537c Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
Date: Mon, 11 Oct 2021 14:07:01 +0300
Subject: [PATCH] gsocks5proxy: Fix buffer overflow on a really long domain
name
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/b32727d43d9d11aa017f1f29648ad5019376537c
---
gio/gsocks5proxy.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/gio/gsocks5proxy.c b/gio/gsocks5proxy.c
index 873db7ea6d..948ac8b8b8 100644
--- a/gio/gsocks5proxy.c
+++ b/gio/gsocks5proxy.c
@@ -328,7 +328,7 @@ set_connect_msg (guint8 *msg,
*
* The parser only requires 4 bytes.
*/
-#define SOCKS5_CONN_REP_LEN 255
+#define SOCKS5_CONN_REP_LEN 257
static gboolean
parse_connect_reply (const guint8 *data, gint *atype, GError **error)
{
@@ -509,7 +509,7 @@ g_socks5_proxy_connect (GProxy *proxy,
guint8 data[SOCKS5_CONN_REP_LEN];
gint atype;
- if (!g_input_stream_read_all (in, data, 4, NULL,
+ if (!g_input_stream_read_all (in, data, 4 /* VER, REP, RSV, ATYP */, NULL,
cancellable, error))
goto error;
@@ -519,23 +519,26 @@ g_socks5_proxy_connect (GProxy *proxy,
switch (atype)
{
case SOCKS5_ATYP_IPV4:
- if (!g_input_stream_read_all (in, data, 6, NULL,
- cancellable, error))
+ if (!g_input_stream_read_all (in, data,
+ 4 /* IPv4 length */ + 2 /* port */,
+ NULL, cancellable, error))
goto error;
break;
case SOCKS5_ATYP_IPV6:
- if (!g_input_stream_read_all (in, data, 18, NULL,
- cancellable, error))
+ if (!g_input_stream_read_all (in, data,
+ 16 /* IPv6 length */ + 2 /* port */,
+ NULL, cancellable, error))
goto error;
break;
case SOCKS5_ATYP_DOMAINNAME:
- if (!g_input_stream_read_all (in, data, 1, NULL,
- cancellable, error))
+ if (!g_input_stream_read_all (in, data, 1 /* domain name length */,
+ NULL, cancellable, error))
goto error;
- if (!g_input_stream_read_all (in, data, data[0] + 2, NULL,
- cancellable, error))
+ if (!g_input_stream_read_all (in, data,
+ data[0] /* domain name length */ + 2 /* port */,
+ NULL, cancellable, error))
goto error;
break;
}
--
GitLab

View File

@ -0,0 +1,110 @@
From 40a46d1346fdd4e07c648ba1ee78dedd9bfa33ad Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Tue, 6 Apr 2021 16:52:23 +0200
Subject: [PATCH] gsocks5proxy: Handle EOF when reading from a stream
The code did not handle EOF (0 byte read) correctly. This can e.g. cause
an infinite loop if an incorrect socks proxy is configured.
Add the appropriate checks and return an G_IO_ERROR_CONNECTION_CLOSED
error if EOF is encountered.
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/40a46d1346fdd4e07c648ba1ee78dedd9bfa33ad
---
gio/gsocks5proxy.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/gio/gsocks5proxy.c b/gio/gsocks5proxy.c
index 09b7fcac29..873db7ea6d 100644
--- a/gio/gsocks5proxy.c
+++ b/gio/gsocks5proxy.c
@@ -717,6 +717,16 @@ nego_reply_read_cb (GObject *source,
return;
}
+ if (read == 0)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_CONNECTION_CLOSED,
+ "Connection to SOCKSv5 proxy server lost");
+ g_object_unref (task);
+ return;
+ }
+
data->offset += read;
if (data->offset == data->length)
@@ -821,6 +831,16 @@ auth_reply_read_cb (GObject *source,
return;
}
+ if (read == 0)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_CONNECTION_CLOSED,
+ "Connection to SOCKSv5 proxy server lost");
+ g_object_unref (task);
+ return;
+ }
+
data->offset += read;
if (data->offset == data->length)
@@ -923,6 +943,16 @@ connect_reply_read_cb (GObject *source,
return;
}
+ if (read == 0)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_CONNECTION_CLOSED,
+ "Connection to SOCKSv5 proxy server lost");
+ g_object_unref (task);
+ return;
+ }
+
data->offset += read;
if (data->offset == data->length)
@@ -983,6 +1013,16 @@ connect_addr_len_read_cb (GObject *source,
return;
}
+ if (read == 0)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_CONNECTION_CLOSED,
+ "Connection to SOCKSv5 proxy server lost");
+ g_object_unref (task);
+ return;
+ }
+
data->length = data->buffer[0] + 2;
data->offset = 0;
@@ -1009,6 +1049,16 @@ connect_addr_read_cb (GObject *source,
return;
}
+ if (read == 0)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_CONNECTION_CLOSED,
+ "Connection to SOCKSv5 proxy server lost");
+ g_object_unref (task);
+ return;
+ }
+
data->offset += read;
if (data->offset == data->length)
--
GitLab

View File

@ -0,0 +1,192 @@
From d98a52254b4a681569a44f6be2aeceeaed58202c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Mon, 22 Nov 2021 16:55:35 +0100
Subject: [PATCH] gtestdbus: Print the dbus address on a specific FD intead of
stdout
We used to use a pipe for the dbus daemon stdout to read the defined
address, but that was already requiring a workaround to ensure that dbus
daemon children were then able to write to stdout.
However the current implementation is still causing troubles in some
cases in which the daemon is very verbose, leading to hangs when writing
to stdout.
As per this, just don't handle stdout ourself, but use instead a
specific pipe to get the address address. That can now be safely closed
once we've received the data we need.
This reverts commit d80adeaa960ddfa13837900d0391f9bd9c239f78.
Fixes: #2537
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d98a52254b4a681569a44f6be2aeceeaed58202c
---
gio/gtestdbus.c | 89 ++++++++++++++++++++++++++++++++-----------------
1 file changed, 59 insertions(+), 30 deletions(-)
diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c
index 703a0b3a5a..992d29cef0 100644
--- a/gio/gtestdbus.c
+++ b/gio/gtestdbus.c
@@ -32,6 +32,8 @@
#endif
#ifdef G_OS_WIN32
#include <io.h>
+#include <fcntl.h>
+#include <windows.h>
#endif
#include <glib.h>
@@ -44,8 +46,8 @@
#include "glibintl.h"
-#ifdef G_OS_WIN32
-#include <windows.h>
+#ifdef G_OS_UNIX
+#include "glib-unix.h"
#endif
/* -------------------------------------------------------------------------- */
@@ -436,7 +438,6 @@ struct _GTestDBusPrivate
GTestDBusFlags flags;
GPtrArray *service_dirs;
GPid bus_pid;
- gint bus_stdout_fd;
gchar *bus_address;
gboolean up;
};
@@ -596,58 +597,87 @@ write_config_file (GTestDBus *self)
return path;
}
+static gboolean
+make_pipe (gint pipe_fds[2],
+ GError **error)
+{
+#if defined(G_OS_UNIX)
+ return g_unix_open_pipe (pipe_fds, FD_CLOEXEC, error);
+#elif defined(G_OS_WIN32)
+ if (_pipe (pipe_fds, 4096, _O_BINARY) < 0)
+ {
+ int errsv = errno;
+
+ g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+ _("Failed to create pipe for communicating with child process (%s)"),
+ g_strerror (errsv));
+ return FALSE;
+ }
+ return TRUE;
+#else
+ g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+ _("Pipes are not supported in this platform"));
+ return FALSE;
+#endif
+}
+
static void
start_daemon (GTestDBus *self)
{
const gchar *argv[] = {"dbus-daemon", "--print-address", "--config-file=foo", NULL};
+ gint pipe_fds[2] = {-1, -1};
gchar *config_path;
gchar *config_arg;
+ gchar *print_address;
GIOChannel *channel;
- gint stdout_fd2;
gsize termpos;
GError *error = NULL;
if (g_getenv ("G_TEST_DBUS_DAEMON") != NULL)
argv[0] = (gchar *)g_getenv ("G_TEST_DBUS_DAEMON");
+ make_pipe (pipe_fds, &error);
+ g_assert_no_error (error);
+
+ print_address = g_strdup_printf ("--print-address=%d", pipe_fds[1]);
+ argv[1] = print_address;
+ g_assert_no_error (error);
+
/* Write config file and set its path in argv */
config_path = write_config_file (self);
config_arg = g_strdup_printf ("--config-file=%s", config_path);
argv[2] = config_arg;
/* Spawn dbus-daemon */
- g_spawn_async_with_pipes (NULL,
- (gchar **) argv,
- NULL,
- /* We Need this to get the pid returned on win32 */
- G_SPAWN_DO_NOT_REAP_CHILD |
- G_SPAWN_SEARCH_PATH |
- /* dbus-daemon will not abuse our descriptors, and
- * passing this means we can use posix_spawn() for speed */
- G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
- NULL,
- NULL,
- &self->priv->bus_pid,
- NULL,
- &self->priv->bus_stdout_fd,
- NULL,
- &error);
+ g_spawn_async_with_pipes_and_fds (NULL,
+ argv,
+ NULL,
+ /* We Need this to get the pid returned on win32 */
+ G_SPAWN_DO_NOT_REAP_CHILD |
+ G_SPAWN_SEARCH_PATH |
+ /* dbus-daemon will not abuse our descriptors, and
+ * passing this means we can use posix_spawn() for speed */
+ G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
+ NULL, NULL,
+ -1, -1, -1,
+ &pipe_fds[1], &pipe_fds[1], 1,
+ &self->priv->bus_pid,
+ NULL, NULL, NULL,
+ &error);
g_assert_no_error (error);
_g_test_watcher_add_pid (self->priv->bus_pid);
- /* Read bus address from daemon' stdout. We have to be careful to avoid
- * closing the FD, as it is passed to any D-Bus service activated processes,
- * and if we close it, they will get a SIGPIPE and die when they try to write
- * to their stdout. */
- stdout_fd2 = dup (self->priv->bus_stdout_fd);
- g_assert_cmpint (stdout_fd2, >=, 0);
- channel = g_io_channel_unix_new (stdout_fd2);
-
+ /* Read bus address from pipe */
+ channel = g_io_channel_unix_new (pipe_fds[0]);
+ pipe_fds[0] = -1;
+ g_io_channel_set_close_on_unref (channel, TRUE);
g_io_channel_read_line (channel, &self->priv->bus_address, NULL,
&termpos, &error);
g_assert_no_error (error);
self->priv->bus_address[termpos] = '\0';
+ close (pipe_fds[1]);
+ pipe_fds[1] = -1;
/* start dbus-monitor */
if (g_getenv ("G_DBUS_MONITOR") != NULL)
@@ -671,6 +701,7 @@ start_daemon (GTestDBus *self)
if (g_unlink (config_path) != 0)
g_assert_not_reached ();
+ g_free (print_address);
g_free (config_path);
g_free (config_arg);
}
@@ -687,8 +718,6 @@ stop_daemon (GTestDBus *self)
_g_test_watcher_remove_pid (self->priv->bus_pid);
g_spawn_close_pid (self->priv->bus_pid);
self->priv->bus_pid = 0;
- close (self->priv->bus_stdout_fd);
- self->priv->bus_stdout_fd = -1;
g_free (self->priv->bus_address);
self->priv->bus_address = NULL;
--
GitLab

View File

@ -0,0 +1,27 @@
From d129395fe2f22f12004526bc11ca7d407f42e4ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?GOUJON=20=C3=89van?= <goujon.evan@gmail.com>
Date: Thu, 22 Jul 2021 16:41:09 +0200
Subject: [PATCH] g_system_thread_new: Free a memory leak on error path
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d129395fe2f22f12004526bc11ca7d407f42e4ab
---
glib/gthread-posix.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c
index 3d69767e67..8e2e66db54 100644
--- a/glib/gthread-posix.c
+++ b/glib/gthread-posix.c
@@ -1331,6 +1331,7 @@ g_system_thread_new (GThreadFunc proxy,
{
g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
"Error creating thread: %s", g_strerror (ret));
+ g_free (thread->thread.name);
g_slice_free (GThreadPosix, thread);
return NULL;
}
--
GitLab

View File

@ -0,0 +1,35 @@
From 5419228f632af830d9117c142a1c7c1a9708cc08 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
Date: Mon, 11 Oct 2021 14:26:20 +0300
Subject: [PATCH] gtype: Fix pointer being dereferenced despite NULL check
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/5419228f632af830d9117c142a1c7c1a9708cc08
---
gobject/gtype.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 34f62ecba5..26ec30b7b7 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -3159,11 +3159,14 @@ g_type_class_peek_parent (gpointer g_class)
g_return_val_if_fail (g_class != NULL, NULL);
node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class));
+
+ g_return_val_if_fail (node != NULL, NULL);
+
/* We used to acquire a read lock here. That is not necessary, since
* parent->data->class.class is constant as long as the derived class
* exists.
*/
- if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node))
+ if (node->is_classed && node->data && NODE_PARENT_TYPE (node))
{
node = lookup_type_node_I (NODE_PARENT_TYPE (node));
class = node->data->class.class;
--
GitLab

View File

@ -0,0 +1,77 @@
From 36f7684d56c5d6182398b5db992c1e81ef6cb2f5 Mon Sep 17 00:00:00 2001
From: Rozhuk Ivan <rozhuk.im@gmail.com>
Date: Sun, 18 Oct 2020 03:06:46 +0300
Subject: [PATCH] gunixmounts: Add cache to g_unix_mount_points_get()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`_g_get_unix_mount_points()` parses `/etc/fstab` every time its called,
so caching the result can improve performance when mounts are queried
frequently.
The cache will remain in memory until `/etc/fstab` is next modified.
This means that the final copy of the cache will be deliberately
leaked on process exit.
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/36f7684d56c5d6182398b5db992c1e81ef6cb2f5
---
gio/gunixmounts.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index ecfa61de86..9c8ef5d666 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -1666,6 +1666,14 @@ g_unix_mount_for (const char *file_path,
return entry;
}
+static gpointer
+copy_mount_point_cb (gconstpointer src,
+ gpointer data)
+{
+ GUnixMountPoint *src_mount_point = (GUnixMountPoint *) src;
+ return g_unix_mount_point_copy (src_mount_point);
+}
+
/**
* g_unix_mount_points_get:
* @time_read: (out) (optional): guint64 to contain a timestamp.
@@ -1681,10 +1689,29 @@ g_unix_mount_for (const char *file_path,
GList *
g_unix_mount_points_get (guint64 *time_read)
{
+ static GList *mnt_pts_last = NULL;
+ static guint64 time_read_last = 0;
+ GList *mnt_pts = NULL;
+ guint64 time_read_now;
+ G_LOCK_DEFINE_STATIC (unix_mount_points);
+
+ G_LOCK (unix_mount_points);
+
+ time_read_now = get_mount_points_timestamp ();
+ if (time_read_now != time_read_last || mnt_pts_last == NULL)
+ {
+ time_read_last = time_read_now;
+ g_list_free_full (mnt_pts_last, (GDestroyNotify) g_unix_mount_point_free);
+ mnt_pts_last = _g_get_unix_mount_points ();
+ }
+ mnt_pts = g_list_copy_deep (mnt_pts_last, copy_mount_point_cb, NULL);
+
+ G_UNLOCK (unix_mount_points);
+
if (time_read)
- *time_read = get_mount_points_timestamp ();
+ *time_read = time_read_now;
- return _g_get_unix_mount_points ();
+ return mnt_pts;
}
/**
--
GitLab

View File

@ -0,0 +1,97 @@
From 9adbdd45d7101405eb05487bdf6a2015af9f8afd Mon Sep 17 00:00:00 2001
From: Chen Guanqiao <chen.chenchacha@foxmail.com>
Date: Thu, 11 Nov 2021 01:04:38 +0800
Subject: [PATCH] gutf8: add string length check when ending character offset
is -1
Some function such as atk_text_get_text, use -1 to indicate the end of the
string. And an crash occurs when the -1 is passed to g_utf8_substring.
Call Trace:
0 __memmove_avx_unaligned_erms
1 memcpy
2 g_utf8_substring
3 impl_GetText
4 handle_other
5 handle_message
6 _dbus_object_tree_dispatch_and_unlock
7 dbus_connection_dispatch
8 dbus_connection_dispatch
9 ()
10 g_main_dispatch
11 g_main_context_dispatch
12 g_main_context_iterate
13 g_main_context_iteration
14 g_application_run
15 main
Signed-off-by: Chen Guanqiao <chen.chenchacha@foxmail.com>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/9adbdd45d7101405eb05487bdf6a2015af9f8afd
---
glib/gutf8.c | 19 +++++++++++++++++--
glib/tests/utf8-misc.c | 4 ++++
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/glib/gutf8.c b/glib/gutf8.c
index 7d053540d6..9097f690b3 100644
--- a/glib/gutf8.c
+++ b/glib/gutf8.c
@@ -271,11 +271,15 @@ g_utf8_strlen (const gchar *p,
* g_utf8_substring:
* @str: a UTF-8 encoded string
* @start_pos: a character offset within @str
- * @end_pos: another character offset within @str
+ * @end_pos: another character offset within @str,
+ * or `-1` to indicate the end of the string
*
* Copies a substring out of a UTF-8 encoded string.
* The substring will contain @end_pos - @start_pos characters.
*
+ * Since GLib 2.72, `-1` can be passed to @end_pos to indicate the
+ * end of the string.
+ *
* Returns: (transfer full): a newly allocated copy of the requested
* substring. Free with g_free() when no longer needed.
*
@@ -288,8 +292,19 @@ g_utf8_substring (const gchar *str,
{
gchar *start, *end, *out;
+ g_return_val_if_fail (end_pos >= start_pos || end_pos == -1, NULL);
+
start = g_utf8_offset_to_pointer (str, start_pos);
- end = g_utf8_offset_to_pointer (start, end_pos - start_pos);
+
+ if (end_pos == -1)
+ {
+ glong length = g_utf8_strlen (start, -1);
+ end = g_utf8_offset_to_pointer (start, length);
+ }
+ else
+ {
+ end = g_utf8_offset_to_pointer (start, end_pos - start_pos);
+ }
out = g_malloc (end - start + 1);
memcpy (out, start, end - start);
diff --git a/glib/tests/utf8-misc.c b/glib/tests/utf8-misc.c
index 7a8c37448b..c137294229 100644
--- a/glib/tests/utf8-misc.c
+++ b/glib/tests/utf8-misc.c
@@ -128,6 +128,10 @@ test_utf8_substring (void)
r = g_utf8_substring ("abc\xe2\x82\xa0gh\xe2\x82\xa4", 2, 5);
g_assert_cmpstr (r, ==, "c\xe2\x82\xa0g");
g_free (r);
+
+ r = g_utf8_substring ("abcd", 1, -1);
+ g_assert_cmpstr (r, ==, "bcd");
+ g_free (r);
}
static void
--
GitLab

View File

@ -0,0 +1,58 @@
From bb40105fe95b5d95e31715ddb210380d381a1e26 Mon Sep 17 00:00:00 2001
From: Jamie Bainbridge <jamie.bainbridge@gmail.com>
Date: Wed, 8 Sep 2021 12:08:17 +1000
Subject: [PATCH] gutils: Avoid segfault in g_get_user_database_entry
g_get_user_database_entry() capitalises the first letter of pw_name
with g_ascii_toupper (pw->pw_name[0]).
However, the manpage for getpwnam() and getpwuid() says the result of
those calls "may point to a static area". GLib is then trying to edit
static memory which belongs to a shared library, so segfaults.
The reentrant variants of the above calls are supposed to fill the user
buffer supplied to them, however Michael Catanzaro also found a bug in
systemd where the data is not copied to the user buffer and still points
to static memory, resulting in the same sort of segfault. See:
https://github.com/systemd/systemd/issues/20679
Solve both these cases in GLib by copying pw_name off to a temporary
variable, set uppercase on that variable, and use the variable to join
into the desired string. Free the variable after it is no longer needed.
Signed-off-by: Jamie Bainbridge <jamie.bainbridge@gmail.com>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/bb40105fe95b5d95e31715ddb210380d381a1e26
---
glib/gutils.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/glib/gutils.c b/glib/gutils.c
index b7a2113d41..4bccd72297 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -692,14 +692,17 @@ g_get_user_database_entry (void)
{
gchar **gecos_fields;
gchar **name_parts;
+ gchar *uppercase_pw_name;
/* split the gecos field and substitute '&' */
gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
name_parts = g_strsplit (gecos_fields[0], "&", 0);
- pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
- e.real_name = g_strjoinv (pw->pw_name, name_parts);
+ uppercase_pw_name = g_strdup (pw->pw_name);
+ uppercase_pw_name[0] = g_ascii_toupper (uppercase_pw_name[0]);
+ e.real_name = g_strjoinv (uppercase_pw_name, name_parts);
g_strfreev (gecos_fields);
g_strfreev (name_parts);
+ g_free (uppercase_pw_name);
}
#endif
--
GitLab

View File

@ -0,0 +1,41 @@
From 78dc1cc3cd669e9fb92ae7847bab2b308c0a8628 Mon Sep 17 00:00:00 2001
From: Christoph Niethammer <christoph.niethammer@gmail.com>
Date: Thu, 27 Jan 2022 03:54:01 +0100
Subject: [PATCH] gutils: Fix g_find_program_in_path() to return an absolute
path
Fix a possibility of returning a relative path, in case PATH contains
a relative path. According to the doc, the function should return an
absolute path.
Signed-off-by: Christoph Niethammer <christoph.niethammer@gmail.com>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/78dc1cc3cd669e9fb92ae7847bab2b308c0a8628
---
glib/gutils.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/glib/gutils.c b/glib/gutils.c
index 6652d0ba05..6cc4506073 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -456,7 +456,14 @@ g_find_program_in_path (const gchar *program)
!g_file_test (startp, G_FILE_TEST_IS_DIR))
{
gchar *ret;
- ret = g_strdup (startp);
+ if (g_path_is_absolute (startp)) {
+ ret = g_strdup (startp);
+ } else {
+ gchar *cwd = NULL;
+ cwd = g_get_current_dir ();
+ ret = g_build_filename (cwd, startp, NULL);
+ g_free (cwd);
+ }
g_free (freeme);
#ifdef G_OS_WIN32
g_free ((gchar *) path_copy);
--
GitLab

View File

@ -0,0 +1,34 @@
From 05dffc1a7f562e9c8c6c21b67f99204f7a7b4e27 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
Date: Mon, 11 Oct 2021 14:20:26 +0300
Subject: [PATCH] gvariant: Fix memory leak on a TYPE_CHECK failure
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/05dffc1a7f562e9c8c6c21b67f99204f7a7b4e27
---
glib/gvariant.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/glib/gvariant.c b/glib/gvariant.c
index a9bb99c647..4a9704c19c 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -800,7 +800,13 @@ g_variant_new_array (const GVariantType *child_type,
for (i = 0; i < n_children; i++)
{
- TYPE_CHECK (children[i], child_type, NULL);
+ if G_UNLIKELY (!g_variant_is_of_type (children[i], child_type))
+ {
+ while (i != 0)
+ g_variant_unref (my_children[--i]);
+ g_free (my_children);
+ g_return_val_if_fail (g_variant_is_of_type (children[i], child_type), NULL);
+ }
my_children[i] = g_variant_ref_sink (children[i]);
trusted &= g_variant_is_trusted (children[i]);
}
--
GitLab

View File

@ -0,0 +1,61 @@
From 7f6ce4d8d234996b523b71abef139f1c80c88254 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
Date: Mon, 11 Oct 2021 14:24:12 +0300
Subject: [PATCH] gvariant: Fix pointers being dereferenced despite NULL checks
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/7f6ce4d8d234996b523b71abef139f1c80c88254
---
glib/gvariant.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/glib/gvariant.c b/glib/gvariant.c
index 4a9704c19c..5fa6a82685 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -3196,8 +3196,7 @@ struct heap_builder
#define GVSB_MAGIC ((gsize) 1033660112u)
#define GVSB_MAGIC_PARTIAL ((gsize) 2942751021u)
#define GVHB_MAGIC ((gsize) 3087242682u)
-#define is_valid_builder(b) (b != NULL && \
- GVSB(b)->magic == GVSB_MAGIC)
+#define is_valid_builder(b) (GVSB(b)->magic == GVSB_MAGIC)
#define is_valid_heap_builder(b) (GVHB(b)->magic == GVHB_MAGIC)
/* Just to make sure that by adding a union to GVariantBuilder, we
@@ -3207,7 +3206,9 @@ G_STATIC_ASSERT (sizeof (GVariantBuilder) == sizeof (gsize[16]));
static gboolean
ensure_valid_builder (GVariantBuilder *builder)
{
- if (is_valid_builder (builder))
+ if (builder == NULL)
+ return FALSE;
+ else if (is_valid_builder (builder))
return TRUE;
if (builder->u.s.partial_magic == GVSB_MAGIC_PARTIAL)
{
@@ -3853,8 +3854,7 @@ struct heap_dict
#define GVSD_MAGIC ((gsize) 2579507750u)
#define GVSD_MAGIC_PARTIAL ((gsize) 3488698669u)
#define GVHD_MAGIC ((gsize) 2450270775u)
-#define is_valid_dict(d) (d != NULL && \
- GVSD(d)->magic == GVSD_MAGIC)
+#define is_valid_dict(d) (GVSD(d)->magic == GVSD_MAGIC)
#define is_valid_heap_dict(d) (GVHD(d)->magic == GVHD_MAGIC)
/* Just to make sure that by adding a union to GVariantDict, we didn't
@@ -3864,7 +3864,9 @@ G_STATIC_ASSERT (sizeof (GVariantDict) == sizeof (gsize[16]));
static gboolean
ensure_valid_dict (GVariantDict *dict)
{
- if (is_valid_dict (dict))
+ if (dict == NULL)
+ return FALSE;
+ else if (is_valid_dict (dict))
return TRUE;
if (dict->u.s.partial_magic == GVSD_MAGIC_PARTIAL)
{
--
GitLab

View File

@ -0,0 +1,54 @@
From 77233f6f0779fe0c1cb48861d7deded4ae413567 Mon Sep 17 00:00:00 2001
From: Sebastian Wilhelmi <wilhelmi@google.com>
Date: Thu, 6 Jan 2022 20:50:34 +0000
Subject: [PATCH] gvariant-serialiser: Prevent unbounded recursion in
is_normal()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This fixes a bug in 7c4e6e9fbe473de0401c778c6b0c4aad27d5145a.
The original approach in that commit accidentally only checked the depth
at the leaf nodes in the variant tree, whereas actually the depth should
be checked before recursing to avoid stack overflow.
It neglected to consider that `g_variant_serialised_is_normal()` would
be recursed into by some of the `DISPATCH(_is_normal)` cases. When that
happened, the depth check was after the recursion so couldn鈥檛 prevent a
stack overflow.
Fixes: #2572
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/77233f6f0779fe0c1cb48861d7deded4ae413567
---
glib/gvariant-serialiser.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index 832a8fdc2a..7b13381b6f 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -1587,6 +1587,9 @@ g_variant_serialised_byteswap (GVariantSerialised serialised)
gboolean
g_variant_serialised_is_normal (GVariantSerialised serialised)
{
+ if (serialised.depth >= G_VARIANT_MAX_RECURSION_DEPTH)
+ return FALSE;
+
DISPATCH_CASES (serialised.type_info,
return gvs_/**/,/**/_is_normal (serialised);
@@ -1595,8 +1598,6 @@ g_variant_serialised_is_normal (GVariantSerialised serialised)
if (serialised.data == NULL)
return FALSE;
- if (serialised.depth >= G_VARIANT_MAX_RECURSION_DEPTH)
- return FALSE;
/* some hard-coded terminal cases */
switch (g_variant_type_info_get_type_char (serialised.type_info))
--
GitLab

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,76 @@
From d6ad10404f1d61d83803336ba5b64ec0bfd07da8 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Wed, 9 Mar 2022 14:09:57 +0000
Subject: [PATCH] tests: Add some tests for g_string_append_vprintf()
This adds coverage of one previously uncovered branch in `gstring.c`.
Real progress!
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d6ad10404f1d61d83803336ba5b64ec0bfd07da8
---
glib/tests/string.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/glib/tests/string.c b/glib/tests/string.c
index 24098d1be6..0229099e79 100644
--- a/glib/tests/string.c
+++ b/glib/tests/string.c
@@ -215,6 +215,44 @@ test_string_append (void)
g_string_free (string, TRUE);
}
+static void string_append_vprintf_va (GString *string,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (2, 3);
+
+/* Wrapper around g_string_append_vprintf() which takes varargs */
+static void
+string_append_vprintf_va (GString *string,
+ const gchar *format,
+ ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ g_string_append_vprintf (string, format, args);
+ va_end (args);
+}
+
+static void
+test_string_append_vprintf (void)
+{
+ GString *string;
+
+ /* append */
+ string = g_string_new ("firsthalf");
+
+ string_append_vprintf_va (string, "some %s placeholders", "format");
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+ string_append_vprintf_va (string, "%l", "invalid");
+#pragma GCC diagnostic pop
+
+ g_assert_cmpstr (string->str, ==, "firsthalfsome format placeholders");
+
+ g_string_free (string, TRUE);
+}
+
static void
test_string_prepend_c (void)
{
@@ -571,6 +609,7 @@ main (int argc,
g_test_add_func ("/string/test-string-assign", test_string_assign);
g_test_add_func ("/string/test-string-append-c", test_string_append_c);
g_test_add_func ("/string/test-string-append", test_string_append);
+ g_test_add_func ("/string/test-string-append-vprintf", test_string_append_vprintf);
g_test_add_func ("/string/test-string-prepend-c", test_string_prepend_c);
g_test_add_func ("/string/test-string-prepend", test_string_prepend);
g_test_add_func ("/string/test-string-insert", test_string_insert);
--
GitLab

View File

@ -0,0 +1,74 @@
From 27e1509cd68e58d9057091eadf97de96165c2bea Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Wed, 9 Mar 2022 14:08:49 +0000
Subject: [PATCH] tests: Add some tests for g_vasprintf() invalid format
strings
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/27e1509cd68e58d9057091eadf97de96165c2bea
---
glib/tests/test-printf.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/glib/tests/test-printf.c b/glib/tests/test-printf.c
index 59a461ddb0..77eb76a4ab 100644
--- a/glib/tests/test-printf.c
+++ b/glib/tests/test-printf.c
@@ -895,6 +895,44 @@ test_upper_bound (void)
g_assert_cmpint (res, ==, 20);
}
+static gint test_vasprintf_va (gchar **string,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (2, 3);
+
+/* Wrapper around g_vasprintf() which takes varargs */
+static gint
+test_vasprintf_va (gchar **string,
+ const gchar *format,
+ ...)
+{
+ va_list args;
+ gint len;
+
+ va_start (args, format);
+ len = g_vasprintf (string, format, args);
+ va_end (args);
+
+ return len;
+}
+
+static void
+test_vasprintf_invalid_format_placeholder (void)
+{
+ gint len = 0;
+ gchar *buf = "some non-null string";
+
+ g_test_summary ("Test error handling for invalid format placeholder in g_vasprintf()");
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+ len = test_vasprintf_va (&buf, "%l", "nope");
+#pragma GCC diagnostic pop
+
+ g_assert_cmpint (len, ==, -1);
+ g_assert_null (buf);
+}
+
int
main (int argc,
char *argv[])
@@ -935,5 +973,7 @@ main (int argc,
g_test_add_func ("/sprintf/test-positional-params", test_positional_params3);
g_test_add_func ("/sprintf/upper-bound", test_upper_bound);
+ g_test_add_func ("/vasprintf/invalid-format-placeholder", test_vasprintf_invalid_format_placeholder);
+
return g_test_run();
}
--
GitLab

View File

@ -0,0 +1,441 @@
From a7750cd02004d5e5f2660426b4d6728a604ef1e2 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 17 Mar 2022 19:05:14 +0000
Subject: [PATCH] tests: Add unit tests for GDBusMethodInvocation
These should cover everything to do with returning a value or error from
a `GDBusMethodInvocation` object.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a7750cd02004d5e5f2660426b4d6728a604ef1e2
---
gio/tests/gdbus-method-invocation.c | 402 ++++++++++++++++++++++++++++
gio/tests/meson.build | 1 +
2 files changed, 403 insertions(+)
create mode 100644 gio/tests/gdbus-method-invocation.c
diff --git a/gio/tests/gdbus-method-invocation.c b/gio/tests/gdbus-method-invocation.c
new file mode 100644
index 0000000000..985fd45ced
--- /dev/null
+++ b/gio/tests/gdbus-method-invocation.c
@@ -0,0 +1,402 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 漏 2022 Endless OS Foundation, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "gdbus-tests.h"
+
+static const GDBusArgInfo foo_get_fds_in_args =
+{
+ -1,
+ "type",
+ "s",
+ NULL
+};
+static const GDBusArgInfo * const foo_get_fds_in_arg_pointers[] = {&foo_get_fds_in_args, NULL};
+
+static const GDBusArgInfo foo_get_fds_out_args =
+{
+ -1,
+ "some_fd",
+ "h",
+ NULL
+};
+static const GDBusArgInfo * const foo_get_fds_out_arg_pointers[] = {&foo_get_fds_out_args, NULL};
+
+static const GDBusMethodInfo foo_method_info_wrong_return_type =
+{
+ -1,
+ "WrongReturnType",
+ NULL, /* in args */
+ NULL, /* out args */
+ NULL /* annotations */
+};
+static const GDBusMethodInfo foo_method_info_close_before_returning =
+{
+ -1,
+ "CloseBeforeReturning",
+ NULL, /* in args */
+ NULL, /* out args */
+ NULL /* annotations */
+};
+static const GDBusMethodInfo foo_method_info_get_fds =
+{
+ -1,
+ "GetFDs",
+ (GDBusArgInfo **) foo_get_fds_in_arg_pointers,
+ (GDBusArgInfo **) foo_get_fds_out_arg_pointers,
+ NULL /* annotations */
+};
+static const GDBusMethodInfo foo_method_info_return_error =
+{
+ -1,
+ "ReturnError",
+ NULL, /* in args */
+ NULL, /* out args */
+ NULL /* annotations */
+};
+static const GDBusMethodInfo * const foo_method_info_pointers[] = {
+ &foo_method_info_wrong_return_type,
+ &foo_method_info_close_before_returning,
+ &foo_method_info_get_fds,
+ &foo_method_info_return_error,
+ NULL
+};
+
+static const GDBusPropertyInfo foo_property_info[] =
+{
+ {
+ -1,
+ "InvalidType",
+ "s",
+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
+ NULL
+ },
+ {
+ -1,
+ "InvalidTypeNull",
+ "s",
+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
+ NULL
+ },
+ {
+ -1,
+ "InvalidValueType",
+ "s",
+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
+ NULL
+ },
+};
+static const GDBusPropertyInfo * const foo_property_info_pointers[] =
+{
+ &foo_property_info[0],
+ &foo_property_info[1],
+ &foo_property_info[2],
+ NULL
+};
+
+static const GDBusInterfaceInfo foo_interface_info =
+{
+ -1,
+ "org.example.Foo",
+ (GDBusMethodInfo **) &foo_method_info_pointers,
+ NULL, /* signals */
+ (GDBusPropertyInfo **) &foo_property_info_pointers,
+ NULL, /* annotations */
+};
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+test_method_invocation_return_method_call (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ gboolean no_reply = g_dbus_message_get_flags (g_dbus_method_invocation_get_message (invocation)) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
+
+ if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") &&
+ g_str_equal (method_name, "Get"))
+ {
+ const gchar *iface_name, *prop_name;
+
+ g_variant_get (parameters, "(&s&s)", &iface_name, &prop_name);
+ g_assert_cmpstr (iface_name, ==, "org.example.Foo");
+
+ /* Do different things depending on the property name. */
+ if (g_str_equal (prop_name, "InvalidType"))
+ {
+ if (!no_reply)
+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING,
+ "Type of return value for property 'Get' call should be '(v)' but got '(s)'");
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "this type is invalid"));
+ }
+ else if (g_str_equal (prop_name, "InvalidTypeNull"))
+ {
+ if (!no_reply)
+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING,
+ "Type of return value for property 'Get' call should be '(v)' but got '()'");
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ }
+ else if (g_str_equal (prop_name, "InvalidValueType"))
+ {
+ if (!no_reply)
+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING,
+ "Value returned from property 'Get' call for 'InvalidValueType' should be 's' but is 'u'");
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(v)", g_variant_new_uint32 (123)));
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+
+ g_test_assert_expected_messages ();
+ }
+ else if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") &&
+ g_str_equal (method_name, "Set"))
+ {
+ const gchar *iface_name, *prop_name;
+ GVariant *value;
+
+ g_variant_get (parameters, "(&s&sv)", &iface_name, &prop_name, &value);
+ g_assert_cmpstr (iface_name, ==, "org.example.Foo");
+
+ if (g_str_equal (prop_name, "InvalidType"))
+ {
+ if (!no_reply)
+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING,
+ "Type of return value for property 'Set' call should be '()' but got '(s)'");
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be unit"));
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+
+ g_test_assert_expected_messages ();
+ g_variant_unref (value);
+ }
+ else if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") &&
+ g_str_equal (method_name, "GetAll"))
+ {
+ const gchar *iface_name;
+
+ g_variant_get (parameters, "(&s)", &iface_name);
+ g_assert_cmpstr (iface_name, ==, "org.example.Foo");
+
+ if (!no_reply)
+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING,
+ "Type of return value for property 'GetAll' call should be '(a{sv})' but got '(s)'");
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be a different type"));
+ }
+ else if (g_str_equal (interface_name, "org.example.Foo") &&
+ g_str_equal (method_name, "WrongReturnType"))
+ {
+ if (!no_reply)
+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING,
+ "Type of return value is incorrect: expected '()', got '(s)'");
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be a different type"));
+ }
+ else if (g_str_equal (interface_name, "org.example.Foo") &&
+ g_str_equal (method_name, "CloseBeforeReturning"))
+ {
+ g_dbus_connection_close (connection, NULL, NULL, NULL);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ }
+ else if (g_str_equal (interface_name, "org.example.Foo") &&
+ g_str_equal (method_name, "GetFDs"))
+ {
+ const gchar *action;
+ GUnixFDList *list = NULL;
+ GError *local_error = NULL;
+
+ g_variant_get (parameters, "(&s)", &action);
+
+ list = g_unix_fd_list_new ();
+ g_unix_fd_list_append (list, 1, &local_error);
+ g_assert_no_error (local_error);
+
+ if (g_str_equal (action, "WrongNumber"))
+ {
+ g_unix_fd_list_append (list, 1, &local_error);
+ g_assert_no_error (local_error);
+ }
+
+ if (g_str_equal (action, "Valid") ||
+ g_str_equal (action, "WrongNumber"))
+ g_dbus_method_invocation_return_value_with_unix_fd_list (invocation, g_variant_new ("(h)"), list);
+ else
+ g_assert_not_reached ();
+
+ g_object_unref (list);
+ }
+ else if (g_str_equal (interface_name, "org.example.Foo") &&
+ g_str_equal (method_name, "ReturnError"))
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation, "org.example.Foo", "SomeError");
+ }
+ else
+ g_assert_not_reached ();
+}
+
+static void
+ensure_result_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GDBusConnection *connection = G_DBUS_CONNECTION (source);
+ GVariant *reply;
+ guint *n_outstanding_calls = user_data;
+
+ reply = g_dbus_connection_call_finish (connection, result, NULL);
+
+ /* We don鈥檛 care what the reply is. */
+ g_clear_pointer (&reply, g_variant_unref);
+
+ g_assert_cmpint (*n_outstanding_calls, >, 0);
+ *n_outstanding_calls = *n_outstanding_calls - 1;
+}
+
+static void
+test_method_invocation_return (void)
+{
+ GDBusConnection *connection = NULL;
+ GError *local_error = NULL;
+ guint registration_id;
+ const GDBusInterfaceVTable vtable = {
+ test_method_invocation_return_method_call, NULL, NULL, { 0 }
+ };
+ guint n_outstanding_calls = 0;
+
+ g_test_summary ("Test calling g_dbus_method_invocation_return_*() in various ways");
+
+ /* Connect to the bus. */
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error);
+ g_assert_no_error (local_error);
+ g_assert_nonnull (connection);
+
+ /* Register an object which we can call methods on. */
+ registration_id = g_dbus_connection_register_object (connection,
+ "/foo",
+ (GDBusInterfaceInfo *) &foo_interface_info,
+ &vtable, NULL, NULL, &local_error);
+ g_assert_no_error (local_error);
+ g_assert_cmpint (registration_id, !=, 0);
+
+ /* Test a variety of error cases */
+ {
+ const struct
+ {
+ const gchar *interface_name;
+ const gchar *method_name;
+ const gchar *parameters_string;
+ gboolean tests_undefined_behaviour;
+ }
+ calls[] =
+ {
+ { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidType')", TRUE },
+ { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidTypeNull')", TRUE },
+ { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidValueType')", TRUE },
+ { "org.freedesktop.DBus.Properties", "Set", "('org.example.Foo', 'InvalidType', <'irrelevant'>)", TRUE },
+ { "org.freedesktop.DBus.Properties", "GetAll", "('org.example.Foo',)", TRUE },
+ { "org.example.Foo", "WrongReturnType", "()", TRUE },
+ { "org.example.Foo", "GetFDs", "('Valid',)", FALSE },
+ { "org.example.Foo", "GetFDs", "('WrongNumber',)", TRUE },
+ { "org.example.Foo", "ReturnError", "()", FALSE },
+ { "org.example.Foo", "CloseBeforeReturning", "()", FALSE },
+ };
+ gsize i;
+
+ for (i = 0; i < G_N_ELEMENTS (calls); i++)
+ {
+ if (calls[i].tests_undefined_behaviour && !g_test_undefined ())
+ {
+ g_test_message ("Skipping %s.%s", calls[i].interface_name, calls[i].method_name);
+ continue;
+ }
+ else
+ {
+ g_test_message ("Calling %s.%s", calls[i].interface_name, calls[i].method_name);
+ }
+
+ /* Call twice, once expecting a result and once not. Do the call which
+ * doesn鈥檛 expect a result first; message ordering should ensure that
+ * it鈥檚 completed by the time the second call completes, so we don鈥檛
+ * have to account for it separately.
+ *
+ * That鈥檚 good, because the only way to get g_dbus_connection_call()
+ * to set %G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED is to not provide
+ * a callback function. */
+ n_outstanding_calls++;
+
+ g_dbus_connection_call (connection,
+ g_dbus_connection_get_unique_name (connection),
+ "/foo",
+ calls[i].interface_name,
+ calls[i].method_name,
+ g_variant_new_parsed (calls[i].parameters_string),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL, /* no callback */
+ NULL);
+
+ g_dbus_connection_call (connection,
+ g_dbus_connection_get_unique_name (connection),
+ "/foo",
+ calls[i].interface_name,
+ calls[i].method_name,
+ g_variant_new_parsed (calls[i].parameters_string),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ ensure_result_cb,
+ &n_outstanding_calls);
+ }
+ }
+
+ /* Wait until all the calls are complete. */
+ while (n_outstanding_calls > 0)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_dbus_connection_unregister_object (connection, registration_id);
+ g_object_unref (connection);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
+
+ g_test_add_func ("/gdbus/method-invocation/return", test_method_invocation_return);
+
+ return session_bus_run ();
+}
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index 81ff551dda..c825b0cd7a 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -333,6 +333,7 @@ if host_machine.system() != 'windows'
'suite' : ['slow'],
},
'gdbus-introspection' : {'extra_sources' : extra_sources},
+ 'gdbus-method-invocation' : {'extra_sources' : extra_sources},
'gdbus-names' : {'extra_sources' : extra_sources},
'gdbus-proxy' : {'extra_sources' : extra_sources},
'gdbus-proxy-threads' : {
--
GitLab

View File

@ -0,0 +1,77 @@
From 80d3018c1d3e3abf3b2440140ceff8cefa5b8902 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 4 Mar 2022 19:21:40 +0000
Subject: [PATCH] =?UTF-8?q?tests:=20Make=20the=20642026=20test=20take=2010?=
=?UTF-8?q?0=C3=97=20less=20time?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Its a tradeoff of time against reproducibility of the failure conditions
this test is testing for. If this test is run 100× on CI (which it will
be every few weeks), that should be often enough to catch a regression
here.
A regression in this code is unlikely, though.
This change is motivated by the fact that periodically this test times
out, and even when it doesnt, it takes on average 240s of CI runner
time during each CI run. Thats a lot of resources.
See: https://gitlab.gnome.org/GNOME/glib/-/jobs/1862013
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/80d3018c1d3e3abf3b2440140ceff8cefa5b8902
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
---
glib/tests/642026.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/glib/tests/642026.c b/glib/tests/642026.c
index aface4ea02..6fed6cd08c 100644
--- a/glib/tests/642026.c
+++ b/glib/tests/642026.c
@@ -16,10 +16,6 @@
#include <glib.h>
-/* On smcv's laptop, 1e4 iterations didn't always exhibit the bug, but 1e5
- * iterations exhibited it 10/10 times in practice. YMMV. */
-#define ITERATIONS 100000
-
static GStaticPrivate sp;
static GMutex *mutex;
static GCond *cond;
@@ -51,6 +47,19 @@ static gpointer thread_func (gpointer nil)
static void
testcase (void)
{
+ /* On smcv's laptop, 1e4 iterations didn't always exhibit the bug, but 1e5
+ * iterations exhibited it 10/10 times in practice. YMMV.
+ *
+ * If running with `-m slow` we want to try hard to reproduce the bug 10/10
+ * times. However, as of 2022 this takes around 240s on a CI machine, which
+ * is a long time to tie up those resources to verify that a bug fixed 10
+ * years ago is still fixed.
+ *
+ * So if running without `-m slow`, try 100× less hard to reproduce the bug,
+ * and rely on the fact that this is run under CI often enough to have a good
+ * chance of reproducing the bug in 1% of CI runs. */
+ const guint n_iterations = g_test_slow () ? 100000 : 1000;
+
g_test_bug ("642026");
mutex = g_mutex_new ();
@@ -58,7 +67,7 @@ testcase (void)
g_mutex_lock (mutex);
- for (i = 0; i < ITERATIONS; i++)
+ for (i = 0; i < n_iterations; i++)
{
GThread *t1;
--
GitLab

View File

@ -0,0 +1,119 @@
From 511627b7356af527c85c049e2020a36694d7de54 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 2 Sep 2022 18:56:35 +0200
Subject: [PATCH] tests/dbus-appinfo: Add test case for flatpak opening an
invalid file
We were testing the case in which we were opening an actual file, and so
potentially using a fd-list, however we were missing the case in which a file
was not existent.
And in such case we are incidentally hitting a leak now.
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/511627b7356af527c85c049e2020a36694d7de54
---
gio/tests/dbus-appinfo.c | 79 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/gio/tests/dbus-appinfo.c b/gio/tests/dbus-appinfo.c
index 2017e02df2..91e76403c6 100644
--- a/gio/tests/dbus-appinfo.c
+++ b/gio/tests/dbus-appinfo.c
@@ -360,6 +360,84 @@ test_flatpak_doc_export (void)
g_object_unref (flatpak_appinfo);
}
+static void
+on_flatpak_launch_invalid_uri_finish (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GApplication *app = user_data;
+ GError *error = NULL;
+
+ g_app_info_launch_uris_finish (G_APP_INFO (object), result, &error);
+ g_assert_no_error (error);
+
+ g_application_release (app);
+}
+
+static void
+on_flatpak_activate_invalid_uri (GApplication *app,
+ gpointer user_data)
+{
+ GDesktopAppInfo *flatpak_appinfo = user_data;
+ GList *uris;
+
+ /* The app will be released in on_flatpak_launch_uris_finish */
+ g_application_hold (app);
+
+ uris = g_list_prepend (NULL, "file:///hopefully/an/invalid/path.desktop");
+ g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, NULL,
+ NULL, on_flatpak_launch_invalid_uri_finish, app);
+ g_list_free (uris);
+}
+
+static void
+on_flatpak_open_invalid_uri (GApplication *app,
+ GFile **files,
+ gint n_files,
+ const char *hint)
+{
+ GFile *f;
+
+ g_assert_cmpint (n_files, ==, 1);
+ g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0]));
+
+ /* The file has been exported via the document portal */
+ f = g_file_new_for_uri ("file:///hopefully/an/invalid/path.desktop");
+ g_assert_true (g_file_equal (files[0], f));
+ g_object_unref (f);
+}
+
+static void
+test_flatpak_missing_doc_export (void)
+{
+ const gchar *argv[] = { "myapp", NULL };
+ gchar *desktop_file = NULL;
+ GDesktopAppInfo *flatpak_appinfo;
+ GApplication *app;
+ int status;
+
+ g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal.");
+
+ desktop_file = g_test_build_filename (G_TEST_DIST,
+ "org.gtk.test.dbusappinfo.flatpak.desktop",
+ NULL);
+ flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file);
+ g_assert_nonnull (flatpak_appinfo);
+
+ app = g_application_new ("org.gtk.test.dbusappinfo.flatpak",
+ G_APPLICATION_HANDLES_OPEN);
+ g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate_invalid_uri),
+ flatpak_appinfo);
+ g_signal_connect (app, "open", G_CALLBACK (on_flatpak_open_invalid_uri), NULL);
+
+ status = g_application_run (app, 1, (gchar **) argv);
+ g_assert_cmpint (status, ==, 0);
+
+ g_object_unref (app);
+ g_object_unref (flatpak_appinfo);
+ g_free (desktop_file);
+}
+
int
main (int argc, char **argv)
{
@@ -367,6 +445,7 @@ main (int argc, char **argv)
g_test_add_func ("/appinfo/dbusappinfo", test_dbus_appinfo);
g_test_add_func ("/appinfo/flatpak-doc-export", test_flatpak_doc_export);
+ g_test_add_func ("/appinfo/flatpak-missing-doc-export", test_flatpak_missing_doc_export);
return session_bus_run ();
}
--
GitLab

View File

@ -0,0 +1,36 @@
From f95ca6cb713383548f16f9a8ba2f6c51a4d25e25 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Fri, 17 Jun 2022 08:48:10 -0500
Subject: [PATCH] xdgmime: fix double free
We free xdg_dirs[i] twice, but fail to free xdg_dirs itself.
Also, since free() is NULL-safe, there is no need for the second check
here.
Discovered in: https://gitlab.freedesktop.org/xdg/xdgmime/-/merge_requests/16#note_1432025
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/f95ca6cb713383548f16f9a8ba2f6c51a4d25e25
---
gio/xdgmime/xdgmime.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/gio/xdgmime/xdgmime.c b/gio/xdgmime/xdgmime.c
index 9ab6760486..c3c11625e8 100644
--- a/gio/xdgmime/xdgmime.c
+++ b/gio/xdgmime/xdgmime.c
@@ -350,8 +350,7 @@ xdg_mime_set_dirs (const char * const *dirs)
for (i = 0; xdg_dirs != NULL && xdg_dirs[i] != NULL; i++)
free (xdg_dirs[i]);
- if (xdg_dirs != NULL)
- free (xdg_dirs[i]);
+ free (xdg_dirs);
xdg_dirs = NULL;
if (dirs != NULL)
--
GitLab