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

Bug#986001: marked as done (buster-pu: package glib2.0/2.58.3-2+deb10u3)



Your message dated Sat, 19 Jun 2021 10:56:39 +0100
with message-id <5c65c3ad2ac9b1b1f78bf73b1cf073041e619b51.camel@adam-barratt.org.uk>
and subject line Closing p-u requests for fixes included in 10.10 point release
has caused the Debian Bug report #986001,
regarding buster-pu: package glib2.0/2.58.3-2+deb10u3
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
986001: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986001
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

[ Reason ]
Backport security fixes from testing/unstable. The security team say
they do not intend to issue a DSA for these.

[ Impact ]
* CVE-2021-28153: symlink attack allowing an attacker to create an empty
  regular file in a location of their choice when a malicious archive is
  unpacked with file-roller
* CVE-2021-27219: integer overflow that can cause at least a crash (DoS),
  and maybe code execution, in a setuid program from policykit-1
* CVE-2021-27218: another integer overflow, not known to be exploitable
* various other integer overflows fixed at the same time as CVE-2021-27219,
  which are not known to be exploitable

Please see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=984969#26 if
more information is required.

[ Tests ]
I'm trying the proposed version with normal use on a GNOME laptop and
some servers. The autopkgtests are fairly extensive, and still pass,
including new coverage for CVE-2021-28153. The proof-of-concept exploits
for CVE-2021-27219 and CVE-2021-28153 also now fail.

[ Risks ]
This is a key package and a dependency of many high-visibility packages,
but the changes are reasonably straightforward. They were reviewed
upstream, and the upstream maintainer who made most of the original changes
has checked my backporting.

