diff --git a/backport-Add-D-Bus-object-subtree-unregistration-tests.patch b/backport-Add-D-Bus-object-subtree-unregistration-tests.patch new file mode 100644 index 0000000000000000000000000000000000000000..75d959191e9785f8c1a6a635453aee21ae2ad6d5 --- /dev/null +++ b/backport-Add-D-Bus-object-subtree-unregistration-tests.patch @@ -0,0 +1,219 @@ +From 34ce204fd758e2ce0ab6bf152051534f46cdb336 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 isn’t 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 doesn’t ++ * 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 " ++ "doesn’t cause problems when racing with method callbacks " ++ "in another thread for that object or subtree"); ++ ++ /* Run iterations of the test until it’s likely we’ve hit the race. Limit the ++ * number of iterations so the test doesn’t 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. ++ * Don’t fail the test, though, as we can’t 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 + diff --git a/backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch b/backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch new file mode 100644 index 0000000000000000000000000000000000000000..4c52f54fe15388d87f73b11a207c8655a2448fc2 --- /dev/null +++ b/backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch @@ -0,0 +1,69 @@ +From f43cf341511dd684a58c09e104e28c11987cbff1 Mon Sep 17 00:00:00 2001 +From: Rozhuk Ivan +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 + diff --git a/backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch b/backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch new file mode 100644 index 0000000000000000000000000000000000000000..39caff89bebb6b3c5cf6f59fe474bca25ff6deb9 --- /dev/null +++ b/backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch @@ -0,0 +1,26 @@ +From 6ec432386ef98e26e5079b060ad823277e10f41f Mon Sep 17 00:00:00 2001 +From: Loic Le Page +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 diff --git a/backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch b/backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch new file mode 100644 index 0000000000000000000000000000000000000000..0dd94f7baf2c0a7e800ec7eb34ca3b99a807b368 --- /dev/null +++ b/backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch @@ -0,0 +1,68 @@ +From d9ba6150909818beb05573f54f26232063492c5b Mon Sep 17 00:00:00 2001 +From: Emmanuel Fleury +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 + diff --git a/backport-Implement-GFileIface.set_display_name-for-resource-files.patch b/backport-Implement-GFileIface.set_display_name-for-resource-files.patch new file mode 100644 index 0000000000000000000000000000000000000000..ca4f5577656f2d42571476749a50ba5a3811439b --- /dev/null +++ b/backport-Implement-GFileIface.set_display_name-for-resource-files.patch @@ -0,0 +1,52 @@ +From a9394bd68e222377f0156bf9c213b3f3a1e340d0 Mon Sep 17 00:00:00 2001 +From: Emmanuele Bassi +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 + diff --git a/backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch b/backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch new file mode 100644 index 0000000000000000000000000000000000000000..b0f8a1d1685df31bd7238123064efa021b90601b --- /dev/null +++ b/backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch @@ -0,0 +1,34 @@ +From 27203e48c91ab8b55033dcf1773cb60c0aaed3fa Mon Sep 17 00:00:00 2001 +From: Sebastian Keller +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 + diff --git a/backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch b/backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch new file mode 100644 index 0000000000000000000000000000000000000000..2c8c7f3a3a33362c1900d72f2d9412f86c4d3af5 --- /dev/null +++ b/backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch @@ -0,0 +1,46 @@ +From 02d0d6497b92d05d1145d1077654ad2453938b6c Mon Sep 17 00:00:00 2001 +From: Rozhuk Ivan +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, diff --git a/backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch b/backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch new file mode 100644 index 0000000000000000000000000000000000000000..10b9e402a8f01ac37468e8f05ac3731973229346 --- /dev/null +++ b/backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch @@ -0,0 +1,55 @@ +From 374a1895b62b2504d0b6ae1c404237802e73ddb6 Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann +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 diff --git a/backport-garray-buffer-overflow-fix.patch b/backport-garray-buffer-overflow-fix.patch new file mode 100644 index 0000000000000000000000000000000000000000..b8ab9c4bd8a3edb056defaf83020f0afa43d4026 --- /dev/null +++ b/backport-garray-buffer-overflow-fix.patch @@ -0,0 +1,279 @@ +From 995823b9d9e866ffb133cf3ff53e7e09da9f13d6 Mon Sep 17 00:00:00 2001 +From: Mark Weaver +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_MAXSIZE / 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_MAXSIZE, 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 diff --git a/backport-gdbusconnection-Add-some-ownership-annotations.patch b/backport-gdbusconnection-Add-some-ownership-annotations.patch new file mode 100644 index 0000000000000000000000000000000000000000..0b279447ab4271a8103e1b4679ceca7f97aac0ba --- /dev/null +++ b/backport-gdbusconnection-Add-some-ownership-annotations.patch @@ -0,0 +1,54 @@ +From a497fdf302bf67e4df2e1474389c0ff2152f1e99 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Fri, 24 Sep 2021 08:58:42 +0100 +Subject: [PATCH] gdbusconnection: Add some ownership annotations + +Signed-off-by: Philip Withnall + +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 + diff --git a/backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch b/backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch new file mode 100644 index 0000000000000000000000000000000000000000..7f3a61025871b215c9fa213bb7586debd364b80e --- /dev/null +++ b/backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch @@ -0,0 +1,194 @@ +From 50fbf05d61db500df9052bb682d9c01e0bf51ffb Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 + diff --git a/backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch b/backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch new file mode 100644 index 0000000000000000000000000000000000000000..645faeb540fc7ac17e9d07ddd646d64c247c04d3 --- /dev/null +++ b/backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch @@ -0,0 +1,62 @@ +From 117b748e44e0ec930fcb9641e3f808572d4a41f2 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 + diff --git a/backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch b/backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch new file mode 100644 index 0000000000000000000000000000000000000000..cbd3b3c02304469690ca58f46d1cc0ec4ae081fb --- /dev/null +++ b/backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch @@ -0,0 +1,136 @@ +From c8c2ed4af5cdf8d77af2cd9a2a4b4f6ac8d1fc70 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 diff --git a/backport-gdbusconnection-Move-ExportedSubtree-definition.patch b/backport-gdbusconnection-Move-ExportedSubtree-definition.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb8b926fcf4af2c729d82fdf54bb7304d44595c2 --- /dev/null +++ b/backport-gdbusconnection-Move-ExportedSubtree-definition.patch @@ -0,0 +1,94 @@ +From 310f2c1632e05c4f32be033c009642012741d876 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 + diff --git a/backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch b/backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch new file mode 100644 index 0000000000000000000000000000000000000000..5e1a82d2dfd632acbf03080fa7b7fc6408d7a94e --- /dev/null +++ b/backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch @@ -0,0 +1,53 @@ +From c74177337dae7b06383261b2bedabf1f12d816b5 Mon Sep 17 00:00:00 2001 +From: Sebastian Wilhelmi +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 diff --git a/backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch b/backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch new file mode 100644 index 0000000000000000000000000000000000000000..937835b09a42675e8d93e921022d3c57cd8eace8 --- /dev/null +++ b/backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch @@ -0,0 +1,30 @@ +From 7143457076d6469f76185a2f1d7071aca40a591e Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 17 Mar 2022 19:03:15 +0000 +Subject: [PATCH] gdbusmethodinvocation: Drop redundant quote from warning + message + +Signed-off-by: Philip Withnall + +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 diff --git a/backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch b/backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch new file mode 100644 index 0000000000000000000000000000000000000000..4259891e45308bb2998f14cd9af07a465e23bc24 --- /dev/null +++ b/backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch @@ -0,0 +1,66 @@ +From a3b8846e54c7132056411605f815b67e831833d2 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 (¶meters)); + + #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 diff --git a/backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch b/backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch new file mode 100644 index 0000000000000000000000000000000000000000..6994562567c7c5b2a24bd66ad0235cf37d6ffbf6 --- /dev/null +++ b/backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch @@ -0,0 +1,81 @@ +From 76f5460107c86a44be6387c159b34ae50aa1e623 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 diff --git a/backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch b/backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch new file mode 100644 index 0000000000000000000000000000000000000000..0d5d1d3324901d6f92ad611861e8ba7939a0442e --- /dev/null +++ b/backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch @@ -0,0 +1,48 @@ +From 221f22b6e18fdd306e676e28a79afd3697bddd03 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch b/backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch new file mode 100644 index 0000000000000000000000000000000000000000..9a62b5b1cd67aef3ab8b1e96295cd368e6d1317d --- /dev/null +++ b/backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch @@ -0,0 +1,29 @@ +From e268ff39b648e7b100d2aa50f472b4ff8ff5313a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch b/backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch new file mode 100644 index 0000000000000000000000000000000000000000..ce5f46b5fbd4d662c5f1d2212d0152a5109e6595 --- /dev/null +++ b/backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch @@ -0,0 +1,67 @@ +From 1da208cddc19cad05ccf4b798a99f7045e41ffc4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gio-tool-Fix-a-minor-memory-leak.patch b/backport-gio-tool-Fix-a-minor-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..6684613770468731582ea64c5bc5316121299264 --- /dev/null +++ b/backport-gio-tool-Fix-a-minor-memory-leak.patch @@ -0,0 +1,72 @@ +From 49cc9b96f4c19a98ddf6e9b7417c7019ebc28ca3 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 diff --git a/backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch b/backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..39228fc64c27b1a0811d5b3bf44ef3a85a51bf8b --- /dev/null +++ b/backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch @@ -0,0 +1,33 @@ +From 2401e1a090dcaac7614a8984cd3e3832a2a476ab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gopenuriportal-Fix-GVariantBuilder-and-string-leakage.patch b/backport-gopenuriportal-Fix-GVariantBuilder-and-string-leakage.patch index 097ab8bb8cded6caf9a7a2940f388bc42189f30a..33c8b8bfe345d682be786201a5a05dee1fc16490 100644 --- a/backport-gopenuriportal-Fix-GVariantBuilder-and-string-leakage.patch +++ b/backport-gopenuriportal-Fix-GVariantBuilder-and-string-leakage.patch @@ -19,8 +19,8 @@ index be68569ed8..6ef8f037c3 100644 errsv = errno; if (fd == -1) { -+ g_free (path); -+ g_variant_builder_clear (&opt_builder); ++ 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; diff --git a/backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch b/backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8115245cf7e2c5a55ad2fd2ac171ea74da6b648 --- /dev/null +++ b/backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch @@ -0,0 +1,39 @@ +From 969eb835dc2f07c34ae8ca45ddbc41590a2e2f8e Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 + diff --git a/backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch b/backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch new file mode 100644 index 0000000000000000000000000000000000000000..60c0414f0e759c579d11f885341c4e6f0fd9da40 --- /dev/null +++ b/backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch @@ -0,0 +1,38 @@ +From 7329c6e09bf59ccae2d8d3e788ce43bb6af6c3db Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 diff --git a/backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch b/backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch new file mode 100644 index 0000000000000000000000000000000000000000..d865a121b8decf9955c98ff2860dfb3b53acf764 --- /dev/null +++ b/backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch @@ -0,0 +1,117 @@ +From 56d371942e43c52bc6131067e2dc2a35f6cd5a3d Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 + diff --git a/backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch b/backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch new file mode 100644 index 0000000000000000000000000000000000000000..912e474f51b1bf6ddf77e48b9877c10ea08b049c --- /dev/null +++ b/backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch @@ -0,0 +1,192 @@ +From d98a52254b4a681569a44f6be2aeceeaed58202c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 ++#include ++#include + #endif + + #include +@@ -44,8 +46,8 @@ + + #include "glibintl.h" + +-#ifdef G_OS_WIN32 +-#include ++#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 diff --git a/backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch b/backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch new file mode 100644 index 0000000000000000000000000000000000000000..c511c7e30d38febeba2d1ac4c3fdaab8b8993574 --- /dev/null +++ b/backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch @@ -0,0 +1,77 @@ +From 36f7684d56c5d6182398b5db992c1e81ef6cb2f5 Mon Sep 17 00:00:00 2001 +From: Rozhuk Ivan +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 it’s 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 + diff --git a/backport-gutf8-add-string-length-check.patch b/backport-gutf8-add-string-length-check.patch new file mode 100644 index 0000000000000000000000000000000000000000..93603952b9dd3e810deb3f7262772dfc127ce5ad --- /dev/null +++ b/backport-gutf8-add-string-length-check.patch @@ -0,0 +1,97 @@ +From 9adbdd45d7101405eb05487bdf6a2015af9f8afd Mon Sep 17 00:00:00 2001 +From: Chen Guanqiao +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 + +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 + diff --git a/backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch b/backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch new file mode 100644 index 0000000000000000000000000000000000000000..405164e330178d548c27da8f7dbdd90b170913a7 --- /dev/null +++ b/backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch @@ -0,0 +1,41 @@ +From 78dc1cc3cd669e9fb92ae7847bab2b308c0a8628 Mon Sep 17 00:00:00 2001 +From: Christoph Niethammer +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 + +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 diff --git a/backport-gvariant-serialiser-Prevent-unbounded-recursion.patch b/backport-gvariant-serialiser-Prevent-unbounded-recursion.patch new file mode 100644 index 0000000000000000000000000000000000000000..447cbf9ab6c788e20ecd47128c5c9d18f4825a14 --- /dev/null +++ b/backport-gvariant-serialiser-Prevent-unbounded-recursion.patch @@ -0,0 +1,54 @@ +From 77233f6f0779fe0c1cb48861d7deded4ae413567 Mon Sep 17 00:00:00 2001 +From: Sebastian Wilhelmi +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 diff --git a/backport-tests-Add-some-tests-for-g_string_append_vprintf.patch b/backport-tests-Add-some-tests-for-g_string_append_vprintf.patch new file mode 100644 index 0000000000000000000000000000000000000000..0c99c60696ed9a64e6a9c7bb4ce42bb5e26ceb7f --- /dev/null +++ b/backport-tests-Add-some-tests-for-g_string_append_vprintf.patch @@ -0,0 +1,76 @@ +From d6ad10404f1d61d83803336ba5b64ec0bfd07da8 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 diff --git a/backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch b/backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch new file mode 100644 index 0000000000000000000000000000000000000000..ed15c52b789373858ee19933205a0c6d89f9e0e4 --- /dev/null +++ b/backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch @@ -0,0 +1,74 @@ +From 27e1509cd68e58d9057091eadf97de96165c2bea Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 diff --git a/backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch b/backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch new file mode 100644 index 0000000000000000000000000000000000000000..59e1d327303d69827eb60703ea063d577627fcae --- /dev/null +++ b/backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch @@ -0,0 +1,441 @@ +From a7750cd02004d5e5f2660426b4d6728a604ef1e2 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 . ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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 diff --git a/backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch b/backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch new file mode 100644 index 0000000000000000000000000000000000000000..b82fc7f37d783367304eac95c97980e0a1e09d29 --- /dev/null +++ b/backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch @@ -0,0 +1,119 @@ +From 511627b7356af527c85c049e2020a36694d7de54 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-xdgmime-fix-double-free.patch b/backport-xdgmime-fix-double-free.patch new file mode 100644 index 0000000000000000000000000000000000000000..8aa6991fb30c94662c71b5f7a99dc6dd7af74446 --- /dev/null +++ b/backport-xdgmime-fix-double-free.patch @@ -0,0 +1,36 @@ +From f95ca6cb713383548f16f9a8ba2f6c51a4d25e25 Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +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 + diff --git a/glib2.spec b/glib2.spec index dad7e28941ce58977d5074b68d3cbb81bc63401d..970fc79ee2b2bd5a0a995263c48f2cb303837126 100644 --- a/glib2.spec +++ b/glib2.spec @@ -1,6 +1,6 @@ Name: glib2 Version: 2.68.1 -Release: 12 +Release: 13 Summary: The core library that forms the basis for projects such as GTK+ and GNOME License: LGPLv2+ URL: http://www.gtk.org @@ -25,6 +25,42 @@ Patch6015: backport-gvariant-Fix-memory-leak-on-a-TYPE-CHECK-failure.patch Patch6016: backport-gvariant-Fix-pointers-being-dereferenced-despite-NULL-checks.patch Patch6017: backport-gtype-Fix-pointer-being-dereferenced-despite-NULL-check.patch Patch6018: backport-add-OOM-handling-in-mimemagic.patch +Patch6019: backport-garray-buffer-overflow-fix.patch +Patch6020: backport-gdbusconnection-Move-ExportedSubtree-definition.patch +Patch6021: backport-gdbusconnection-Add-some-ownership-annotations.patch +Patch6022: backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch +Patch6023: backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch +Patch6024: backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch +Patch6025: backport-Add-D-Bus-object-subtree-unregistration-tests.patch +Patch6026: backport-gutf8-add-string-length-check.patch +Patch6027: backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch +Patch6028: backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch +Patch6029: backport-gvariant-serialiser-Prevent-unbounded-recursion.patch +Patch6030: backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch +Patch6031: backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch +Patch6032: backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch +Patch6033: backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch +Patch6034: backport-tests-Add-some-tests-for-g_string_append_vprintf.patch +Patch6035: backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch +Patch6036: backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch +Patch6037: backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch +Patch6038: backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch +Patch6039: backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch +Patch6040: backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch +Patch6041: backport-gio-tool-Fix-a-minor-memory-leak.patch +Patch6042: backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch +Patch6043: backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch +Patch6044: backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch +Patch6045: backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch +Patch6046: backport-xdgmime-fix-double-free.patch +Patch6047: backport-Implement-GFileIface.set_display_name-for-resource-files.patch +Patch6048: backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch +Patch6049: backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch +Patch6050: backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch +Patch6051: backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch +Patch6052: backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch +Patch6053: backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch +Patch6054: backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch BuildRequires: chrpath gcc gcc-c++ gettext perl-interpreter BUildRequires: glibc-devel libattr-devel libselinux-devel meson @@ -190,6 +226,10 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %endif %changelog +* Sat Oct 15 2022 hanhuihui - 2.68.1-13 +- Type:bugfix +- DESC:backport some patches from community + * Thu Apr 28 2022 yanan - 2.68.1-12 - Type:bugfix - DESC:fix issues found by svace static code analyzer