All the changes here are already in unstable, and most are in testing
(a follow-up error-handling fix related to CVE-2021-28153 was unblocked
in #985610 but has not yet migrated).

I've deliberately only backported the simpler and more obviously correct
changes related to CVE-2021-27219. Some more complex overflow fixes
that came with those turned out to cause regressions, so instead of
backporting those and the subsequent regression fixes, I checked
that the overflows being fixed were unlikely to be realistically
attacker-triggerable (please see
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=984969#26 if more
information is required).

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
 glib2.0 (2.58.3-2+deb10u3) buster; urgency=medium
 .
   * d/patches: Resolve integer overflows, including CVE-2021-27219.
     These backported patches resolve an integer overflow that is known to
     be attacker-triggerable for denial of service in polkit (policykit-1),
     as well as replacing other simple uses of g_memdup() with g_memdup2().
     Overflows in most of these places would not be attacker-triggerable,
     but replacing them is simpler than assessing whether they are
     attacker-triggerable.
     The more complicated changes from 2.66.7 have not been backported,
     to avoid regressions in Debian 10; overflows in those locations are
     not believed to be attacker-triggerable. (Closes: #982778)
   * d/patches: Fix integer overflow CVE-2021-27218.
     This is not known to be exploitable in any particular program, but
     might be. (Closes: #982779)
   * d/patches: Fix a symlink attack affecting file-roller, CVE-2021-28153
     (Closes: #984969)

[ Other information ]
If the SRMs are doing 10.10 sooner than the usual schedule to resolve
Secure Boot revocations, I'm happy for this to either be included in
10.10, or skipped for 10.10 and included in 10.11 instead.

Thanks,
    smcv
diffstat for glib2.0-2.58.3 glib2.0-2.58.3

 changelog                                                               |   20 
 patches/gbytearray-Do-not-accept-too-large-byte-arrays.patch            |  133 +++++
 patches/ghash-Use-g_memdup2-instead-of-g_memdup.patch                   |   36 +
 patches/gio-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch   |  260 +++++++++
 patches/glib-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch  |  249 +++++++++
 patches/glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-to-re.patch |   53 ++
 patches/glocalfileoutputstream-Factor-out-a-flag-check.patch            |   54 ++
 patches/glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATION-wit.patch |  264 ++++++++++
 patches/glocalfileoutputstream-Fix-a-typo-in-a-comment.patch            |   26 
 patches/glocalfileoutputstream-Tidy-up-error-handling.patch             |  156 +++++
 patches/gobject-Use-g_memdup2-instead-of-g_memdup-in-obvious-plac.patch |  134 +++++
 patches/gstrfuncs-Add-internal-g_memdup2-function.patch                 |  173 ++++++
 patches/gvariant-test-Use-g_memdup2.patch                               |   64 ++
 patches/gwin32-Use-gsize-internally-in-g_wcsdup.patch                   |   52 +
 patches/gwinhttpfile-Avoid-arithmetic-overflow-when-calculating-a.patch |   45 +
 patches/series                                                          |   15 
 patches/tests-Stop-using-g_test_bug_base-in-file-tests.patch            |   46 +
 17 files changed, 1780 insertions(+)

diff -Nru glib2.0-2.58.3/debian/changelog glib2.0-2.58.3/debian/changelog
--- glib2.0-2.58.3/debian/changelog	2019-11-06 08:29:15.000000000 +0000
+++ glib2.0-2.58.3/debian/changelog	2021-03-27 11:34:13.000000000 +0000
@@ -1,3 +1,23 @@
+glib2.0 (2.58.3-2+deb10u3) buster; urgency=medium
+
+  * d/patches: Resolve integer overflows, including CVE-2021-27219.
+    These backported patches resolve an integer overflow that is known to
+    be attacker-triggerable for denial of service in polkit (policykit-1),
+    as well as replacing other simple uses of g_memdup() with g_memdup2().
+    Overflows in most of these places would not be attacker-triggerable,
+    but replacing them is simpler than assessing whether they are
+    attacker-triggerable.
+    The more complicated changes from 2.66.7 have not been backported,
+    to avoid regressions in Debian 10; overflows in those locations are
+    not believed to be attacker-triggerable. (Closes: #982778)
+  * d/patches: Fix integer overflow CVE-2021-27218.
+    This is not known to be exploitable in any particular program, but
+    might be. (Closes: #982779)
+  * d/patches: Fix a symlink attack affecting file-roller, CVE-2021-28153
+    (Closes: #984969)
+
+ -- Simon McVittie <smcv@debian.org>  Sat, 27 Mar 2021 11:34:13 +0000
+
 glib2.0 (2.58.3-2+deb10u2) buster; urgency=medium
 
   * Team upload
diff -Nru glib2.0-2.58.3/debian/patches/gbytearray-Do-not-accept-too-large-byte-arrays.patch glib2.0-2.58.3/debian/patches/gbytearray-Do-not-accept-too-large-byte-arrays.patch
--- glib2.0-2.58.3/debian/patches/gbytearray-Do-not-accept-too-large-byte-arrays.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/gbytearray-Do-not-accept-too-large-byte-arrays.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,133 @@
+From: Krzesimir Nowak <qdlacz@gmail.com>
+Date: Wed, 10 Feb 2021 23:51:07 +0100
+Subject: gbytearray: Do not accept too large byte arrays
+
+GByteArray uses guint for storing the length of the byte array, but it
+also has a constructor (g_byte_array_new_take) that takes length as a
+gsize. gsize may be larger than guint (64 bits for gsize vs 32 bits
+for guint). It is possible to call the function with a value greater
+than G_MAXUINT, which will result in silent length truncation. This
+may happen as a result of unreffing GBytes into GByteArray, so rather
+be loud about it.
+
+(Test case tweaked by Philip Withnall.)
+
+(Backport 2.66: Add #include gstrfuncsprivate.h in the test case for
+`g_memdup2()`.)
+
+Fixes: CVE-2021-27218
+Bug-Debian: https://bugs.debian.org/982779
+Origin: backport, commit:0f384c88a241bbbd884487b1c40b7b75f1e638d3
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2001
+---
+ glib/garray.c      |  6 ++++++
+ glib/gbytes.c      |  4 ++++
+ glib/tests/bytes.c | 37 +++++++++++++++++++++++++++++++++++--
+ 3 files changed, 45 insertions(+), 2 deletions(-)
+
+diff --git a/glib/garray.c b/glib/garray.c
+index a6cbd57..b00033a 100644
+--- a/glib/garray.c
++++ b/glib/garray.c
+@@ -1755,6 +1755,10 @@ g_byte_array_new (void)
+  * Create byte array containing the data. The data will be owned by the array
+  * and will be freed with g_free(), i.e. it could be allocated using g_strdup().
+  *
++ * Do not use it if @len is greater than %G_MAXUINT. #GByteArray
++ * stores the length of its data in #guint, which may be shorter than
++ * #gsize.
++ *
+  * Since: 2.32
+  *
+  * Returns: (transfer full): a new #GByteArray
+@@ -1766,6 +1770,8 @@ g_byte_array_new_take (guint8 *data,
+   GByteArray *array;
+   GRealArray *real;
+ 
++  g_return_val_if_fail (len <= G_MAXUINT, NULL);
++
+   array = g_byte_array_new ();
+   real = (GRealArray *)array;
+   g_assert (real->data == NULL);
+diff --git a/glib/gbytes.c b/glib/gbytes.c
+index 84c87e4..dee4948 100644
+--- a/glib/gbytes.c
++++ b/glib/gbytes.c
+@@ -521,6 +521,10 @@ g_bytes_unref_to_data (GBytes *bytes,
+  * g_bytes_new(), g_bytes_new_take() or g_byte_array_free_to_bytes(). In all
+  * other cases the data is copied.
+  *
++ * Do not use it if @bytes contains more than %G_MAXUINT
++ * bytes. #GByteArray stores the length of its data in #guint, which
++ * may be shorter than #gsize, that @bytes is using.
++ *
+  * Returns: (transfer full): a new mutable #GByteArray containing the same byte data
+  *
+  * Since: 2.32
+diff --git a/glib/tests/bytes.c b/glib/tests/bytes.c
+index 5ea5c2b..9e26382 100644
+--- a/glib/tests/bytes.c
++++ b/glib/tests/bytes.c
+@@ -10,12 +10,12 @@
+  */
+ 
+ #undef G_DISABLE_ASSERT
+-#undef G_LOG_DOMAIN
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "glib.h"
++#include "glib/gstrfuncsprivate.h"
+ 
+ /* Keep in sync with glib/gbytes.c */
+ struct _GBytes
+@@ -333,6 +333,38 @@ test_to_array_transferred (void)
+   g_byte_array_unref (array);
+ }
+ 
++static void
++test_to_array_transferred_oversize (void)
++{
++  g_test_message ("g_bytes_unref_to_array() can only take GBytes up to "
++                  "G_MAXUINT in length; test that longer ones are rejected");
++
++  if (sizeof (guint) >= sizeof (gsize))
++    {
++      g_test_skip ("Skipping test as guint is not smaller than gsize");
++    }
++  else if (g_test_undefined ())
++    {
++      GByteArray *array = NULL;
++      GBytes *bytes = NULL;
++      gpointer data = g_memdup2 (NYAN, N_NYAN);
++      gsize len = ((gsize) G_MAXUINT) + 1;
++
++      bytes = g_bytes_new_take (data, len);
++      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
++                             "g_byte_array_new_take: assertion 'len <= G_MAXUINT' failed");
++      array = g_bytes_unref_to_array (g_steal_pointer (&bytes));
++      g_test_assert_expected_messages ();
++      g_assert_null (array);
++
++      g_free (data);
++    }
++  else
++    {
++      g_test_skip ("Skipping test as testing undefined behaviour is disabled");
++    }
++}
++
+ static void
+ test_to_array_two_refs (void)
+ {
+@@ -407,7 +439,8 @@ main (int argc, char *argv[])
+   g_test_add_func ("/bytes/to-data/transfered", test_to_data_transferred);
+   g_test_add_func ("/bytes/to-data/two-refs", test_to_data_two_refs);
+   g_test_add_func ("/bytes/to-data/non-malloc", test_to_data_non_malloc);
+-  g_test_add_func ("/bytes/to-array/transfered", test_to_array_transferred);
++  g_test_add_func ("/bytes/to-array/transferred", test_to_array_transferred);
++  g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize);
+   g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs);
+   g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc);
+   g_test_add_func ("/bytes/null", test_null);
diff -Nru glib2.0-2.58.3/debian/patches/ghash-Use-g_memdup2-instead-of-g_memdup.patch glib2.0-2.58.3/debian/patches/ghash-Use-g_memdup2-instead-of-g_memdup.patch
--- glib2.0-2.58.3/debian/patches/ghash-Use-g_memdup2-instead-of-g_memdup.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/ghash-Use-g_memdup2-instead-of-g_memdup.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,36 @@
+From: Simon McVittie <smcv@collabora.com>
+Date: Thu, 18 Mar 2021 10:31:00 +0000
+Subject: ghash: Use g_memdup2() instead of g_memdup()
+
+Backport of part of commit 0736b7c1e7cf4232c5d7eb2b0fbfe9be81bd3baa
+to the simpler structure of the GHashTable code in glib-2-58.
+
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
+Bug-Debian: https://bugs.debian.org/982778
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2000
+---
+ glib/ghash.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/glib/ghash.c b/glib/ghash.c
+index 433004c..e36a7a8 100644
+--- a/glib/ghash.c
++++ b/glib/ghash.c
+@@ -34,6 +34,7 @@
+ 
+ #include "glib-private.h"
+ #include "gstrfuncs.h"
++#include "gstrfuncsprivate.h"
+ #include "gatomic.h"
+ #include "gtestutils.h"
+ #include "gslice.h"
+@@ -967,7 +968,7 @@ g_hash_table_insert_node (GHashTable *hash_table,
+    * split the table.
+    */
+   if (G_UNLIKELY (hash_table->keys == hash_table->values && hash_table->keys[node_index] != new_value))
+-    hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size);
++    hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size);
+ 
+   /* Step 3: Actually do the write */
+   hash_table->values[node_index] = new_value;
diff -Nru glib2.0-2.58.3/debian/patches/gio-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch glib2.0-2.58.3/debian/patches/gio-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch
--- glib2.0-2.58.3/debian/patches/gio-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/gio-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,260 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Thu, 4 Feb 2021 13:37:56 +0000
+Subject: gio: Use g_memdup2() instead of g_memdup() in obvious places
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Convert all the call sites which use `g_memdup()`’s length argument
+trivially (for example, by passing a `sizeof()`), so that they use
+`g_memdup2()` instead.
+
+In almost all of these cases the use of `g_memdup()` would not have
+caused problems, but it will soon be deprecated, so best port away from
+it.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
+Bug-Debian: https://bugs.debian.org/982778
+Origin: backport, commit:be8834340a2d928ece82025463ae23dee2c333d0
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2000
+---
+ gio/gdbusconnection.c                 | 5 +++--
+ gio/gdbusinterfaceskeleton.c          | 3 ++-
+ gio/gfile.c                           | 7 ++++---
+ gio/gsettingsschema.c                 | 5 +++--
+ gio/gwin32registrykey.c               | 8 +++++---
+ gio/tests/async-close-output-stream.c | 6 ++++--
+ gio/tests/gdbus-export.c              | 5 +++--
+ gio/win32/gwinhttpfile.c              | 9 +++++----
+ 8 files changed, 29 insertions(+), 19 deletions(-)
+
+diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
+index 7270365..85ed1a3 100644
+--- a/gio/gdbusconnection.c
++++ b/gio/gdbusconnection.c
+@@ -110,6 +110,7 @@
+ #include "gasyncinitable.h"
+ #include "giostream.h"
+ #include "gasyncresult.h"
++#include "gstrfuncsprivate.h"
+ #include "gtask.h"
+ 
+ #ifdef G_OS_UNIX
+@@ -3961,7 +3962,7 @@ _g_dbus_interface_vtable_copy (const GDBusInterfaceVTable *vtable)
+   /* Don't waste memory by copying padding - remember to update this
+    * when changing struct _GDBusInterfaceVTable in gdbusconnection.h
+    */
+-  return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer));
++  return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer));
+ }
+ 
+ static void
+@@ -3978,7 +3979,7 @@ _g_dbus_subtree_vtable_copy (const GDBusSubtreeVTable *vtable)
+   /* Don't waste memory by copying padding - remember to update this
+    * when changing struct _GDBusSubtreeVTable in gdbusconnection.h
+    */
+-  return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer));
++  return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer));
+ }
+ 
+ static void
+diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c
+index 96bd520..672604c 100644
+--- a/gio/gdbusinterfaceskeleton.c
++++ b/gio/gdbusinterfaceskeleton.c
+@@ -27,6 +27,7 @@
+ #include "gdbusprivate.h"
+ #include "gdbusmethodinvocation.h"
+ #include "gdbusconnection.h"
++#include "gstrfuncsprivate.h"
+ #include "gtask.h"
+ #include "gioerror.h"
+ 
+@@ -697,7 +698,7 @@ add_connection_locked (GDBusInterfaceSkeleton *interface_,
+        * properly before building the hooked_vtable, so we create it
+        * once at the last minute.
+        */
+-      interface_->priv->hooked_vtable = g_memdup (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
++      interface_->priv->hooked_vtable = g_memdup2 (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
+       interface_->priv->hooked_vtable->method_call = skeleton_intercept_handle_method_call;
+     }
+ 
+diff --git a/gio/gfile.c b/gio/gfile.c
+index e017ee1..cd362d4 100644
+--- a/gio/gfile.c
++++ b/gio/gfile.c
+@@ -60,6 +60,7 @@
+ #include "gasyncresult.h"
+ #include "gioerror.h"
+ #include "glibintl.h"
++#include "gstrfuncsprivate.h"
+ 
+ 
+ /**
+@@ -7739,7 +7740,7 @@ measure_disk_usage_progress (gboolean reporting,
+   g_main_context_invoke_full (g_task_get_context (task),
+                               g_task_get_priority (task),
+                               measure_disk_usage_invoke_progress,
+-                              g_memdup (&progress, sizeof progress),
++                              g_memdup2 (&progress, sizeof progress),
+                               g_free);
+ }
+ 
+@@ -7757,7 +7758,7 @@ measure_disk_usage_thread (GTask        *task,
+                                  data->progress_callback ? measure_disk_usage_progress : NULL, task,
+                                  &result.disk_usage, &result.num_dirs, &result.num_files,
+                                  &error))
+-    g_task_return_pointer (task, g_memdup (&result, sizeof result), g_free);
++    g_task_return_pointer (task, g_memdup2 (&result, sizeof result), g_free);
+   else
+     g_task_return_error (task, error);
+ }
+@@ -7781,7 +7782,7 @@ g_file_real_measure_disk_usage_async (GFile                        *file,
+ 
+   task = g_task_new (file, cancellable, callback, user_data);
+   g_task_set_source_tag (task, g_file_real_measure_disk_usage_async);
+-  g_task_set_task_data (task, g_memdup (&data, sizeof data), g_free);
++  g_task_set_task_data (task, g_memdup2 (&data, sizeof data), g_free);
+   g_task_set_priority (task, io_priority);
+ 
+   g_task_run_in_thread (task, measure_disk_usage_thread);
+diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
+index 38c9d78..e23dd8c 100644
+--- a/gio/gsettingsschema.c
++++ b/gio/gsettingsschema.c
+@@ -20,6 +20,7 @@
+ 
+ #include "gsettingsschema-internal.h"
+ #include "gsettings.h"
++#include "gstrfuncsprivate.h"
+ 
+ #include "gvdb/gvdb-reader.h"
+ #include "strinfo.c"
+@@ -1057,9 +1058,9 @@ g_settings_schema_list_children (GSettingsSchema *schema)
+ 
+       if (g_str_has_suffix (key, "/"))
+         {
+-          gint length = strlen (key);
++          gsize length = strlen (key);
+ 
+-          strv[j] = g_memdup (key, length);
++          strv[j] = g_memdup2 (key, length);
+           strv[j][length - 1] = '\0';
+           j++;
+         }
+diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c
+index c19fede..619fd48 100644
+--- a/gio/gwin32registrykey.c
++++ b/gio/gwin32registrykey.c
+@@ -28,6 +28,8 @@
+ #include <ntstatus.h>
+ #include <winternl.h>
+ 
++#include "gstrfuncsprivate.h"
++
+ #ifndef _WDMDDK_
+ typedef enum _KEY_INFORMATION_CLASS {
+   KeyBasicInformation,
+@@ -247,7 +249,7 @@ g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter)
+   new_iter->value_name_size = iter->value_name_size;
+ 
+   if (iter->value_data != NULL)
+-    new_iter->value_data = g_memdup (iter->value_data, iter->value_data_size);
++    new_iter->value_data = g_memdup2 (iter->value_data, iter->value_data_size);
+ 
+   new_iter->value_data_size = iter->value_data_size;
+ 
+@@ -268,8 +270,8 @@ g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter)
+   new_iter->value_data_expanded_charsize = iter->value_data_expanded_charsize;
+ 
+   if (iter->value_data_expanded_u8 != NULL)
+-    new_iter->value_data_expanded_u8 = g_memdup (iter->value_data_expanded_u8,
+-                                                 iter->value_data_expanded_charsize);
++    new_iter->value_data_expanded_u8 = g_memdup2 (iter->value_data_expanded_u8,
++                                                  iter->value_data_expanded_charsize);
+ 
+   new_iter->value_data_expanded_u8_size = iter->value_data_expanded_charsize;
+ 
+diff --git a/gio/tests/async-close-output-stream.c b/gio/tests/async-close-output-stream.c
+index 5f66202..d3f97a1 100644
+--- a/gio/tests/async-close-output-stream.c
++++ b/gio/tests/async-close-output-stream.c
+@@ -24,6 +24,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include "gstrfuncsprivate.h"
++
+ #define DATA_TO_WRITE "Hello world\n"
+ 
+ typedef struct
+@@ -147,9 +149,9 @@ prepare_data (SetupData *data,
+ 
+   data->expected_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream));
+ 
+-  g_assert_cmpint (data->expected_size, >, 0);
++  g_assert_cmpuint (data->expected_size, >, 0);
+ 
+-  data->expected_output = g_memdup (written, (guint)data->expected_size);
++  data->expected_output = g_memdup2 (written, data->expected_size);
+ 
+   /* then recreate the streams and prepare them for the asynchronous close */
+   destroy_streams (data);
+diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c
+index 4d6d3a4..544b886 100644
+--- a/gio/tests/gdbus-export.c
++++ b/gio/tests/gdbus-export.c
+@@ -23,6 +23,7 @@
+ #include <string.h>
+ 
+ #include "gdbus-tests.h"
++#include "gstrfuncsprivate.h"
+ 
+ /* all tests rely on a shared mainloop */
+ static GMainLoop *loop = NULL;
+@@ -652,7 +653,7 @@ subtree_introspect (GDBusConnection       *connection,
+       g_assert_not_reached ();
+     }
+ 
+-  return g_memdup (interfaces, 2 * sizeof (void *));
++  return g_memdup2 (interfaces, 2 * sizeof (void *));
+ }
+ 
+ static const GDBusInterfaceVTable *
+@@ -708,7 +709,7 @@ dynamic_subtree_introspect (GDBusConnection       *connection,
+ {
+   const GDBusInterfaceInfo *interfaces[2] = { &dyna_interface_info, NULL };
+ 
+-  return g_memdup (interfaces, 2 * sizeof (void *));
++  return g_memdup2 (interfaces, 2 * sizeof (void *));
+ }
+ 
+ static const GDBusInterfaceVTable *
+diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c
+index d5df16d..f424d21 100644
+--- a/gio/win32/gwinhttpfile.c
++++ b/gio/win32/gwinhttpfile.c
+@@ -29,6 +29,7 @@
+ #include "gio/gfile.h"
+ #include "gio/gfileattribute.h"
+ #include "gio/gfileinfo.h"
++#include "gstrfuncsprivate.h"
+ #include "gwinhttpfile.h"
+ #include "gwinhttpfileinputstream.h"
+ #include "gwinhttpfileoutputstream.h"
+@@ -393,10 +394,10 @@ g_winhttp_file_resolve_relative_path (GFile      *file,
+   child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
+   child->vfs = winhttp_file->vfs;
+   child->url = winhttp_file->url;
+-  child->url.lpszScheme = g_memdup (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
+-  child->url.lpszHostName = g_memdup (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
+-  child->url.lpszUserName = g_memdup (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
+-  child->url.lpszPassword = g_memdup (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
++  child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
++  child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
++  child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
++  child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
+   child->url.lpszUrlPath = wnew_path;
+   child->url.dwUrlPathLength = wcslen (wnew_path);
+   child->url.lpszExtraInfo = NULL;
diff -Nru glib2.0-2.58.3/debian/patches/glib-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch glib2.0-2.58.3/debian/patches/glib-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch
--- glib2.0-2.58.3/debian/patches/glib-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/glib-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,249 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Thu, 4 Feb 2021 13:41:21 +0000
+Subject: glib: Use g_memdup2() instead of g_memdup() in obvious places
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Convert all the call sites which use `g_memdup()`’s length argument
+trivially (for example, by passing a `sizeof()` or an existing `gsize`
+variable), so that they use `g_memdup2()` instead.
+
+In almost all of these cases the use of `g_memdup()` would not have
+caused problems, but it will soon be deprecated, so best port away from
+it
+
+In particular, this fixes an overflow within `g_bytes_new()`, identified
+as GHSL-2021-045 (aka CVE-2021-27219) by GHSL team member Kevin Backhouse.
+
+Adapted for GLib 2.58 by Simon McVittie.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Fixes: CVE-2021-27219
+Fixes: GHSL-2021-045
+[Backport to 2.58: Omit changes to ghash.c, will be a separate commit]
+[Backport to 2.58: Omit changes to giochannel.c, not needed in this branch]
+[Backport to 2.58: Omit changes to uri test, not needed in this branch]
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
+Bug-Debian: https://bugs.debian.org/982778
+Origin: backport, commit:0736b7c1e7cf4232c5d7eb2b0fbfe9be81bd3baa
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2000
+---
+ glib/gbytes.c               | 6 ++++--
+ glib/gdir.c                 | 3 ++-
+ glib/gslice.c               | 3 ++-
+ glib/gtestutils.c           | 3 ++-
+ glib/gvariant.c             | 7 ++++---
+ glib/gvarianttype.c         | 3 ++-
+ glib/tests/array-test.c     | 4 +++-
+ glib/tests/option-context.c | 6 ++++--
+ 8 files changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/glib/gbytes.c b/glib/gbytes.c
+index 7b72886..84c87e4 100644
+--- a/glib/gbytes.c
++++ b/glib/gbytes.c
+@@ -34,6 +34,8 @@
+ 
+ #include <string.h>
+ 
++#include "gstrfuncsprivate.h"
++
+ /**
+  * GBytes:
+  *
+@@ -95,7 +97,7 @@ g_bytes_new (gconstpointer data,
+ {
+   g_return_val_if_fail (data != NULL || size == 0, NULL);
+ 
+-  return g_bytes_new_take (g_memdup (data, size), size);
++  return g_bytes_new_take (g_memdup2 (data, size), size);
+ }
+ 
+ /**
+@@ -499,7 +501,7 @@ g_bytes_unref_to_data (GBytes *bytes,
+        * Copy: Non g_malloc (or compatible) allocator, or static memory,
+        * so we have to copy, and then unref.
+        */
+-      result = g_memdup (bytes->data, bytes->size);
++      result = g_memdup2 (bytes->data, bytes->size);
+       *size = bytes->size;
+       g_bytes_unref (bytes);
+     }
+diff --git a/glib/gdir.c b/glib/gdir.c
+index cb4ad0b..9d955d5 100644
+--- a/glib/gdir.c
++++ b/glib/gdir.c
+@@ -37,6 +37,7 @@
+ #include "gconvert.h"
+ #include "gfileutils.h"
+ #include "gstrfuncs.h"
++#include "gstrfuncsprivate.h"
+ #include "gtestutils.h"
+ #include "glibintl.h"
+ 
+@@ -113,7 +114,7 @@ g_dir_open_with_errno (const gchar *path,
+     return NULL;
+ #endif
+ 
+-  return g_memdup (&dir, sizeof dir);
++  return g_memdup2 (&dir, sizeof dir);
+ }
+ 
+ /**
+diff --git a/glib/gslice.c b/glib/gslice.c
+index d1b1fc6..db3331b 100644
+--- a/glib/gslice.c
++++ b/glib/gslice.c
+@@ -41,6 +41,7 @@
+ #include "gmain.h"
+ #include "gmem.h"               /* gslice.h */
+ #include "gstrfuncs.h"
++#include "gstrfuncsprivate.h"
+ #include "gutils.h"
+ #include "gtrashstack.h"
+ #include "gtestutils.h"
+@@ -349,7 +350,7 @@ g_slice_get_config_state (GSliceConfig ckey,
+       array[i++] = allocator->contention_counters[address];
+       array[i++] = allocator_get_magazine_threshold (allocator, address);
+       *n_values = i;
+-      return g_memdup (array, sizeof (array[0]) * *n_values);
++      return g_memdup2 (array, sizeof (array[0]) * *n_values);
+     default:
+       return NULL;
+     }
+diff --git a/glib/gtestutils.c b/glib/gtestutils.c
+index 7b29c27..f484fd3 100644
+--- a/glib/gtestutils.c
++++ b/glib/gtestutils.c
+@@ -49,6 +49,7 @@
+ #include "gpattern.h"
+ #include "grand.h"
+ #include "gstrfuncs.h"
++#include "gstrfuncsprivate.h"
+ #include "gtimer.h"
+ #include "gslice.h"
+ #include "gspawn.h"
+@@ -3461,7 +3462,7 @@ g_test_log_extract (GTestLogBuffer *tbuffer)
+       if (p <= tbuffer->data->str + mlength)
+         {
+           g_string_erase (tbuffer->data, 0, mlength);
+-          tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg)));
++          tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup2 (&msg, sizeof (msg)));
+           return TRUE;
+         }
+ 
+diff --git a/glib/gvariant.c b/glib/gvariant.c
+index d45b487..de35c3e 100644
+--- a/glib/gvariant.c
++++ b/glib/gvariant.c
+@@ -33,6 +33,7 @@
+ 
+ #include <string.h>
+ 
++#include "gstrfuncsprivate.h"
+ 
+ /**
+  * SECTION:gvariant
+@@ -720,7 +721,7 @@ g_variant_new_variant (GVariant *value)
+   g_variant_ref_sink (value);
+ 
+   return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT,
+-                                      g_memdup (&value, sizeof value),
++                                      g_memdup2 (&value, sizeof value),
+                                       1, g_variant_is_trusted (value));
+ }
+ 
+@@ -1224,7 +1225,7 @@ g_variant_new_fixed_array (const GVariantType  *element_type,
+       return NULL;
+     }
+ 
+-  data = g_memdup (elements, n_elements * element_size);
++  data = g_memdup2 (elements, n_elements * element_size);
+   value = g_variant_new_from_data (array_type, data,
+                                    n_elements * element_size,
+                                    FALSE, g_free, data);
+@@ -1901,7 +1902,7 @@ g_variant_dup_bytestring (GVariant *value,
+   if (length)
+     *length = size;
+ 
+-  return g_memdup (original, size + 1);
++  return g_memdup2 (original, size + 1);
+ }
+ 
+ /**
+diff --git a/glib/gvarianttype.c b/glib/gvarianttype.c
+index f64be97..59ae6aa 100644
+--- a/glib/gvarianttype.c
++++ b/glib/gvarianttype.c
+@@ -28,6 +28,7 @@
+ 
+ #include <string.h>
+ 
++#include "gstrfuncsprivate.h"
+ 
+ /**
+  * SECTION:gvarianttype
+@@ -1177,7 +1178,7 @@ g_variant_type_new_tuple (const GVariantType * const *items,
+   g_assert (offset < sizeof buffer);
+   buffer[offset++] = ')';
+ 
+-  return (GVariantType *) g_memdup (buffer, offset);
++  return (GVariantType *) g_memdup2 (buffer, offset);
+ }
+ 
+ /**
+diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
+index e0a6109..faa6061 100644
+--- a/glib/tests/array-test.c
++++ b/glib/tests/array-test.c
+@@ -30,6 +30,8 @@
+ #include <string.h>
+ #include "glib.h"
+ 
++#include "gstrfuncsprivate.h"
++
+ /* Test data to be passed to any function which calls g_array_new(), providing
+  * the parameters for that call. Most #GArray tests should be repeated for all
+  * possible values of #ArrayTestData. */
+@@ -1177,7 +1179,7 @@ byte_array_new_take (void)
+   GByteArray *gbarray;
+   guint8 *data;
+ 
+-  data = g_memdup ("woooweeewow", 11);
++  data = g_memdup2 ("woooweeewow", 11);
+   gbarray = g_byte_array_new_take (data, 11);
+   g_assert (gbarray->data == data);
+   g_assert_cmpuint (gbarray->len, ==, 11);
+diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c
+index 34ebfaa..7125e22 100644
+--- a/glib/tests/option-context.c
++++ b/glib/tests/option-context.c
+@@ -27,6 +27,8 @@
+ #include <string.h>
+ #include <locale.h>
+ 
++#include "gstrfuncsprivate.h"
++
+ static GOptionEntry main_entries[] = {
+   { "main-switch", 0, 0,
+     G_OPTION_ARG_NONE, NULL,
+@@ -256,7 +258,7 @@ join_stringv (int argc, char **argv)
+ static char **
+ copy_stringv (char **argv, int argc)
+ {
+-  return g_memdup (argv, sizeof (char *) * (argc + 1));
++  return g_memdup2 (argv, sizeof (char *) * (argc + 1));
+ }
+ 
+ static void
+@@ -2318,7 +2320,7 @@ test_group_parse (void)
+   g_option_context_add_group (context, group);
+ 
+   argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc);
+-  orig_argv = g_memdup (argv, (argc + 1) * sizeof (char *));
++  orig_argv = g_memdup2 (argv, (argc + 1) * sizeof (char *));
+ 
+   retval = g_option_context_parse (context, &argc, &argv, &error);
+ 
diff -Nru glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-to-re.patch glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-to-re.patch
--- glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-to-re.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-to-re.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,53 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Wed, 24 Feb 2021 17:42:24 +0000
+Subject: glocalfileoutputstream: Add a missing O_CLOEXEC flag to replace()
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2325
+Bug-Debian: https://bugs.debian.org/984969
+Origin: backport, commit:6c6439261bc7a8a0627519848a7222b3e1bd4ffe
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2002
+---
+ gio/glocalfileoutputstream.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
+index 2be51ae..fff2439 100644
+--- a/gio/glocalfileoutputstream.c
++++ b/gio/glocalfileoutputstream.c
+@@ -56,6 +56,12 @@
+ #define O_BINARY 0
+ #endif
+ 
++#ifndef O_CLOEXEC
++#define O_CLOEXEC 0
++#else
++#define HAVE_O_CLOEXEC 1
++#endif
++
+ struct _GLocalFileOutputStreamPrivate {
+   char *tmp_filename;
+   char *original_filename;
+@@ -1123,7 +1129,7 @@ _g_local_file_output_stream_replace (const char        *filename,
+   sync_on_close = FALSE;
+ 
+   /* If the file doesn't exist, create it */
+-  open_flags = O_CREAT | O_EXCL | O_BINARY;
++  open_flags = O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC;
+   if (readable)
+     open_flags |= O_RDWR;
+   else
+@@ -1153,8 +1159,11 @@ _g_local_file_output_stream_replace (const char        *filename,
+       set_error_from_open_errno (filename, error);
+       return NULL;
+     }
+-  
+- 
++#if !defined(HAVE_O_CLOEXEC) && defined(F_SETFD)
++  else
++    fcntl (fd, F_SETFD, FD_CLOEXEC);
++#endif
++
+   stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
+   stream->priv->fd = fd;
+   stream->priv->sync_on_close = sync_on_close;
diff -Nru glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Factor-out-a-flag-check.patch glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Factor-out-a-flag-check.patch
--- glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Factor-out-a-flag-check.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Factor-out-a-flag-check.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,54 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Wed, 10 Mar 2021 16:05:55 +0000
+Subject: glocalfileoutputstream: Factor out a flag check
+
+This clarifies the code a little. It introduces no functional changes.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2325
+Bug-Debian: https://bugs.debian.org/984969
+Origin: backport, commit:ce0eb088a68171eed3ac217cb92a72e36eb57d1b
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2002
+---
+ gio/glocalfileoutputstream.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
+index 8a68be3..8e0e793 100644
+--- a/gio/glocalfileoutputstream.c
++++ b/gio/glocalfileoutputstream.c
+@@ -751,6 +751,7 @@ handle_overwrite_open (const char    *filename,
+   int res;
+   int mode;
+   int errsv;
++  gboolean replace_destination_set = (flags & G_FILE_CREATE_REPLACE_DESTINATION);
+ 
+   mode = mode_from_flags_or_info (flags, reference_info);
+ 
+@@ -858,7 +859,7 @@ handle_overwrite_open (const char    *filename,
+    * to a backup file and rewrite the contents of the file.
+    */
+   
+-  if ((flags & G_FILE_CREATE_REPLACE_DESTINATION) ||
++  if (replace_destination_set ||
+       (!(original_stat.st_nlink > 1) && !is_symlink))
+     {
+       char *dirname, *tmp_filename;
+@@ -877,7 +878,7 @@ handle_overwrite_open (const char    *filename,
+       
+       /* try to keep permissions (unless replacing) */
+ 
+-      if ( ! (flags & G_FILE_CREATE_REPLACE_DESTINATION) &&
++      if (!replace_destination_set &&
+ 	   (
+ #ifdef HAVE_FCHOWN
+ 	    fchown (tmpfd, original_stat.st_uid, original_stat.st_gid) == -1 ||
+@@ -1016,7 +1017,7 @@ handle_overwrite_open (const char    *filename,
+ 	}
+     }
+ 
+-  if (flags & G_FILE_CREATE_REPLACE_DESTINATION)
++  if (replace_destination_set)
+     {
+       g_close (fd, NULL);
+       
diff -Nru glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Fix-a-typo-in-a-comment.patch glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Fix-a-typo-in-a-comment.patch
--- glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Fix-a-typo-in-a-comment.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Fix-a-typo-in-a-comment.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,26 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Wed, 24 Feb 2021 17:33:38 +0000
+Subject: glocalfileoutputstream: Fix a typo in a comment
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2325
+Bug-Debian: https://bugs.debian.org/984969
+Origin: backport, commit:78420a75aeb70569a8cd79fa0fea7b786b6f785f
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2002
+---
+ gio/glocalfileoutputstream.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
+index 57d2d5d..8a68be3 100644
+--- a/gio/glocalfileoutputstream.c
++++ b/gio/glocalfileoutputstream.c
+@@ -755,7 +755,7 @@ handle_overwrite_open (const char    *filename,
+   mode = mode_from_flags_or_info (flags, reference_info);
+ 
+   /* We only need read access to the original file if we are creating a backup.
+-   * We also add O_CREATE to avoid a race if the file was just removed */
++   * We also add O_CREAT to avoid a race if the file was just removed */
+   if (create_backup || readable)
+     open_flags = O_RDWR | O_CREAT | O_BINARY;
+   else
diff -Nru glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATION-wit.patch glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATION-wit.patch
--- glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATION-wit.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATION-wit.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,264 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Wed, 24 Feb 2021 17:36:07 +0000
+Subject: glocalfileoutputstream: Fix CREATE_REPLACE_DESTINATION with symlinks
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+The `G_FILE_CREATE_REPLACE_DESTINATION` flag is equivalent to unlinking
+the destination file and re-creating it from scratch. That did
+previously work, but in the process the code would call `open(O_CREAT)`
+on the file. If the file was a dangling symlink, this would create the
+destination file (empty). That’s not an intended side-effect, and has
+security implications if the symlink is controlled by a lower-privileged
+process.
+
+Fix that by not opening the destination file if it’s a symlink, and
+adjusting the rest of the code to cope with
+ - the fact that `fd == -1` is not an error iff `is_symlink` is true,
+ - and that `original_stat` will contain the `lstat()` results for the
+   symlink now, rather than the `stat()` results for its target (again,
+   iff `is_symlink` is true).
+
+This means that the target of the dangling symlink is no longer created,
+which was the bug. The symlink itself continues to be replaced (as
+before) with the new file — this is the intended behaviour of
+`g_file_replace()`.
+
+The behaviour for non-symlink cases, or cases where the symlink was not
+dangling, should be unchanged.
+
+Includes a unit test.
+
+Resolves CVE-2021-28153 (glib#2325). Backported to GLib 2.58 by
+Simon McVittie.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+[Backport to 2.58.x: replace g_local_file_fstat with fstat]
+[Backport to 2.58.x: replace g_local_file_lstat with lstat]
+[Backport to 2.58.x: replace _g_stat_mode with direct access to st_mode]
+[Backport to 2.58.x: don't call g_test_summary()]
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2325
+Bug-Debian: https://bugs.debian.org/984969
+Origin: backport, commit:317b3b587058a05dca95d56dac26568c5b098d33
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2002
+---
+ gio/glocalfileoutputstream.c |  49 ++++++++++++++------
+ gio/tests/file.c             | 107 +++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 142 insertions(+), 14 deletions(-)
+
+diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
+index 8e0e793..2be51ae 100644
+--- a/gio/glocalfileoutputstream.c
++++ b/gio/glocalfileoutputstream.c
+@@ -779,16 +779,22 @@ handle_overwrite_open (const char    *filename,
+       /* Could be a symlink, or it could be a regular ELOOP error,
+        * but then the next open will fail too. */
+       is_symlink = TRUE;
+-      fd = g_open (filename, open_flags, mode);
++      if (!replace_destination_set)
++        fd = g_open (filename, open_flags, mode);
+     }
+-#else
+-  fd = g_open (filename, open_flags, mode);
+-  errsv = errno;
++#else  /* if !O_NOFOLLOW */
+   /* This is racy, but we do it as soon as possible to minimize the race */
+   is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK);
++
++  if (!is_symlink || !replace_destination_set)
++    {
++      fd = g_open (filename, open_flags, mode);
++      errsv = errno;
++    }
+ #endif
+ 
+-  if (fd == -1)
++  if (fd == -1 &&
++      (!is_symlink || !replace_destination_set))
+     {
+       char *display_name = g_filename_display_name (filename);
+       g_set_error (error, G_IO_ERROR,
+@@ -802,7 +808,10 @@ handle_overwrite_open (const char    *filename,
+ #ifdef G_OS_WIN32
+   res = GLIB_PRIVATE_CALL (g_win32_fstat) (fd, &original_stat);
+ #else
+-  res = fstat (fd, &original_stat);
++  if (!is_symlink)
++    res = fstat (fd, &original_stat);
++  else
++    res = lstat (filename, &original_stat);
+ #endif
+   errsv = errno;
+ 
+@@ -821,16 +830,27 @@ handle_overwrite_open (const char    *filename,
+   if (!S_ISREG (original_stat.st_mode))
+     {
+       if (S_ISDIR (original_stat.st_mode))
+-	g_set_error_literal (error,
+-                             G_IO_ERROR,
+-                             G_IO_ERROR_IS_DIRECTORY,
+-                             _("Target file is a directory"));
+-      else
+-	g_set_error_literal (error,
++        {
++          g_set_error_literal (error,
++                               G_IO_ERROR,
++                               G_IO_ERROR_IS_DIRECTORY,
++                               _("Target file is a directory"));
++          goto err_out;
++        }
++      else if (!is_symlink ||
++#ifdef S_ISLNK
++               !S_ISLNK (original_stat.st_mode)
++#else
++               FALSE
++#endif
++               )
++        {
++          g_set_error_literal (error,
+                              G_IO_ERROR,
+                              G_IO_ERROR_NOT_REGULAR_FILE,
+                              _("Target file is not a regular file"));
+-      goto err_out;
++          goto err_out;
++        }
+     }
+   
+   if (etag != NULL)
+@@ -911,7 +931,8 @@ handle_overwrite_open (const char    *filename,
+ 	    }
+ 	}
+ 
+-      g_close (fd, NULL);
++      if (fd >= 0)
++        g_close (fd, NULL);
+       *temp_filename = tmp_filename;
+       return tmpfd;
+     }
+diff --git a/gio/tests/file.c b/gio/tests/file.c
+index 9c2af64..1bdbe19 100644
+--- a/gio/tests/file.c
++++ b/gio/tests/file.c
+@@ -787,6 +787,112 @@ test_replace_cancel (void)
+   g_object_unref (tmpdir);
+ }
+ 
++static void
++test_replace_symlink (void)
++{
++#ifdef G_OS_UNIX
++  gchar *tmpdir_path = NULL;
++  GFile *tmpdir = NULL, *source_file = NULL, *target_file = NULL;
++  GFileOutputStream *stream = NULL;
++  const gchar *new_contents = "this is a test message which should be written to source and not target";
++  gsize n_written;
++  GFileEnumerator *enumerator = NULL;
++  GFileInfo *info = NULL;
++  gchar *contents = NULL;
++  gsize length = 0;
++  GError *local_error = NULL;
++
++  g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2325";);
++
++  /* Create a fresh, empty working directory. */
++  tmpdir_path = g_dir_make_tmp ("g_file_replace_symlink_XXXXXX", &local_error);
++  g_assert_no_error (local_error);
++  tmpdir = g_file_new_for_path (tmpdir_path);
++
++  g_test_message ("Using temporary directory %s", tmpdir_path);
++  g_free (tmpdir_path);
++
++  /* Create symlink `source` which points to `target`. */
++  source_file = g_file_get_child (tmpdir, "source");
++  target_file = g_file_get_child (tmpdir, "target");
++  g_file_make_symbolic_link (source_file, "target", NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  /* Ensure that `target` doesn’t exist */
++  g_assert_false (g_file_query_exists (target_file, NULL));
++
++  /* Replace the `source` symlink with a regular file using
++   * %G_FILE_CREATE_REPLACE_DESTINATION, which should replace it *without*
++   * following the symlink */
++  stream = g_file_replace (source_file, NULL, FALSE  /* no backup */,
++                           G_FILE_CREATE_REPLACE_DESTINATION, NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  g_output_stream_write_all (G_OUTPUT_STREAM (stream), new_contents, strlen (new_contents),
++                             &n_written, NULL, &local_error);
++  g_assert_no_error (local_error);
++  g_assert_cmpint (n_written, ==, strlen (new_contents));
++
++  g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  g_clear_object (&stream);
++
++  /* At this point, there should still only be one file: `source`. It should
++   * now be a regular file. `target` should not exist. */
++  enumerator = g_file_enumerate_children (tmpdir,
++                                          G_FILE_ATTRIBUTE_STANDARD_NAME ","
++                                          G_FILE_ATTRIBUTE_STANDARD_TYPE,
++                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  info = g_file_enumerator_next_file (enumerator, NULL, &local_error);
++  g_assert_no_error (local_error);
++  g_assert_nonnull (info);
++
++  g_assert_cmpstr (g_file_info_get_name (info), ==, "source");
++  g_assert_cmpint (g_file_info_get_file_type (info), ==, G_FILE_TYPE_REGULAR);
++
++  g_clear_object (&info);
++
++  info = g_file_enumerator_next_file (enumerator, NULL, &local_error);
++  g_assert_no_error (local_error);
++  g_assert_null (info);
++
++  g_file_enumerator_close (enumerator, NULL, &local_error);
++  g_assert_no_error (local_error);
++  g_clear_object (&enumerator);
++
++  /* Double-check that `target` doesn’t exist */
++  g_assert_false (g_file_query_exists (target_file, NULL));
++
++  /* Check the content of `source`. */
++  g_file_load_contents (source_file,
++                        NULL,
++                        &contents,
++                        &length,
++                        NULL,
++                        &local_error);
++  g_assert_no_error (local_error);
++  g_assert_cmpstr (contents, ==, new_contents);
++  g_assert_cmpuint (length, ==, strlen (new_contents));
++  g_free (contents);
++
++  /* Tidy up. */
++  g_file_delete (source_file, NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  g_file_delete (tmpdir, NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  g_clear_object (&target_file);
++  g_clear_object (&source_file);
++  g_clear_object (&tmpdir);
++#else  /* if !G_OS_UNIX */
++  g_test_skip ("Symlink replacement tests can only be run on Unix")
++#endif
++}
++
+ static void
+ on_file_deleted (GObject      *object,
+ 		 GAsyncResult *result,
+@@ -1182,6 +1288,7 @@ main (int argc, char *argv[])
+   g_test_add_data_func ("/file/async-create-delete/4096", GINT_TO_POINTER (4096), test_create_delete);
+   g_test_add_func ("/file/replace-load", test_replace_load);
+   g_test_add_func ("/file/replace-cancel", test_replace_cancel);
++  g_test_add_func ("/file/replace-symlink", test_replace_symlink);
+   g_test_add_func ("/file/async-delete", test_async_delete);
+ #ifdef G_OS_UNIX
+   g_test_add_func ("/file/copy-preserve-mode", test_copy_preserve_mode);
diff -Nru glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Tidy-up-error-handling.patch glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Tidy-up-error-handling.patch
--- glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Tidy-up-error-handling.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/glocalfileoutputstream-Tidy-up-error-handling.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,156 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Tue, 16 Mar 2021 11:36:27 +0000
+Subject: glocalfileoutputstream: Tidy up error handling
+
+After the recent reworking of this code it was possible for `g_close()`
+to be called on `fd == -1`, which is invalid. It would have reported an
+error, were errors not ignored. So it was harmless, but still best to
+fix.
+
+Simplify the error handling by combining both error labels and checking
+the state of `fd` dynamically.
+
+Coverity CID: #1450834
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2325
+Bug-Debian: https://bugs.debian.org/984969
+Origin: backport, commit:c4b4fecaef5fa6eac63569513511ba6f8674548a
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2002
+---
+ gio/glocalfileoutputstream.c | 33 +++++++++++++++++----------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
+index fff2439..8d7eadd 100644
+--- a/gio/glocalfileoutputstream.c
++++ b/gio/glocalfileoutputstream.c
+@@ -829,7 +829,7 @@ handle_overwrite_open (const char    *filename,
+ 		   _("Error when getting information for file “%s”: %s"),
+ 		   display_name, g_strerror (errsv));
+       g_free (display_name);
+-      goto err_out;
++      goto error;
+     }
+   
+   /* not a regular file */
+@@ -841,7 +841,7 @@ handle_overwrite_open (const char    *filename,
+                                G_IO_ERROR,
+                                G_IO_ERROR_IS_DIRECTORY,
+                                _("Target file is a directory"));
+-          goto err_out;
++          goto error;
+         }
+       else if (!is_symlink ||
+ #ifdef S_ISLNK
+@@ -855,7 +855,7 @@ handle_overwrite_open (const char    *filename,
+                              G_IO_ERROR,
+                              G_IO_ERROR_NOT_REGULAR_FILE,
+                              _("Target file is not a regular file"));
+-          goto err_out;
++          goto error;
+         }
+     }
+   
+@@ -869,7 +869,7 @@ handle_overwrite_open (const char    *filename,
+                                G_IO_ERROR_WRONG_ETAG,
+                                _("The file was externally modified"));
+ 	  g_free (current_etag);
+-	  goto err_out;
++          goto error;
+ 	}
+       g_free (current_etag);
+     }
+@@ -962,7 +962,7 @@ handle_overwrite_open (const char    *filename,
+                                G_IO_ERROR_CANT_CREATE_BACKUP,
+                                _("Backup file creation failed"));
+ 	  g_free (backup_filename);
+-	  goto err_out;
++          goto error;
+ 	}
+ 
+       bfd = g_open (backup_filename,
+@@ -976,7 +976,7 @@ handle_overwrite_open (const char    *filename,
+                                G_IO_ERROR_CANT_CREATE_BACKUP,
+                                _("Backup file creation failed"));
+ 	  g_free (backup_filename);
+-	  goto err_out;
++          goto error;
+ 	}
+ 
+       /* If needed, Try to set the group of the backup same as the
+@@ -993,7 +993,7 @@ handle_overwrite_open (const char    *filename,
+ 	  g_unlink (backup_filename);
+ 	  g_close (bfd, NULL);
+ 	  g_free (backup_filename);
+-	  goto err_out;
++          goto error;
+ 	}
+       
+       if ((original_stat.st_gid != tmp_statbuf.st_gid)  &&
+@@ -1010,7 +1010,7 @@ handle_overwrite_open (const char    *filename,
+ 	      g_unlink (backup_filename);
+ 	      g_close (bfd, NULL);
+ 	      g_free (backup_filename);
+-	      goto err_out;
++              goto error;
+ 	    }
+ 	}
+ #endif
+@@ -1025,7 +1025,7 @@ handle_overwrite_open (const char    *filename,
+           g_close (bfd, NULL);
+ 	  g_free (backup_filename);
+ 	  
+-	  goto err_out;
++          goto error;
+ 	}
+       
+       g_close (bfd, NULL);
+@@ -1040,7 +1040,7 @@ handle_overwrite_open (const char    *filename,
+ 		       g_io_error_from_errno (errsv),
+ 		       _("Error seeking in file: %s"),
+ 		       g_strerror (errsv));
+-	  goto err_out;
++          goto error;
+ 	}
+     }
+ 
+@@ -1056,7 +1056,7 @@ handle_overwrite_open (const char    *filename,
+ 		       g_io_error_from_errno (errsv),
+ 		       _("Error removing old file: %s"),
+ 		       g_strerror (errsv));
+-	  goto err_out2;
++          goto error;
+ 	}
+ 
+       if (readable)
+@@ -1073,7 +1073,7 @@ handle_overwrite_open (const char    *filename,
+ 		       _("Error opening file “%s”: %s"),
+ 		       display_name, g_strerror (errsv));
+ 	  g_free (display_name);
+-	  goto err_out2;
++          goto error;
+ 	}
+     }
+   else
+@@ -1091,15 +1091,16 @@ handle_overwrite_open (const char    *filename,
+ 			 g_io_error_from_errno (errsv),
+ 			 _("Error truncating file: %s"),
+ 			 g_strerror (errsv));
+-	    goto err_out;
++            goto error;
+ 	  }
+     }
+     
+   return fd;
+ 
+- err_out:
+-  g_close (fd, NULL);
+- err_out2:
++error:
++  if (fd >= 0)
++    g_close (fd, NULL);
++
+   return -1;
+ }
+ 
diff -Nru glib2.0-2.58.3/debian/patches/gobject-Use-g_memdup2-instead-of-g_memdup-in-obvious-plac.patch glib2.0-2.58.3/debian/patches/gobject-Use-g_memdup2-instead-of-g_memdup-in-obvious-plac.patch
--- glib2.0-2.58.3/debian/patches/gobject-Use-g_memdup2-instead-of-g_memdup-in-obvious-plac.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/gobject-Use-g_memdup2-instead-of-g_memdup-in-obvious-plac.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,134 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Thu, 4 Feb 2021 13:39:25 +0000
+Subject: gobject: Use g_memdup2() instead of g_memdup() in obvious places
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Convert all the call sites which use `g_memdup()`’s length argument
+trivially (for example, by passing a `sizeof()`), so that they use
+`g_memdup2()` instead.
+
+In almost all of these cases the use of `g_memdup()` would not have
+caused problems, but it will soon be deprecated, so best port away from
+it.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
+Bug-Debian: https://bugs.debian.org/982778
+Origin: backport, commit:6110caea45b235420b98cd41d845cc92238f6781
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2000
+---
+ gobject/gsignal.c     | 3 ++-
+ gobject/gtype.c       | 9 +++++----
+ gobject/gtypemodule.c | 3 ++-
+ gobject/tests/param.c | 4 +++-
+ 4 files changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/gobject/gsignal.c b/gobject/gsignal.c
+index 76f1dc9..4296eb2 100644
+--- a/gobject/gsignal.c
++++ b/gobject/gsignal.c
+@@ -28,6 +28,7 @@
+ #include <signal.h>
+ 
+ #include "gsignal.h"
++#include "gstrfuncsprivate.h"
+ #include "gtype-private.h"
+ #include "gbsearcharray.h"
+ #include "gvaluecollector.h"
+@@ -1724,7 +1725,7 @@ g_signal_newv (const gchar       *signal_name,
+   node->single_va_closure_is_valid = FALSE;
+   node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
+   node->n_params = n_params;
+-  node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
++  node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params);
+   node->return_type = return_type;
+   node->class_closure_bsa = NULL;
+   if (accumulator)
+diff --git a/gobject/gtype.c b/gobject/gtype.c
+index 1acc0a0..bee83bd 100644
+--- a/gobject/gtype.c
++++ b/gobject/gtype.c
+@@ -33,6 +33,7 @@
+ 
+ #include "glib-private.h"
+ #include "gconstructor.h"
++#include "gstrfuncsprivate.h"
+ 
+ #ifdef G_OS_WIN32
+ #include <windows.h>
+@@ -1467,7 +1468,7 @@ type_add_interface_Wm (TypeNode             *node,
+   iholder->next = iface_node_get_holders_L (iface);
+   iface_node_set_holders_W (iface, iholder);
+   iholder->instance_type = NODE_TYPE (node);
+-  iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
++  iholder->info = info ? g_memdup2 (info, sizeof (*info)) : NULL;
+   iholder->plugin = plugin;
+ 
+   /* create an iface entry for this type */
+@@ -1728,7 +1729,7 @@ type_iface_retrieve_holder_info_Wm (TypeNode *iface,
+         INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface));
+       
+       check_interface_info_I (iface, instance_type, &tmp_info);
+-      iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
++      iholder->info = g_memdup2 (&tmp_info, sizeof (tmp_info));
+     }
+   
+   return iholder;	/* we don't modify write lock upon returning NULL */
+@@ -2013,10 +2014,10 @@ type_iface_vtable_base_init_Wm (TypeNode *iface,
+       IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);
+       
+       if (pentry)
+-	vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size);
++	vtable = g_memdup2 (pentry->vtable, iface->data->iface.vtable_size);
+     }
+   if (!vtable)
+-    vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
++    vtable = g_memdup2 (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
+   entry->vtable = vtable;
+   vtable->g_type = NODE_TYPE (iface);
+   vtable->g_instance_type = NODE_TYPE (node);
+diff --git a/gobject/gtypemodule.c b/gobject/gtypemodule.c
+index 4ecaf8c..20911fa 100644
+--- a/gobject/gtypemodule.c
++++ b/gobject/gtypemodule.c
+@@ -19,6 +19,7 @@
+ 
+ #include <stdlib.h>
+ 
++#include "gstrfuncsprivate.h"
+ #include "gtypeplugin.h"
+ #include "gtypemodule.h"
+ 
+@@ -436,7 +437,7 @@ g_type_module_register_type (GTypeModule     *module,
+   module_type_info->loaded = TRUE;
+   module_type_info->info = *type_info;
+   if (type_info->value_table)
+-    module_type_info->info.value_table = g_memdup (type_info->value_table,
++    module_type_info->info.value_table = g_memdup2 (type_info->value_table,
+ 						   sizeof (GTypeValueTable));
+ 
+   return module_type_info->type;
+diff --git a/gobject/tests/param.c b/gobject/tests/param.c
+index 758289b..971cff1 100644
+--- a/gobject/tests/param.c
++++ b/gobject/tests/param.c
+@@ -2,6 +2,8 @@
+ #include <glib-object.h>
+ #include <stdlib.h>
+ 
++#include "gstrfuncsprivate.h"
++
+ static void
+ test_param_value (void)
+ {
+@@ -851,7 +853,7 @@ main (int argc, char *argv[])
+             test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
+                                          data.change_this_flag, data.change_this_type,
+                                          data.use_this_flag, data.use_this_type);
+-            test_data = g_memdup (&data, sizeof (TestParamImplementData));
++            test_data = g_memdup2 (&data, sizeof (TestParamImplementData));
+             g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free);
+             g_free (test_path);
+           }
diff -Nru glib2.0-2.58.3/debian/patches/gstrfuncs-Add-internal-g_memdup2-function.patch glib2.0-2.58.3/debian/patches/gstrfuncs-Add-internal-g_memdup2-function.patch
--- glib2.0-2.58.3/debian/patches/gstrfuncs-Add-internal-g_memdup2-function.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/gstrfuncs-Add-internal-g_memdup2-function.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,173 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Thu, 4 Feb 2021 13:30:52 +0000
+Subject: gstrfuncs: Add internal g_memdup2() function
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+This will replace the existing `g_memdup()` function for use within
+GLib. It has an unavoidable security flaw of taking its `byte_size`
+argument as a `guint` rather than as a `gsize`. Most callers will
+expect it to be a `gsize`, and may pass in large values which could
+silently be truncated, resulting in an undersize allocation compared
+to what the caller expects.
+
+This could lead to a classic buffer overflow vulnerability for many
+callers of `g_memdup()`.
+
+`g_memdup2()`, in comparison, takes its `byte_size` as a `gsize`.
+
+Spotted by Kevin Backhouse of GHSL.
+
+In GLib 2.68, `g_memdup2()` will be a new public API. In this version
+for backport to older stable releases, it’s a new `static inline` API
+in a private header, so that use of `g_memdup()` within GLib can be
+fixed without adding a new API in a stable release series.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Helps: CVE-2021-27219
+Helps: GHSL-2021-045
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
+Bug-Debian: https://bugs.debian.org/982778
+Origin: backport, commit:5e5f75a77e399c638be66d74e5daa8caeb433e00
+---
+ docs/reference/glib/meson.build |  1 +
+ glib/gstrfuncsprivate.h         | 55 +++++++++++++++++++++++++++++++++++++++++
+ glib/meson.build                |  1 +
+ glib/tests/strfuncs.c           | 23 +++++++++++++++++
+ 4 files changed, 80 insertions(+)
+ create mode 100644 glib/gstrfuncsprivate.h
+
+diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build
+index f14824b..f0b0cb5 100644
+--- a/docs/reference/glib/meson.build
++++ b/docs/reference/glib/meson.build
+@@ -20,6 +20,7 @@ if get_option('gtk_doc')
+     'gprintfint.h',
+     'gmirroringtable.h',
+     'gscripttable.h',
++    'gstrfuncsprivate.h',
+     'glib-mirroring-tab',
+     'gnulib',
+     'pcre',
+diff --git a/glib/gstrfuncsprivate.h b/glib/gstrfuncsprivate.h
+new file mode 100644
+index 0000000..85c8832
+--- /dev/null
++++ b/glib/gstrfuncsprivate.h
+@@ -0,0 +1,55 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <glib.h>
++#include <string.h>
++
++/*
++ * g_memdup2:
++ * @mem: (nullable): the memory to copy.
++ * @byte_size: the number of bytes to copy.
++ *
++ * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it
++ * from @mem. If @mem is %NULL it returns %NULL.
++ *
++ * This replaces g_memdup(), which was prone to integer overflows when
++ * converting the argument from a #gsize to a #guint.
++ *
++ * This static inline version is a backport of the new public API from
++ * GLib 2.68, kept internal to GLib for backport to older stable releases.
++ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2319.
++ *
++ * Returns: (nullable): a pointer to the newly-allocated copy of the memory,
++ *    or %NULL if @mem is %NULL.
++ * Since: 2.68
++ */
++static inline gpointer
++g_memdup2 (gconstpointer mem,
++           gsize         byte_size)
++{
++  gpointer new_mem;
++
++  if (mem && byte_size != 0)
++    {
++      new_mem = g_malloc (byte_size);
++      memcpy (new_mem, mem, byte_size);
++    }
++  else
++    new_mem = NULL;
++
++  return new_mem;
++}
+diff --git a/glib/meson.build b/glib/meson.build
+index 6fc56da..dcbd20e 100644
+--- a/glib/meson.build
++++ b/glib/meson.build
+@@ -182,6 +182,7 @@ glib_sources = files(
+   'gslist.c',
+   'gstdio.c',
+   'gstrfuncs.c',
++  'gstrfuncsprivate.h',
+   'gstring.c',
+   'gstringchunk.c',
+   'gtestutils.c',
+diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c
+index d974ad4..1111226 100644
+--- a/glib/tests/strfuncs.c
++++ b/glib/tests/strfuncs.c
+@@ -32,6 +32,8 @@
+ #include <string.h>
+ #include "glib.h"
+ 
++#include "gstrfuncsprivate.h"
++
+ #if defined (_MSC_VER) && (_MSC_VER <= 1800)
+ #define isnan(x) _isnan(x)
+ 
+@@ -199,6 +201,26 @@ test_is_to_digit (void)
+   #undef TEST_DIGIT
+ }
+ 
++/* Testing g_memdup2() function with various positive and negative cases */
++static void
++test_memdup2 (void)
++{
++  gchar *str_dup = NULL;
++  const gchar *str = "The quick brown fox jumps over the lazy dog";
++
++  /* Testing negative cases */
++  g_assert_null (g_memdup2 (NULL, 1024));
++  g_assert_null (g_memdup2 (str, 0));
++  g_assert_null (g_memdup2 (NULL, 0));
++
++  /* Testing normal usage cases */
++  str_dup = g_memdup2 (str, strlen (str) + 1);
++  g_assert_nonnull (str_dup);
++  g_assert_cmpstr (str, ==, str_dup);
++
++  g_free (str_dup);
++}
++
+ static void
+ test_strdup (void)
+ {
+@@ -1731,6 +1753,7 @@ main (int   argc,
+   g_test_init (&argc, &argv, NULL);
+ 
+   g_test_add_func ("/strfuncs/test-is-to-digit", test_is_to_digit);
++  g_test_add_func ("/strfuncs/memdup2", test_memdup2);
+   g_test_add_func ("/strfuncs/strdup", test_strdup);
+   g_test_add_func ("/strfuncs/strndup", test_strndup);
+   g_test_add_func ("/strfuncs/strdup-printf", test_strdup_printf);
diff -Nru glib2.0-2.58.3/debian/patches/gvariant-test-Use-g_memdup2.patch glib2.0-2.58.3/debian/patches/gvariant-test-Use-g_memdup2.patch
--- glib2.0-2.58.3/debian/patches/gvariant-test-Use-g_memdup2.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/gvariant-test-Use-g_memdup2.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,64 @@
+From: Simon McVittie <smcv@collabora.com>
+Date: Thu, 18 Mar 2021 10:33:32 +0000
+Subject: gvariant test: Use g_memdup2
+
+This code no longer existed on the glib-2-66 branch, but it's present
+in glib-2-58. It's easier to verify that all potentially problematic
+g_memdup() uses have been replaced if we replace these too.
+
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
+Bug-Debian: https://bugs.debian.org/982778
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2000
+---
+ glib/tests/gvariant.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
+index 18800f9..e6ac324 100644
+--- a/glib/tests/gvariant.c
++++ b/glib/tests/gvariant.c
+@@ -17,6 +17,7 @@
+ #include <string.h>
+ #include <stdlib.h>
+ #include <glib.h>
++#include "gstrfuncsprivate.h"
+ 
+ #define BASIC "bynqiuxthdsog?"
+ #define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
+@@ -4779,7 +4780,7 @@ test_normal_checking_tuples (void)
+   GVariant *variant = NULL;
+   GVariant *normal_variant = NULL;
+ 
+-  aligned_data = g_memdup (data, size); /* guarantee alignment */
++  aligned_data = g_memdup2 (data, size); /* guarantee alignment */
+   variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size,
+                                      FALSE, NULL, NULL);
+   g_assert_nonnull (variant);
+@@ -4908,7 +4909,7 @@ test_normal_checking_array_offsets (void)
+   GVariant *variant = NULL;
+   GVariant *normal_variant = NULL;
+ 
+-  aligned_data = g_memdup (data, size); /* guarantee alignment */
++  aligned_data = g_memdup2 (data, size); /* guarantee alignment */
+   variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size,
+                                      FALSE, NULL, NULL);
+   g_assert_nonnull (variant);
+@@ -4935,7 +4936,7 @@ test_normal_checking_tuple_offsets (void)
+   GVariant *variant = NULL;
+   GVariant *normal_variant = NULL;
+ 
+-  aligned_data = g_memdup (data, size); /* guarantee alignment */
++  aligned_data = g_memdup2 (data, size); /* guarantee alignment */
+   variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data,
+                                      size, FALSE, NULL, NULL);
+   g_assert_nonnull (variant);
+@@ -4962,7 +4963,7 @@ test_normal_checking_empty_object_path (void)
+   GVariant *variant = NULL;
+   GVariant *normal_variant = NULL;
+ 
+-  aligned_data = g_memdup (data, size); /* guarantee alignment */
++  aligned_data = g_memdup2 (data, size); /* guarantee alignment */
+   variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size,
+                                      FALSE, NULL, NULL);
+   g_assert_nonnull (variant);
diff -Nru glib2.0-2.58.3/debian/patches/gwin32-Use-gsize-internally-in-g_wcsdup.patch glib2.0-2.58.3/debian/patches/gwin32-Use-gsize-internally-in-g_wcsdup.patch
--- glib2.0-2.58.3/debian/patches/gwin32-Use-gsize-internally-in-g_wcsdup.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/gwin32-Use-gsize-internally-in-g_wcsdup.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,52 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Thu, 4 Feb 2021 13:50:37 +0000
+Subject: gwin32: Use gsize internally in g_wcsdup()
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+This allows it to handle strings up to length `G_MAXSIZE` — previously
+it would overflow with such strings.
+
+Update the several copies of it identically.
+
+Adapted for GLib 2.58 by Simon McVittie.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+[Backport to 2.58 branch: g_wcsdup() existed in different places]
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
+Bug-Debian: https://bugs.debian.org/982778
+Origin: backport, commit:9acebef777f4a669819155d844f5dd75a38fdbc8
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2000
+---
+ gio/gwin32appinfo.c     | 2 +-
+ gio/gwin32registrykey.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gio/gwin32appinfo.c b/gio/gwin32appinfo.c
+index 9f335b3..2a0fe38 100644
+--- a/gio/gwin32appinfo.c
++++ b/gio/gwin32appinfo.c
+@@ -472,7 +472,7 @@ g_wcsdup (const gunichar2 *str, gssize str_size)
+       str_size = wcslen (str) + 1;
+       str_size *= sizeof (gunichar2);
+     }
+-  return g_memdup (str, str_size);
++  return g_memdup2 (str, str_size);
+ }
+ 
+ #define URL_ASSOCIATIONS L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\"
+diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c
+index 619fd48..1c55263 100644
+--- a/gio/gwin32registrykey.c
++++ b/gio/gwin32registrykey.c
+@@ -136,7 +136,7 @@ g_wcsdup (const gunichar2 *str,
+       str_size = wcslen (str) + 1;
+       str_size *= sizeof (gunichar2);
+     }
+-  return g_memdup (str, str_size);
++  return g_memdup2 (str, str_size);
+ }
+ 
+ /**
diff -Nru glib2.0-2.58.3/debian/patches/gwinhttpfile-Avoid-arithmetic-overflow-when-calculating-a.patch glib2.0-2.58.3/debian/patches/gwinhttpfile-Avoid-arithmetic-overflow-when-calculating-a.patch
--- glib2.0-2.58.3/debian/patches/gwinhttpfile-Avoid-arithmetic-overflow-when-calculating-a.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/gwinhttpfile-Avoid-arithmetic-overflow-when-calculating-a.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,45 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Thu, 4 Feb 2021 16:12:24 +0000
+Subject: gwinhttpfile: Avoid arithmetic overflow when calculating a size
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+The members of `URL_COMPONENTS` (`winhttp_file->url`) are `DWORD`s, i.e.
+32-bit unsigned integers. Adding to and multiplying them may cause them
+to overflow the unsigned integer bounds, even if the result is passed to
+`g_memdup2()` which accepts a `gsize`.
+
+Cast the `URL_COMPONENTS` members to `gsize` first to ensure that the
+arithmetic is done in terms of `gsize`s rather than unsigned integers.
+
+Spotted by Sebastian Dröge.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
+Bug-Debian: https://bugs.debian.org/982778
+Origin: backport, commit:0cbad673215ec8a049b7fe2ff44b0beed31b376e
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2000
+---
+ gio/win32/gwinhttpfile.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c
+index f424d21..e98031a 100644
+--- a/gio/win32/gwinhttpfile.c
++++ b/gio/win32/gwinhttpfile.c
+@@ -394,10 +394,10 @@ g_winhttp_file_resolve_relative_path (GFile      *file,
+   child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
+   child->vfs = winhttp_file->vfs;
+   child->url = winhttp_file->url;
+-  child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
+-  child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
+-  child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
+-  child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
++  child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, ((gsize) winhttp_file->url.dwSchemeLength + 1) * 2);
++  child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, ((gsize) winhttp_file->url.dwHostNameLength + 1) * 2);
++  child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, ((gsize) winhttp_file->url.dwUserNameLength + 1) * 2);
++  child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, ((gsize) winhttp_file->url.dwPasswordLength + 1) * 2);
+   child->url.lpszUrlPath = wnew_path;
+   child->url.dwUrlPathLength = wcslen (wnew_path);
+   child->url.lpszExtraInfo = NULL;
diff -Nru glib2.0-2.58.3/debian/patches/series glib2.0-2.58.3/debian/patches/series
--- glib2.0-2.58.3/debian/patches/series	2019-11-06 08:29:15.000000000 +0000
+++ glib2.0-2.58.3/debian/patches/series	2021-03-27 11:34:13.000000000 +0000
@@ -8,6 +8,21 @@
 Add-a-test-for-GDBusServer-authentication.patch
 gdbus-server-auth-test-Create-temporary-directory-for-Uni.patch
 gdbus-server-auth-test-Include-gcredentialsprivate.h.patch
+gstrfuncs-Add-internal-g_memdup2-function.patch
+glib-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch
+ghash-Use-g_memdup2-instead-of-g_memdup.patch
+gobject-Use-g_memdup2-instead-of-g_memdup-in-obvious-plac.patch
+gio-Use-g_memdup2-instead-of-g_memdup-in-obvious-places.patch
+gvariant-test-Use-g_memdup2.patch
+gwinhttpfile-Avoid-arithmetic-overflow-when-calculating-a.patch
+gwin32-Use-gsize-internally-in-g_wcsdup.patch
+gbytearray-Do-not-accept-too-large-byte-arrays.patch
+glocalfileoutputstream-Fix-a-typo-in-a-comment.patch
+tests-Stop-using-g_test_bug_base-in-file-tests.patch
+glocalfileoutputstream-Factor-out-a-flag-check.patch
+glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATION-wit.patch
+glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-to-re.patch
+glocalfileoutputstream-Tidy-up-error-handling.patch
 01_gettext-desktopfiles.patch
 81-skip-monitor-test-on-non-linux.patch
 0001-timer-test-use-volatile-for-locals.patch
diff -Nru glib2.0-2.58.3/debian/patches/tests-Stop-using-g_test_bug_base-in-file-tests.patch glib2.0-2.58.3/debian/patches/tests-Stop-using-g_test_bug_base-in-file-tests.patch
--- glib2.0-2.58.3/debian/patches/tests-Stop-using-g_test_bug_base-in-file-tests.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.58.3/debian/patches/tests-Stop-using-g_test_bug_base-in-file-tests.patch	2021-03-27 11:34:13.000000000 +0000
@@ -0,0 +1,46 @@
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Wed, 24 Feb 2021 17:34:32 +0000
+Subject: tests: Stop using g_test_bug_base() in file tests
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Since a following commit is going to add a new test which references
+Gitlab, so it’s best to move the URI bases inside the test cases.
+
+Backported to GLib 2.58 by Simon McVittie.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+[GLib 2.58.x did not allow g_test_bug() without g_test_bug_base(),
+so use an empty string as the base]
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2325
+Bug-Debian: https://bugs.debian.org/984969
+Origin: backport, commit:32d3d02a50e7dcec5f4cf7908e7ac88d575d8fc5
+Forwarded: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2002
+---
+ gio/tests/file.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gio/tests/file.c b/gio/tests/file.c
+index d2f1474..9c2af64 100644
+--- a/gio/tests/file.c
++++ b/gio/tests/file.c
+@@ -679,7 +679,7 @@ test_replace_cancel (void)
+   guint count;
+   GError *error = NULL;
+ 
+-  g_test_bug ("629301");
++  g_test_bug ("https://bugzilla.gnome.org/629301";);
+ 
+   path = g_dir_make_tmp ("g_file_replace_cancel_XXXXXX", &error);
+   g_assert_no_error (error);
+@@ -1167,7 +1167,7 @@ main (int argc, char *argv[])
+ {
+   g_test_init (&argc, &argv, NULL);
+ 
+-  g_test_bug_base ("http://bugzilla.gnome.org/";);
++  g_test_bug_base ("");
+ 
+   g_test_add_func ("/file/basic", test_basic);
+   g_test_add_func ("/file/build-filename", test_build_filename);

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 10.10

Hi,

Each of the updates referenced in these bugs was included in the 10.10
point release today.

Regards,

Adam

--- End Message ---

Reply to: