!41 [sync] PR-40: synchronous community patch

From: @openeuler-sync-bot
Reviewed-by: @dwl301
Signed-off-by: @dwl301,@dwl301
This commit is contained in:
openeuler-ci-bot 2021-05-21 16:52:25 +08:00 committed by Gitee
commit 68966fbcab
21 changed files with 1755 additions and 12 deletions

View File

@ -0,0 +1,81 @@
From 497c511a984d8c71b3ea48e4f5cfc2537b907021 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Stefanesco?= <leo.lveb@gmail.com>
Date: Fri, 3 Jul 2020 15:16:33 +0200
Subject: [PATCH 0698/1095] Fix giomodule.cache being wrongly considered stale
In ostree based systems, such as flatpak and fedora silverblue, the
time of modification of every system file is epoch 0, including
giomodule.cache, which means that every module is loaded and unloaded
every time.
The solution is to use the change time of the file as well. In a typical
system, it is equal to the mtime, and in an ostree based system, since
the directory is mounted as read-only, the user cannot add a module and
we must assume that the cache file corresponds to the modules.
reason:Fix giomodule.cache being wrongly considered stale
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/497c511a984d8c71b3ea48e4f5cfc2537b907021
---
gio/giomodule.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/gio/giomodule.c b/gio/giomodule.c
index f49ea3e..d8d64be 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -462,7 +462,7 @@ g_io_modules_scan_all_in_directory_with_scope (const char *dirname,
GDir *dir;
GStatBuf statbuf;
char *data;
- time_t cache_mtime;
+ time_t cache_time;
GHashTable *cache;
if (!g_module_supported ())
@@ -477,21 +477,24 @@ g_io_modules_scan_all_in_directory_with_scope (const char *dirname,
cache = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify)g_strfreev);
- cache_mtime = 0;
+ cache_time = 0;
if (g_stat (filename, &statbuf) == 0 &&
g_file_get_contents (filename, &data, NULL, NULL))
{
char **lines;
int i;
- /* Cache mtime is the time the cache file was created, any file
- * that has a ctime before this was created then and not modified
- * since then (userspace can't change ctime). Its possible to change
- * the ctime forward without changing the file content, by e.g.
- * chmoding the file, but this is uncommon and will only cause us
- * to not use the cache so will not cause bugs.
+ /* cache_time is the time the cache file was created; we also take
+ * into account the change time because in ostree based systems, all
+ * system file have mtime equal to epoch 0.
+ *
+ * Any file that has a ctime before this was created then and not modified
+ * since then (userspace can't change ctime). Its possible to change the
+ * ctime forward without changing the file content, by e.g. chmoding the
+ * file, but this is uncommon and will only cause us to not use the cache
+ * so will not cause bugs.
*/
- cache_mtime = statbuf.st_mtime;
+ cache_time = MAX(statbuf.st_mtime, statbuf.st_ctime);
lines = g_strsplit (data, "\n", -1);
g_free (data);
@@ -539,7 +542,7 @@ g_io_modules_scan_all_in_directory_with_scope (const char *dirname,
extension_points = g_hash_table_lookup (cache, name);
if (extension_points != NULL &&
g_stat (path, &statbuf) == 0 &&
- statbuf.st_ctime <= cache_mtime)
+ statbuf.st_ctime <= cache_time)
{
/* Lazy load/init the library when first required */
for (i = 0; extension_points[i] != NULL; i++)
--
1.8.3.1

View File

@ -0,0 +1,49 @@
From da00779093f8c69b77b578795e8bec8e27f107d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?=
=?UTF-8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= <lrn1986@gmail.com>
Date: Mon, 5 Oct 2020 16:53:47 +0000
Subject: [PATCH 1022/1095] Fix the 6-days-until-the-end-of-the-month bug
The addition causes the date to shift
forward into 1st of the next month, because a 0-based offset
is compared to be "more than" the days in the month instead of "more than
or equal to".
This is triggered by corner-cases where transition date is 6 days
off the end of the month and our calculations put it at N+1th day of the
month (where N is the number of days in the month). The subtraction should
be triggered to move the date back a week, putting it 6 days off the end;
for example, October 25 for CET DST transition; but due to incorrect comparison
the date isn't shifted back, we add 31 days to October 1st and end up
at November 1st).
Fixes issue #2215.
reason:Fix the 6-days-until-the-end-of-the-month bug
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/da00779093f8c69b77b578795e8bec8e27f107d0
---
glib/gtimezone.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/glib/gtimezone.c b/glib/gtimezone.c
index ef67ec5..0de5c92 100644
--- a/glib/gtimezone.c
+++ b/glib/gtimezone.c
@@ -1041,7 +1041,11 @@ find_relative_date (TimeZoneDate *buffer)
/* week is 1 <= w <= 5, we need 0-based */
days = 7 * (buffer->week - 1) + wday - first_wday;
- while (days > days_in_month)
+ /* "days" is a 0-based offset from the 1st of the month.
+ * Adding days == days_in_month would bring us into the next month,
+ * hence the ">=" instead of just ">".
+ */
+ while (days >= days_in_month)
days -= 7;
g_date_add_days (&date, days);
--
1.8.3.1

View File

@ -0,0 +1,48 @@
From 4332e3b160a1fef92f86b38be3b7286712925d67 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Tue, 5 Nov 2019 10:08:45 +0000
Subject: [PATCH 0115/1095] gbookmarkfile: Fix a minor leak on an error path
Signed-off-by: Philip Withnall <withnall@endlessm.com>
reason:Fix a minor leak on an error path
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/4332e3b160a1fef92f86b38be3b7286712925d67
---
glib/gbookmarkfile.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/glib/gbookmarkfile.c b/glib/gbookmarkfile.c
index 25f1234..e22f794 100644
--- a/glib/gbookmarkfile.c
+++ b/glib/gbookmarkfile.c
@@ -775,13 +775,22 @@ parse_bookmark_element (GMarkupParseContext *context,
item = bookmark_item_new (uri);
if (added != NULL && !timestamp_from_iso8601 (added, &item->added, error))
- return;
+ {
+ bookmark_item_free (item);
+ return;
+ }
if (modified != NULL && !timestamp_from_iso8601 (modified, &item->modified, error))
- return;
+ {
+ bookmark_item_free (item);
+ return;
+ }
if (visited != NULL && !timestamp_from_iso8601 (visited, &item->visited, error))
- return;
+ {
+ bookmark_item_free (item);
+ return;
+ }
add_error = NULL;
g_bookmark_file_add_item (parse_data->bookmark_file,
--
1.8.3.1

View File

@ -0,0 +1,48 @@
From e86dd776552224dfc06818b45257066d4ed5bb25 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Wed, 10 Jun 2020 13:26:14 +0100
Subject: [PATCH 0631/1095] gfileutils: Correct operator precedence to avoid
undefined pointer maths
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`base` can be `-1` in some situations, which would lead to pointing
outside an allocation area if the sums were evaluated as `(file_name +
base) + 1` rather than `file_name + (base + 1)`.
I dont see how this can practically cause an issue, as the arithmetic
is all finished before anythings dereferenced, but lets keep to the
letter of the C standard to avoid this coming up in code audits in
future.
Fix suggested by fablhx.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #2077
reason: Correct operator precedence to avoid undefined pointer maths
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/e86dd776552224dfc06818b45257066d4ed5bb25
---
glib/gfileutils.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/gfileutils.c b/glib/gfileutils.c
index f0799e2..ede22b8 100644
--- a/glib/gfileutils.c
+++ b/glib/gfileutils.c
@@ -2397,7 +2397,7 @@ g_path_get_basename (const gchar *file_name)
len = last_nonslash - base;
retval = g_malloc (len + 1);
- memcpy (retval, file_name + base + 1, len);
+ memcpy (retval, file_name + (base + 1), len);
retval [len] = '\0';
return retval;
--
1.8.3.1

View File

@ -0,0 +1,90 @@
From 14035010dd760d2202d03eba3ca392a488ff04eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Fri, 4 Oct 2019 13:52:39 +0100
Subject: [PATCH] glib: ensure consistent abort-on-OOM with g_vasprintf & its
callers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The g_vasprintf method is called by g_strdup_vprintf, g_strdup_printf,
g_string_append_vprintf and more. It has three different implementations
depending on what the build target platform supports:
1. The gnulib impl appears to use the system malloc, but a
'#define malloc g_malloc' causes it to use GLib's wrapper
and thus abort on OOM. This mostly gets used on Windows
platforms or UNIX platforms with broken printf formatting.
2. The main impl mostly used on modern Linux/UNIX calls the
system vasprintf which uses the system malloc and does not
abort on OOM.
3. The final impl used on remaining platforms calls system
vsprintf on a buffer allocated by g_new, and thus always
aborts on OOM.
Of note is that impl 2 (using vasprintf) historically could abort on
OOM, if the application had installed a non-system malloc impl with
GLib. This was because the code would g_strndup the result from
vasprintf() in that scenario. This was removed in:
commit a3660532535f92cfac136435579ed4f23231f48c
Author: Dan Winship <danw@gnome.org>
Date: Fri Aug 7 09:46:49 2015 -0400
glib: remove deprecated g_mem_is_system_malloc() check in gprintf.c
Having inconsistent OOM behaviour for the three impls is undesirable and
aborting on OOM is normal pratice for GLib APIs. Thus we must thus ensure
this happens in all impls of g_vasprintf.
Fixes #1622
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
reason:ensure consistent abort-on-OOM with g_vasprintf & its callers
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/14035010dd760d2202d03eba3ca392a488ff04eb
---
glib/gprintf.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/glib/gprintf.c b/glib/gprintf.c
index fc0a02a..d4d0b3e 100644
--- a/glib/gprintf.c
+++ b/glib/gprintf.c
@@ -20,6 +20,7 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
+#include <errno.h>
#include "gprintf.h"
#include "gprintfint.h"
@@ -327,9 +328,18 @@ g_vasprintf (gchar **string,
#elif defined (HAVE_VASPRINTF)
- len = vasprintf (string, format, args);
- if (len < 0)
- *string = NULL;
+ {
+ int saved_errno;
+ len = vasprintf (string, format, args);
+ saved_errno = errno;
+ if (len < 0)
+ {
+ if (saved_errno == ENOMEM)
+ g_error ("%s: failed to allocate memory", G_STRLOC);
+ else
+ *string = NULL;
+ }
+ }
#else
--
1.8.3.1

View File

@ -0,0 +1,34 @@
From 02f0d4fc6a863d57f0a669428ef44ee867918a23 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Thu, 25 Jun 2020 10:00:58 +0100
Subject: [PATCH] glib.supp: Suppress calloc() variant of g_get_charset()
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2136
reason:Suppress calloc() variant of g_get_charset()
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/02f0d4fc6a863d57f0a669428ef44ee867918a23
---
glib.supp | 9 +++++++++
1 file changed, 9 insertions(+)
diff -Naur a/glib.supp b/glib.supp
--- a/glib.supp 2020-12-14 14:14:06.868000000 +0800
+++ b/glib.supp 2020-12-14 15:46:11.033000000 +0800
@@ -946,3 +946,13 @@
...
fun:g_file_*
}
+
+# Cached charset
+{
+ g_get_charset_calloc
+ Memcheck:Leak
+ match-leak-kinds:reachable
+ fun:calloc
+ ...
+ fun:g_get_charset
+}

View File

@ -0,0 +1,40 @@
From 63b329fb818358eaf6688f4f78779ef3ee6cfb99 Mon Sep 17 00:00:00 2001
From: Sergio Gelato <sergio.gelato@astro.su.se>
Date: Wed, 8 Jul 2020 12:45:43 +0100
Subject: [PATCH 0715/1095] glocalfileinfo: Correct an off-by-one error when
unescaping hex
Correct an off-by-one error in hex_unescape_string()'s computation of
the output string length.
(Turned into a git-format patch by Philip Withnall. Original patch
submitted on the Debian bug tracker, bug#962912.)
reason:Correct an off-by-one error when unescaping hex
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/63b329fb818358eaf6688f4f78779ef3ee6cfb99
---
gio/glocalfileinfo.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c
index 6cac187..4ca1ce6 100644
--- a/gio/glocalfileinfo.c
+++ b/gio/glocalfileinfo.c
@@ -394,10 +394,10 @@ hex_unescape_string (const char *str,
else
*p++ = str[i];
}
- *p++ = 0;
-
if (out_len)
*out_len = p - unescaped_str;
+ *p++ = 0;
+
*free_return = TRUE;
return unescaped_str;
}
--
1.8.3.1

View File

@ -0,0 +1,37 @@
From 15818926b360b99d7897e519d7414470870b2e58 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Wed, 30 Oct 2019 15:35:15 +0000
Subject: [PATCH 0099/1095] glocalfileinfo: Fix minor leak on error handling
path for xattrs
Spotted by `scan-build`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
reason: Fix minor leak on error handling path for xattrs
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/15818926b360b99d7897e519d7414470870b2e58
---
gio/glocalfileinfo.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c
index dcc9bce..5ba7691 100644
--- a/gio/glocalfileinfo.c
+++ b/gio/glocalfileinfo.c
@@ -504,7 +504,10 @@ get_xattrs (const char *path,
}
if (list_res_size == -1)
- return;
+ {
+ g_free (list);
+ return;
+ }
attr = list;
while (list_res_size > 0)
--
1.8.3.1

View File

@ -0,0 +1,49 @@
From 1a3bba4670e79f9e78fae512ace9191226715e35 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Mon, 28 Oct 2019 14:57:33 +0000
Subject: [PATCH 0078/1095] gparamspecs: Fix type class leaks on error handling
paths
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1911
reason: Fix type class leaks on error handling paths
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/1a3bba4670e79f9e78fae512ace9191226715e35
---
gobject/gparamspecs.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c
index 5d15c26..490c7c2 100644
--- a/gobject/gparamspecs.c
+++ b/gobject/gparamspecs.c
@@ -2092,7 +2092,10 @@ g_param_spec_enum (const gchar *name,
blurb,
flags);
if (espec == NULL)
- return NULL;
+ {
+ g_type_class_unref (enum_class);
+ return NULL;
+ }
espec->enum_class = enum_class;
espec->default_value = default_value;
@@ -2140,7 +2143,10 @@ g_param_spec_flags (const gchar *name,
blurb,
flags);
if (fspec == NULL)
- return NULL;
+ {
+ g_type_class_unref (flags_class);
+ return NULL;
+ }
fspec->flags_class = flags_class;
fspec->default_value = default_value;
--
1.8.3.1

View File

@ -0,0 +1,39 @@
From d691c2ebd269e394457d6367db14cf2cc22bc281 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 13 Oct 2020 09:24:02 -0400
Subject: [PATCH 0999/1095] gsignal: Plug g_signal_connect_object leak
commit 916297be799ee001b4a214cc52c3b960bb0b5deb added a hash table
to provide constant time lookups of signal handlers.
Unfortunately, that commit neglected to remove handlers from
g_signal_connect_object calls from the hash table that are
disconnected implicitly when the associated object goes away.
This commit addresses that bug by changing the closure invalidate
handler associated with the signal connection to properly remove the
handler from the hash table.
reason:Plug g_signal_connect_object leak
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/d691c2ebd269e394457d6367db14cf2cc22bc281
---
gobject/gsignal.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index ebf5b3c..41599eb 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -3916,6 +3916,7 @@ invalid_closure_notify (gpointer instance,
g_assert (handler != NULL);
g_assert (handler->closure == closure);
+ g_hash_table_remove (g_handlers, handler);
handler->sequential_number = 0;
handler->block_count = 1;
handler_unref_R (signal_id, instance, handler);
--
1.8.3.1

View File

@ -0,0 +1,59 @@
From 14f7b5e590f6adc3207019227586d20848274654 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Mon, 5 Oct 2020 12:32:32 -0500
Subject: [PATCH 0990/1095] gsocketclient: Crash on error if error is missing
We should never return unknown errors to the application. This would be
a glib bug.
I don't think it's currently possible to hit these cases, so asserts
should be OK. For this to happen, either (a) a GSocketAddressEnumerator
would have to return NULL on its first enumeration, without returning an
error, or (b) there would have to be a bug in our GSocketClient logic.
Either way, if such a bug were to exist, it would be better to surface
it rather than hide it.
These changes are actually going to be effectively undone in a
subsequent commit, as I'm refactoring the error handling, but the commit
history is a bit nicer with two separate commits, so let's go with two.
reason:Crash on error if error is missing
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/14f7b5e590f6adc3207019227586d20848274654
---
gio/gsocketclient.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index 9df8f29..fb68c09 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -1053,8 +1053,9 @@ g_socket_client_connect (GSocketClient *client,
g_propagate_error (error, last_error);
}
else
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unknown error on connect"));
+ {
+ g_assert_not_reached ();
+ }
break;
}
@@ -1879,10 +1880,9 @@ g_socket_client_enumerator_callback (GObject *object,
error = data->last_error;
data->last_error = NULL;
}
- else if (!error)
+ else
{
- g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unknown error on connect"));
+ g_assert (error);
}
complete_connection_with_error (data, error);
--
1.8.3.1

View File

@ -0,0 +1,118 @@
From f0a7b147806e852e2090eeda6e4e38f7d3f52b52 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Tue, 6 Oct 2020 15:39:45 -0500
Subject: [PATCH 0989/1095] gsocketclient: emit RESOLVING/RESOLVED events only
once
GSocketAddressEnumerator encapsulates the details of how DNS happens, so
we don't have to think about it. But we may have taken encapsulation a
bit too far, here. Usually, we resolve a domain name to a list of IPv4
and IPv6 addresses. Then we go through each address in the list and try
to connect to it. Name resolution happens exactly once, at the start.
It doesn't happen each time we enumerate the enumerator. In theory, it
*could*, because we've designed these APIs to be agnostic of underlying
implementation details like DNS and network protocols. But in practice,
we know that's not really what's happening. It's weird to say that we
are RESOLVING what we know to be the same name multiple times. Behind
the scenes, we're not doing that.
This also fixes #1994, where enumeration can end with a RESOLVING event,
even though this is supposed to be the first event rather than the last.
I thought this would be hard to fix, even requiring new public API in
GSocketAddressEnumerator to peek ahead to see if the next enumeration is
going to return NULL. Then I decided we should just fake it: always emit
both RESOLVING and RESOLVED at the same time right after each
enumeration. Finally, I realized we can emit them at the correct time if
we simply assume resolving only happens the first time. This seems like
the most elegant of the possible solutions.
Now, this is a behavior change, and arguably an API break, but it should
align better with reasonable expectations of how GSocketClientEvent
ought to work. I don't expect it to break anything besides tests that
check which order GSocketClientEvent events are emitted in. (Currently,
libsoup has such tests, which will need to be updated.) Ideally we would
have GLib-level tests as well, but in a concession to pragmatism, it's a
lot easier to keep network tests in libsoup.
reason:emit RESOLVING/RESOLVED events only once
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/f0a7b147806e852e2090eeda6e4e38f7d3f52b52
---
gio/gsocketclient.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index 8a663c3..9df8f29 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -991,6 +991,7 @@ g_socket_client_connect (GSocketClient *client,
{
GIOStream *connection = NULL;
GSocketAddressEnumerator *enumerator = NULL;
+ gboolean ever_resolved = FALSE;
GError *last_error, *tmp_error;
last_error = NULL;
@@ -1025,10 +1026,20 @@ g_socket_client_connect (GSocketClient *client,
}
tmp_error = NULL;
- g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVING,
- connectable, NULL);
+
+ if (!ever_resolved)
+ {
+ g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVING,
+ connectable, NULL);
+ }
address = g_socket_address_enumerator_next (enumerator, cancellable,
&tmp_error);
+ if (!ever_resolved)
+ {
+ g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVED,
+ connectable, NULL);
+ ever_resolved = TRUE;
+ }
if (address == NULL)
{
@@ -1046,8 +1057,6 @@ g_socket_client_connect (GSocketClient *client,
_("Unknown error on connect"));
break;
}
- g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVED,
- connectable, NULL);
using_proxy = (G_IS_PROXY_ADDRESS (address) &&
client->priv->enable_proxy);
@@ -1509,7 +1518,8 @@ enumerator_next_async (GSocketClientAsyncConnectData *data,
if (add_task_ref)
g_object_ref (data->task);
- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVING, data->connectable, NULL);
+ if (!data->enumerated_at_least_once)
+ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVING, data->connectable, NULL);
g_debug ("GSocketClient: Starting new address enumeration");
g_socket_address_enumerator_next_async (data->enumerator,
data->enumeration_cancellable,
@@ -1883,10 +1893,13 @@ g_socket_client_enumerator_callback (GObject *object,
return;
}
- data->enumerated_at_least_once = TRUE;
g_debug ("GSocketClient: Address enumeration succeeded");
- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVED,
- data->connectable, NULL);
+ if (!data->enumerated_at_least_once)
+ {
+ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVED,
+ data->connectable, NULL);
+ data->enumerated_at_least_once = TRUE;
+ }
g_clear_error (&data->last_error);
--
1.8.3.1

View File

@ -0,0 +1,38 @@
From c2b8fa8a34765d42be69e7eb9a4c44eeb970f775 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Wed, 28 Oct 2020 10:41:13 -0500
Subject: [PATCH 1035/1095] gsocketclient: fix crash when async connection step
fails
This is a regression from !1686. The tmp_error is no longer valid after
it is "considered" and cannot be used at this point. We should print the
error earlier instead.
Fixes #2233
reason:fix crash when async connection step fails
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/c2b8fa8a34765d42be69e7eb9a4c44eeb970f775
---
gio/gsocketclient.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index ce3c186..3737746 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -1837,9 +1837,9 @@ g_socket_client_connected_callback (GObject *source,
{
if (!g_cancellable_is_cancelled (attempt->cancellable))
{
+ g_debug ("GSocketClient: Connection attempt failed: %s", data->error_info->tmp_error->message);
clarify_connect_error (data->error_info->tmp_error, data->connectable, attempt->address);
consider_tmp_error (data->error_info, G_SOCKET_CLIENT_CONNECTING);
- g_debug ("GSocketClient: Connection attempt failed: %s", data->error_info->tmp_error->message);
connection_attempt_remove (attempt);
connection_attempt_unref (attempt);
try_next_connection_or_finish (data, FALSE);
--
1.8.3.1

View File

@ -0,0 +1,520 @@
From b88b3712e0d4474ff55d3b94050285ea08580ddb Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Thu, 8 Oct 2020 18:02:56 -0500
Subject: [PATCH 0991/1095] gsocketclient: return best errors possible
Originally, GSocketClient returned whatever error occured last. Turns
out this doesn't work well in practice. Consider the following case:
DNS returns an IPv4 and IPv6 address. First we'll connect() to the
IPv4 address, and say that succeeds, but TLS is enabled and the TLS
handshake fails. Then we try the IPv6 address and receive ENETUNREACH
because IPv6 isn't supported. We wind up returning NETWORK_UNREACHABLE
even though the address can be pinged and a TLS error would be more
appropriate. So instead, we now try to return the error corresponding
to the latest attempted GSocketClientEvent in the connection process.
TLS errors take precedence over proxy errors, which take precedence
over connect() errors, which take precedence over DNS errors.
In writing this commit, I made several mistakes that were caught by
proxy-test.c, which tests using GSocketClient to make a proxy
connection. So although adding a new test to ensure we get the
best-possible error would be awkward, at least we have some test
coverage for the code that helped avoid introducing bugs.
Fixes #2211
reason:gsocketclient: return best errors possible
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/b88b3712e0d4474ff55d3b94050285ea08580ddb
---
gio/gsocketclient.c | 209 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 130 insertions(+), 79 deletions(-)
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index fb68c09..ce3c186 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -953,6 +953,72 @@ g_socket_client_emit_event (GSocketClient *client,
event, connectable, connection);
}
+/* Originally, GSocketClient returned whatever error occured last. Turns
+ * out this doesn't work well in practice. Consider the following case:
+ * DNS returns an IPv4 and IPv6 address. First we'll connect() to the
+ * IPv4 address, and say that succeeds, but TLS is enabled and the TLS
+ * handshake fails. Then we try the IPv6 address and receive ENETUNREACH
+ * because IPv6 isn't supported. We wind up returning NETWORK_UNREACHABLE
+ * even though the address can be pinged and a TLS error would be more
+ * appropriate. So instead, we now try to return the error corresponding
+ * to the latest attempted GSocketClientEvent in the connection process.
+ * TLS errors take precedence over proxy errors, which take precedence
+ * over connect() errors, which take precedence over DNS errors.
+ *
+ * Note that the example above considers a sync codepath, but this is an
+ * issue for the async codepath too, where events and errors may occur
+ * in confusing orders.
+ */
+typedef struct
+{
+ GError *tmp_error;
+ GError *best_error;
+ GSocketClientEvent best_error_event;
+} SocketClientErrorInfo;
+
+static SocketClientErrorInfo *
+socket_client_error_info_new (void)
+{
+ return g_new0 (SocketClientErrorInfo, 1);
+}
+
+static void
+socket_client_error_info_free (SocketClientErrorInfo *info)
+{
+ g_assert (info->tmp_error == NULL);
+ g_clear_error (&info->best_error);
+ g_free (info);
+}
+
+static void
+consider_tmp_error (SocketClientErrorInfo *info,
+ GSocketClientEvent event)
+{
+ if (info->tmp_error == NULL)
+ return;
+
+ /* If we ever add more GSocketClientEvents in the future, then we'll
+ * no longer be able to use >= for this comparison, because future
+ * events will compare greater than G_SOCKET_CLIENT_COMPLETE. Until
+ * then, this is convenient. Note G_SOCKET_CLIENT_RESOLVING is 0 so we
+ * need to use >= here or those errors would never be set. That means
+ * if we get two errors on the same GSocketClientEvent, we wind up
+ * preferring the last one, which is fine.
+ */
+ g_assert (event <= G_SOCKET_CLIENT_COMPLETE);
+ if (event >= info->best_error_event)
+ {
+ g_clear_error (&info->best_error);
+ info->best_error = info->tmp_error;
+ info->tmp_error = NULL;
+ info->best_error_event = event;
+ }
+ else
+ {
+ g_clear_error (&info->tmp_error);
+ }
+}
+
/**
* g_socket_client_connect:
* @client: a #GSocketClient.
@@ -991,10 +1057,10 @@ g_socket_client_connect (GSocketClient *client,
{
GIOStream *connection = NULL;
GSocketAddressEnumerator *enumerator = NULL;
+ SocketClientErrorInfo *error_info;
gboolean ever_resolved = FALSE;
- GError *last_error, *tmp_error;
- last_error = NULL;
+ error_info = socket_client_error_info_new ();
if (can_use_proxy (client))
{
@@ -1019,21 +1085,19 @@ g_socket_client_connect (GSocketClient *client,
if (g_cancellable_is_cancelled (cancellable))
{
- g_clear_error (error);
- g_clear_error (&last_error);
- g_cancellable_set_error_if_cancelled (cancellable, error);
+ g_clear_error (&error_info->best_error);
+ g_cancellable_set_error_if_cancelled (cancellable, &error_info->best_error);
break;
}
- tmp_error = NULL;
-
if (!ever_resolved)
{
g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVING,
connectable, NULL);
}
address = g_socket_address_enumerator_next (enumerator, cancellable,
- &tmp_error);
+ &error_info->tmp_error);
+ consider_tmp_error (error_info, G_SOCKET_CLIENT_RESOLVING);
if (!ever_resolved)
{
g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVED,
@@ -1043,29 +1107,16 @@ g_socket_client_connect (GSocketClient *client,
if (address == NULL)
{
- if (tmp_error)
- {
- g_clear_error (&last_error);
- g_propagate_error (error, tmp_error);
- }
- else if (last_error)
- {
- g_propagate_error (error, last_error);
- }
- else
- {
- g_assert_not_reached ();
- }
+ /* Enumeration is finished. */
+ g_assert (&error_info->best_error != NULL);
break;
}
using_proxy = (G_IS_PROXY_ADDRESS (address) &&
client->priv->enable_proxy);
- /* clear error from previous attempt */
- g_clear_error (&last_error);
-
- socket = create_socket (client, address, &last_error);
+ socket = create_socket (client, address, &error_info->tmp_error);
+ consider_tmp_error (error_info, G_SOCKET_CLIENT_CONNECTING);
if (socket == NULL)
{
g_object_unref (address);
@@ -1077,14 +1128,15 @@ g_socket_client_connect (GSocketClient *client,
g_socket_client_emit_event (client, G_SOCKET_CLIENT_CONNECTING, connectable, connection);
if (g_socket_connection_connect (G_SOCKET_CONNECTION (connection),
- address, cancellable, &last_error))
+ address, cancellable, &error_info->tmp_error))
{
g_socket_connection_set_cached_remote_address ((GSocketConnection*)connection, NULL);
g_socket_client_emit_event (client, G_SOCKET_CLIENT_CONNECTED, connectable, connection);
}
else
{
- clarify_connect_error (last_error, connectable, address);
+ clarify_connect_error (error_info->tmp_error, connectable, address);
+ consider_tmp_error (error_info, G_SOCKET_CLIENT_CONNECTING);
g_object_unref (connection);
connection = NULL;
}
@@ -1105,9 +1157,10 @@ g_socket_client_connect (GSocketClient *client,
g_critical ("Trying to proxy over non-TCP connection, this is "
"most likely a bug in GLib IO library.");
- g_set_error_literal (&last_error,
+ g_set_error_literal (&error_info->tmp_error,
G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Proxying over a non-TCP connection is not supported."));
+ consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
g_object_unref (connection);
connection = NULL;
@@ -1125,7 +1178,9 @@ g_socket_client_connect (GSocketClient *client,
connection,
proxy_addr,
cancellable,
- &last_error);
+ &error_info->tmp_error);
+ consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
+
g_object_unref (connection);
connection = proxy_connection;
g_object_unref (proxy);
@@ -1135,9 +1190,10 @@ g_socket_client_connect (GSocketClient *client,
}
else
{
- g_set_error (&last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ g_set_error (&error_info->tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Proxy protocol “%s” is not supported."),
protocol);
+ consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
g_object_unref (connection);
connection = NULL;
}
@@ -1147,7 +1203,7 @@ g_socket_client_connect (GSocketClient *client,
{
GIOStream *tlsconn;
- tlsconn = g_tls_client_connection_new (connection, connectable, &last_error);
+ tlsconn = g_tls_client_connection_new (connection, connectable, &error_info->tmp_error);
g_object_unref (connection);
connection = tlsconn;
@@ -1157,16 +1213,21 @@ g_socket_client_connect (GSocketClient *client,
client->priv->tls_validation_flags);
g_socket_client_emit_event (client, G_SOCKET_CLIENT_TLS_HANDSHAKING, connectable, connection);
if (g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn),
- cancellable, &last_error))
+ cancellable, &error_info->tmp_error))
{
g_socket_client_emit_event (client, G_SOCKET_CLIENT_TLS_HANDSHAKED, connectable, connection);
}
else
{
+ consider_tmp_error (error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING);
g_object_unref (tlsconn);
connection = NULL;
}
}
+ else
+ {
+ consider_tmp_error (error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING);
+ }
}
if (connection && !G_IS_SOCKET_CONNECTION (connection))
@@ -1183,6 +1244,10 @@ g_socket_client_connect (GSocketClient *client,
}
g_object_unref (enumerator);
+ if (!connection)
+ g_propagate_error (error, g_steal_pointer (&error_info->best_error));
+ socket_client_error_info_free (error_info);
+
g_socket_client_emit_event (client, G_SOCKET_CLIENT_COMPLETE, connectable, connection);
return G_SOCKET_CONNECTION (connection);
}
@@ -1360,7 +1425,7 @@ typedef struct
GSList *connection_attempts;
GSList *successful_connections;
- GError *last_error;
+ SocketClientErrorInfo *error_info;
gboolean enumerated_at_least_once;
gboolean enumeration_completed;
@@ -1380,7 +1445,7 @@ g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data)
g_slist_free_full (data->connection_attempts, connection_attempt_unref);
g_slist_free_full (data->successful_connections, connection_attempt_unref);
- g_clear_error (&data->last_error);
+ g_clear_pointer (&data->error_info, socket_client_error_info_free);
g_slice_free (GSocketClientAsyncConnectData, data);
}
@@ -1503,14 +1568,6 @@ g_socket_client_enumerator_callback (GObject *object,
gpointer user_data);
static void
-set_last_error (GSocketClientAsyncConnectData *data,
- GError *error)
-{
- g_clear_error (&data->last_error);
- data->last_error = error;
-}
-
-static void
enumerator_next_async (GSocketClientAsyncConnectData *data,
gboolean add_task_ref)
{
@@ -1540,7 +1597,7 @@ g_socket_client_tls_handshake_callback (GObject *object,
if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (object),
result,
- &data->last_error))
+ &data->error_info->tmp_error))
{
g_object_unref (attempt->connection);
attempt->connection = G_IO_STREAM (object);
@@ -1553,7 +1610,9 @@ g_socket_client_tls_handshake_callback (GObject *object,
{
g_object_unref (object);
connection_attempt_unref (attempt);
- g_debug ("GSocketClient: TLS handshake failed: %s", data->last_error->message);
+
+ g_debug ("GSocketClient: TLS handshake failed: %s", data->error_info->tmp_error->message);
+ consider_tmp_error (data->error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING);
try_next_connection_or_finish (data, TRUE);
}
}
@@ -1573,7 +1632,7 @@ g_socket_client_tls_handshake (ConnectionAttempt *attempt)
g_debug ("GSocketClient: Starting TLS handshake");
tlsconn = g_tls_client_connection_new (attempt->connection,
data->connectable,
- &data->last_error);
+ &data->error_info->tmp_error);
if (tlsconn)
{
g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
@@ -1588,6 +1647,8 @@ g_socket_client_tls_handshake (ConnectionAttempt *attempt)
else
{
connection_attempt_unref (attempt);
+
+ consider_tmp_error (data->error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING);
try_next_connection_or_finish (data, TRUE);
}
}
@@ -1603,19 +1664,19 @@ g_socket_client_proxy_connect_callback (GObject *object,
g_object_unref (attempt->connection);
attempt->connection = g_proxy_connect_finish (G_PROXY (object),
result,
- &data->last_error);
+ &data->error_info->tmp_error);
if (attempt->connection)
{
g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, attempt->connection);
+ g_socket_client_tls_handshake (attempt);
}
else
{
connection_attempt_unref (attempt);
+
+ consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
try_next_connection_or_finish (data, TRUE);
- return;
}
-
- g_socket_client_tls_handshake (attempt);
}
static void
@@ -1683,9 +1744,10 @@ try_next_successful_connection (GSocketClientAsyncConnectData *data)
g_critical ("Trying to proxy over non-TCP connection, this is "
"most likely a bug in GLib IO library.");
- g_set_error_literal (&data->last_error,
+ g_set_error_literal (&data->error_info->tmp_error,
G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Proxying over a non-TCP connection is not supported."));
+ consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
}
else if (g_hash_table_contains (data->client->priv->app_proxies, protocol))
{
@@ -1712,11 +1774,10 @@ try_next_successful_connection (GSocketClientAsyncConnectData *data)
}
else
{
- g_clear_error (&data->last_error);
-
- g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ g_set_error (&data->error_info->tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Proxy protocol “%s” is not supported."),
protocol);
+ consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
}
data->connection_in_progress = FALSE;
@@ -1747,7 +1808,7 @@ try_next_connection_or_finish (GSocketClientAsyncConnectData *data,
return;
}
- complete_connection_with_error (data, data->last_error);
+ complete_connection_with_error (data, g_steal_pointer (&data->error_info->best_error));
}
static void
@@ -1757,7 +1818,6 @@ g_socket_client_connected_callback (GObject *source,
{
ConnectionAttempt *attempt = user_data;
GSocketClientAsyncConnectData *data = attempt->data;
- GError *error = NULL;
if (task_completed_or_cancelled (data) || g_cancellable_is_cancelled (attempt->cancellable))
{
@@ -1773,20 +1833,20 @@ g_socket_client_connected_callback (GObject *source,
}
if (!g_socket_connection_connect_finish (G_SOCKET_CONNECTION (source),
- result, &error))
+ result, &data->error_info->tmp_error))
{
if (!g_cancellable_is_cancelled (attempt->cancellable))
{
- clarify_connect_error (error, data->connectable, attempt->address);
- set_last_error (data, error);
- g_debug ("GSocketClient: Connection attempt failed: %s", error->message);
+ clarify_connect_error (data->error_info->tmp_error, data->connectable, attempt->address);
+ consider_tmp_error (data->error_info, G_SOCKET_CLIENT_CONNECTING);
+ g_debug ("GSocketClient: Connection attempt failed: %s", data->error_info->tmp_error->message);
connection_attempt_remove (attempt);
connection_attempt_unref (attempt);
try_next_connection_or_finish (data, FALSE);
}
else /* Silently ignore cancelled attempts */
{
- g_clear_error (&error);
+ g_clear_error (&data->error_info->tmp_error);
g_object_unref (data->task);
connection_attempt_unref (attempt);
}
@@ -1844,7 +1904,6 @@ g_socket_client_enumerator_callback (GObject *object,
GSocketAddress *address = NULL;
GSocket *socket;
ConnectionAttempt *attempt;
- GError *error = NULL;
if (task_completed_or_cancelled (data))
{
@@ -1853,7 +1912,7 @@ g_socket_client_enumerator_callback (GObject *object,
}
address = g_socket_address_enumerator_next_finish (data->enumerator,
- result, &error);
+ result, &data->error_info->tmp_error);
if (address == NULL)
{
if (G_UNLIKELY (data->enumeration_completed))
@@ -1862,7 +1921,7 @@ g_socket_client_enumerator_callback (GObject *object,
data->enumeration_completed = TRUE;
g_debug ("GSocketClient: Address enumeration completed (out of addresses)");
- /* As per API docs: We only care about error if its the first call,
+ /* As per API docs: We only care about error if it's the first call,
after that the enumerator is done.
Note that we don't care about cancellation errors because
@@ -1873,19 +1932,11 @@ g_socket_client_enumerator_callback (GObject *object,
if ((data->enumerated_at_least_once && !data->connection_attempts && !data->connection_in_progress) ||
!data->enumerated_at_least_once)
{
- g_debug ("GSocketClient: Address enumeration failed: %s", error ? error->message : NULL);
- if (data->last_error)
- {
- g_clear_error (&error);
- error = data->last_error;
- data->last_error = NULL;
- }
- else
- {
- g_assert (error);
- }
-
- complete_connection_with_error (data, error);
+ g_debug ("GSocketClient: Address enumeration failed: %s",
+ data->error_info->tmp_error ? data->error_info->tmp_error->message : NULL);
+ consider_tmp_error (data->error_info, G_SOCKET_CLIENT_RESOLVING);
+ g_assert (data->error_info->best_error);
+ complete_connection_with_error (data, g_steal_pointer (&data->error_info->best_error));
}
/* Enumeration should never trigger again, drop our ref */
@@ -1901,12 +1952,11 @@ g_socket_client_enumerator_callback (GObject *object,
data->enumerated_at_least_once = TRUE;
}
- g_clear_error (&data->last_error);
-
- socket = create_socket (data->client, address, &data->last_error);
+ socket = create_socket (data->client, address, &data->error_info->tmp_error);
if (socket == NULL)
{
g_object_unref (address);
+ consider_tmp_error (data->error_info, G_SOCKET_CLIENT_CONNECTING);
enumerator_next_async (data, FALSE);
return;
}
@@ -1978,6 +2028,7 @@ g_socket_client_connect_async (GSocketClient *client,
data = g_slice_new0 (GSocketClientAsyncConnectData);
data->client = client;
data->connectable = g_object_ref (connectable);
+ data->error_info = socket_client_error_info_new ();
if (can_use_proxy (client))
{
--
1.8.3.1

View File

@ -0,0 +1,58 @@
From 35bb69bc47fecdf54de887a0c29a0889b79663a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= <crrodriguez@opensuse.org>
Date: Wed, 29 Jul 2020 12:10:08 -0400
Subject: [PATCH 0985/1095] gsocketclient: set IP_BIND_ADDRESS_NO_PORT if
binding to local address
The linux kernel does not know that the socket will be used
for connect or listen and if you bind() to a local address it must
reserve a random port (if port == 0) at bind() time, making very easy
to exhaust the ~32k port range, setting IP_BIND_ADDRESS_NO_PORT tells
the kernel to choose random port at connect() time instead, when the
full 4-tuple is known.
reason:gsocketclient: set IP_BIND_ADDRESS_NO_PORT if binding to local address
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/35bb69bc47fecdf54de887a0c29a0889b79663a1
---
gio/gsocketclient.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index c994330..ca01b68 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -24,6 +24,10 @@
#include "config.h"
#include "gsocketclient.h"
+#ifndef G_OS_WIN32
+#include <netinet/in.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
@@ -39,6 +43,7 @@
#include <gio/gioerror.h>
#include <gio/gsocket.h>
#include <gio/gnetworkaddress.h>
+#include <gio/gnetworking.h>
#include <gio/gnetworkservice.h>
#include <gio/gproxy.h>
#include <gio/gproxyresolver.h>
@@ -142,6 +147,10 @@ create_socket (GSocketClient *client,
if (client->priv->local_address)
{
+#ifdef IP_BIND_ADDRESS_NO_PORT
+ g_socket_set_option (socket, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, 1, NULL);
+#endif
+
if (!g_socket_bind (socket,
client->priv->local_address,
FALSE,
--
1.8.3.1

View File

@ -0,0 +1,35 @@
From b639687b60fb0bd1e2addfa960c3532bf3ebf2a3 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Tue, 18 Aug 2020 09:33:06 +0100
Subject: [PATCH 0861/1095] gtestutils: Fix a minor memory leak
Coverity CID: #1430603
Signed-off-by: Philip Withnall <withnall@endlessm.com>
reason:gtestutils: Fix a minor memory leak
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/b639687b60fb0bd1e2addfa960c3532bf3ebf2a3
---
glib/gtestutils.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index 8ca995c..3b03e98 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -1530,7 +1530,10 @@ void
test_prgname = g_path_get_basename (g_get_prgname ());
if (*test_prgname == '\0')
- test_prgname = g_strdup ("unknown");
+ {
+ g_free (test_prgname);
+ test_prgname = g_strdup ("unknown");
+ }
tmpl = g_strdup_printf ("test_%s_XXXXXX", test_prgname);
g_free (test_prgname);
--
1.8.3.1

View File

@ -0,0 +1,67 @@
From 8c76bec77985be7f4c81a052ec649232341369f6 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Wed, 30 Sep 2020 16:16:11 +0100
Subject: [PATCH] gthread: Destroy value after replacing it in
g_private_replace()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the old value is destroyed before updating the TLS value in pthreads
(or the Windows equivalent) then theres a risk of infinite recursion if
`g_private_replace()` is called from within the `GDestroyNotify`.
Avoid that by destroying the old value after doing the TLS update.
Thanks to Matthias Clasen for diagnosing the issue.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2210
reason:gtestutils: Destroy value after replacing it in g_private_replace()
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/8c76bec77985be7f4c81a052ec649232341369f6
---
glib/gthread-posix.c | 5 +++--
glib/gthread-win32.c | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c
index f360559..f09f58a 100644
--- a/glib/gthread-posix.c
+++ b/glib/gthread-posix.c
@@ -1116,11 +1116,12 @@ g_private_replace (GPrivate *key,
gint status;
old = pthread_getspecific (*impl);
- if (old && key->notify)
- key->notify (old);
if G_UNLIKELY ((status = pthread_setspecific (*impl, value)) != 0)
g_thread_abort (status, "pthread_setspecific");
+
+ if (old && key->notify)
+ key->notify (old);
}
/* {{{1 GThread */
diff --git a/glib/gthread-win32.c b/glib/gthread-win32.c
index 54f74f2..0c37dc6 100644
--- a/glib/gthread-win32.c
+++ b/glib/gthread-win32.c
@@ -373,9 +373,9 @@ g_private_replace (GPrivate *key,
gpointer old;
old = TlsGetValue (impl);
+ TlsSetValue (impl, value);
if (old && key->notify)
key->notify (old);
- TlsSetValue (impl, value);
}
/* {{{1 GThread */
--
1.8.3.1

View File

@ -0,0 +1,175 @@
From 25d950b61f92f25cc9ab20d683aa4d6969f93098 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Thu, 16 Jul 2020 12:41:49 -0700
Subject: [PATCH 0734/1095] gtimezone: support footers in TZif files
Since tzcode95f (1995), TZif files have had a trailing
TZ string, used for timestamps after the last transition.
This string is specified in Internet RFC 8536 section 3.3.
init_zone_from_iana_info has ignored this string, causing it
to mishandle timestamps past the year 2038. With zic's new -b
slim flag, init_zone_from_iana_info would even mishandle current
timestamps. Fix this by parsing the trailing TZ string and adding
its transitions.
Closes #2129
reason:support footers in TZif files
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/25d950b61f92f25cc9ab20d683aa4d6969f93098
---
glib/gtimezone.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 93 insertions(+), 3 deletions(-)
diff --git a/glib/gtimezone.c b/glib/gtimezone.c
index 80f3882..fcf1057 100644
--- a/glib/gtimezone.c
+++ b/glib/gtimezone.c
@@ -203,6 +203,10 @@ static GTimeZone *tz_local = NULL;
there's no point in getting carried
away. */
+#ifdef G_OS_UNIX
+static GTimeZone *parse_footertz (const gchar *, size_t);
+#endif
+
/**
* g_time_zone_unref:
* @tz: a #GTimeZone
@@ -555,7 +559,12 @@ init_zone_from_iana_info (GTimeZone *gtz,
guint8 *tz_transitions, *tz_type_index, *tz_ttinfo;
guint8 *tz_abbrs;
gsize timesize = sizeof (gint32);
- const struct tzhead *header = g_bytes_get_data (zoneinfo, &size);
+ gconstpointer header_data = g_bytes_get_data (zoneinfo, &size);
+ const gchar *data = header_data;
+ const struct tzhead *header = header_data;
+ GTimeZone *footertz = NULL;
+ guint extra_time_count = 0, extra_type_count = 0;
+ gint64 last_explicit_transition_time;
g_return_if_fail (size >= sizeof (struct tzhead) &&
memcmp (header, "TZif", 4) == 0);
@@ -576,6 +585,30 @@ init_zone_from_iana_info (GTimeZone *gtz,
time_count = guint32_from_be(header->tzh_timecnt);
type_count = guint32_from_be(header->tzh_typecnt);
+ if (header->tzh_version >= '2')
+ {
+ const gchar *footer = (((const gchar *) (header + 1))
+ + guint32_from_be(header->tzh_ttisgmtcnt)
+ + guint32_from_be(header->tzh_ttisstdcnt)
+ + 12 * guint32_from_be(header->tzh_leapcnt)
+ + 9 * time_count
+ + 6 * type_count
+ + guint32_from_be(header->tzh_charcnt));
+ const gchar *footerlast;
+ size_t footerlen;
+ g_return_if_fail (footer <= data + size - 2 && footer[0] == '\n');
+ footerlast = memchr (footer + 1, '\n', data + size - (footer + 1));
+ g_return_if_fail (footerlast);
+ footerlen = footerlast + 1 - footer;
+ if (footerlen != 2)
+ {
+ footertz = parse_footertz (footer, footerlen);
+ g_return_if_fail (footertz);
+ extra_type_count = footertz->t_info->len;
+ extra_time_count = footertz->transitions->len;
+ }
+ }
+
tz_transitions = ((guint8 *) (header) + sizeof (*header));
tz_type_index = tz_transitions + timesize * time_count;
tz_ttinfo = tz_type_index + time_count;
@@ -583,9 +616,9 @@ init_zone_from_iana_info (GTimeZone *gtz,
gtz->name = g_steal_pointer (&identifier);
gtz->t_info = g_array_sized_new (FALSE, TRUE, sizeof (TransitionInfo),
- type_count);
+ type_count + extra_type_count);
gtz->transitions = g_array_sized_new (FALSE, TRUE, sizeof (Transition),
- time_count);
+ time_count + extra_time_count);
for (index = 0; index < type_count; index++)
{
@@ -604,11 +637,46 @@ init_zone_from_iana_info (GTimeZone *gtz,
trans.time = gint64_from_be (((gint64_be*)tz_transitions)[index]);
else
trans.time = gint32_from_be (((gint32_be*)tz_transitions)[index]);
+ last_explicit_transition_time = trans.time;
trans.info_index = tz_type_index[index];
g_assert (trans.info_index >= 0);
g_assert ((guint) trans.info_index < gtz->t_info->len);
g_array_append_val (gtz->transitions, trans);
}
+
+ if (footertz)
+ {
+ /* Append footer time types. Don't bother to coalesce
+ duplicates with existing time types. */
+ for (index = 0; index < extra_type_count; index++)
+ {
+ TransitionInfo t_info;
+ TransitionInfo *footer_t_info
+ = &g_array_index (footertz->t_info, TransitionInfo, index);
+ t_info.gmt_offset = footer_t_info->gmt_offset;
+ t_info.is_dst = footer_t_info->is_dst;
+ t_info.abbrev = g_steal_pointer (&footer_t_info->abbrev);
+ g_array_append_val (gtz->t_info, t_info);
+ }
+
+ /* Append footer transitions that follow the last explicit
+ transition. */
+ for (index = 0; index < extra_time_count; index++)
+ {
+ Transition *footer_transition
+ = &g_array_index (footertz->transitions, Transition, index);
+ if (time_count <= 0
+ || last_explicit_transition_time < footer_transition->time)
+ {
+ Transition trans;
+ trans.time = footer_transition->time;
+ trans.info_index = type_count + footer_transition->info_index;
+ g_array_append_val (gtz->transitions, trans);
+ }
+ }
+
+ g_time_zone_unref (footertz);
+ }
}
#elif defined (G_OS_WIN32)
@@ -1504,6 +1572,28 @@ rules_from_identifier (const gchar *identifier,
return create_ruleset_from_rule (rules, &tzr);
}
+#ifdef G_OS_UNIX
+static GTimeZone *
+parse_footertz (const gchar *footer, size_t footerlen)
+{
+ gchar *tzstring = g_strndup (footer + 1, footerlen - 2);
+ GTimeZone *footertz = NULL;
+ gchar *ident;
+ TimeZoneRule *rules;
+ guint rules_num = rules_from_identifier (tzstring, &ident, &rules);
+ g_free (ident);
+ g_free (tzstring);
+ if (rules_num > 1)
+ {
+ footertz = g_slice_new0 (GTimeZone);
+ init_zone_from_rules (footertz, rules, rules_num, NULL);
+ footertz->ref_count++;
+ }
+ g_free (rules);
+ return footertz;
+}
+#endif
+
/* Construction {{{1 */
/**
* g_time_zone_new:
--
1.8.3.1

View File

@ -0,0 +1,41 @@
From ea64c739239faea463f3cb9154a12cc4532ba525 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Wed, 18 Mar 2020 09:15:59 +0000
Subject: [PATCH 0506/1095] gvdb-builder: Initialise some memory to zero in the
bloom filter
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Until a bloom filter is implemented, we need to ensure that all the
memory returned by `file_builder_allocate()` is initialised, since its
not initialised at allocation time.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2
reason:Initialise some memory to zero in the bloom filter
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/ea64c739239faea463f3cb9154a12cc4532ba525
---
gio/gvdb/gvdb-builder.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gio/gvdb/gvdb-builder.c b/gio/gvdb/gvdb-builder.c
index 2383e60..aa29d22 100644
--- a/gio/gvdb/gvdb-builder.c
+++ b/gio/gvdb/gvdb-builder.c
@@ -339,6 +339,8 @@ file_builder_allocate_for_hash (FileBuilder *fb,
#undef chunk
memset (*bloom_filter, 0, n_bloom_words * sizeof (guint32_le));
+ memset (*hash_buckets, 0, n_buckets * sizeof (guint32_le));
+ memset (*hash_items, 0, n_items * sizeof (struct gvdb_hash_item));
/* NOTE - the code to actually fill in the bloom filter here is missing.
* Patches welcome!
--
2.23.0

View File

@ -0,0 +1,61 @@
From 4b3183435bc14daca21bced6d51ac81493649c11 Mon Sep 17 00:00:00 2001
From: Will Thompson <wjt@endlessm.com>
Date: Mon, 13 Jul 2020 16:26:44 +0100
Subject: [PATCH 0722/1095] portal: Read /.flatpak-info in thread-safe fashion
There is no guarantee that this function would not be called
concurrently. Particularly since flatpak_info_read was set to TRUE
before /.flatpak-info is actually read from disk, there is a potential
race where a second thread would return default values for the various
flags set from that file.
Fixes #2159
reason:Read /.flatpak-info in thread-safe fashion
Conflict:NA
Reference:https://github.com/GNOME/glib/commit/4b3183435bc14daca21bced6d51ac81493649c11
---
gio/gportalsupport.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/gio/gportalsupport.c b/gio/gportalsupport.c
index b0a94b3..233f6af 100644
--- a/gio/gportalsupport.c
+++ b/gio/gportalsupport.c
@@ -20,7 +20,6 @@
#include "gportalsupport.h"
-static gboolean flatpak_info_read;
static gboolean use_portal;
static gboolean network_available;
static gboolean dconf_access;
@@ -28,13 +27,12 @@ static gboolean dconf_access;
static void
read_flatpak_info (void)
{
+ static gsize flatpak_info_read = 0;
const gchar *path = "/.flatpak-info";
- if (flatpak_info_read)
+ if (!g_once_init_enter (&flatpak_info_read))
return;
- flatpak_info_read = TRUE;
-
if (g_file_test (path, G_FILE_TEST_EXISTS))
{
GKeyFile *keyfile;
@@ -77,6 +75,8 @@ read_flatpak_info (void)
network_available = TRUE;
dconf_access = TRUE;
}
+
+ g_once_init_leave (&flatpak_info_read, 1);
}
gboolean
--
1.8.3.1

View File

@ -1,6 +1,6 @@
Name: glib2
Version: 2.62.5
Release: 6
Release: 7
Summary: The core library that forms the basis for projects such as GTK+ and GNOME
License: LGPLv2+
URL: http://www.gtk.org
@ -8,20 +8,46 @@ Source0: http://download.gnome.org/sources/glib/2.62/glib-%{version}.tar.
Patch9001: fix-accidentally-delete-temp-file-within-dtrace.patch
Patch6000: backport-CVE-2020-35457.patch
Patch6001: backport-CVE-2021-27218.patch
Patch6002: backport-CVE-2021-27219.patch
Patch6003: backport-0001-CVE-2021-28153.patch
Patch6004: backport-0002-CVE-2021-28153.patch
Patch6005: backport-0003-CVE-2021-28153.patch
Patch6006: backport-0004-CVE-2021-28153.patch
Patch6007: backport-0005-CVE-2021-28153.patch
Patch6001: backport-glib-ensure-consistent-abort-on-OOM-with-g-vasprintf-its-callers.patch
Patch6002: backport-gparamspecs-Fix-type-class-leaks-on-error-handling-paths.patch
Patch6003: backport-glocalfileinfo-Fix-minor-leak-on-error-handling-path-for-xattrs.patch
Patch6004: backport-gbookmarkfile-Fix-a-minor-leak-on-an-error-path.patch
Patch6005: backport-gvdb-builder-Initialise-some-memory-to-zero-in-the-bloom-filter.patch
Patch6006: backport-gfileutils-Correct-operator-precedence-to-avoid-undefined-pointer-maths.patch
Patch6007: backport-glib-supp-Suppress-calloc-variant-of-g-get-charset.patch
Patch6008: backport-Fix-giomodule-cache-being-wrongly-considered-stale.patch
Patch6009: backport-glocalfileinfo-Correct-an-off-by-one-error-when-unescaping-hex.patch
Patch6010: backport-portal-Read-flatpak-info-in-thread-safe-fashion.patch
Patch6011: backport-gtimezone-support-footers-in-TZif-files.patch
Patch6012: backport-gtestutils-Fix-a-minor-memory-leak.patch
Patch6013: backport-gthread-Destroy-value-after-replacing-it.patch
Patch6014: backport-gsocketclient-set-IP-BIND-ADDRESS-NO-PORT-if-binding.patch
Patch6015: backport-gsocketclient-emit-RESOLVING-RESOLVED-events-only-once.patch
Patch6016: backport-gsocketclient-Crash-on-error-if-error-is-missing.patch
Patch6017: backport-gsocketclient-return-best-errors-possible.patch
Patch6018: backport-gsignal-Plug-g-signal-connect-object-leak.patch
Patch6019: backport-Fix-the-6-days-until-the-end-of-the-month-bug.patch
Patch6020: backport-gsocketclient-fix-crash-when-async-connectio-step-fails.patch
Patch6021: backport-CVE-2021-27218.patch
Patch6022: backport-CVE-2021-27219.patch
Patch6023: backport-0001-CVE-2021-28153.patch
Patch6024: backport-0002-CVE-2021-28153.patch
Patch6025: backport-0003-CVE-2021-28153.patch
Patch6026: backport-0004-CVE-2021-28153.patch
Patch6027: backport-0005-CVE-2021-28153.patch
BuildRequires: chrpath gcc gcc-c++ gettext gtk-doc perl-interpreter
BuildRequires: chrpath gcc gcc-c++ gettext perl-interpreter
%ifnarch i686
BUildRequires: gtk-doc
%endif
BUildRequires: glibc-devel libattr-devel libselinux-devel meson
BuildRequires: systemtap-sdt-devel pkgconfig(libelf) pkgconfig(libffi)
BuildRequires: pkgconfig(libpcre) pkgconfig(mount) pkgconfig(zlib)
BuildRequires: python3-devel gamin-devel
Requires: %{name}-help
%ifarch i686
BuildRequires: libxslt
%endif
Provides: %{name}-fam = %{version}-%{release}
Obsoletes: %{name}-fam < %{version}-%{release}
@ -48,6 +74,7 @@ Obsoletes: %{name}-tests < %{version}-%{release}
%description devel
Development and test files for the GLib library.
%ifnarch i686
%package help
Summary: help document for the glib2 package
Buildarch: noarch
@ -56,14 +83,20 @@ Obsoletes: %{name}-doc < %{version}-%{release}
%description help
help document for the glib2 package.
%endif
%prep
%autosetup -n glib-%{version} -p1
%build
rm glib/pcre/*.[ch]
%meson --default-library=both -Dman=true -Ddtrace=true \
-Dsystemtap=true -Dgtk_doc=true -Dfam=true -Dinstalled_tests=true
%meson --default-library=both -Ddtrace=true \
%ifarch i686
-Dman=false -Dgtk_doc=false \
%else
-Dman=true -Dgtk_doc=true \
%endif
-Dsystemtap=true -Dfam=true -Dinstalled_tests=true
%meson_build
@ -81,6 +114,16 @@ mv %{buildroot}%{_bindir}/gio-querymodules %{buildroot}%{_bindir}/gio-querymodu
touch %{buildroot}%{_libdir}/gio/modules/giomodule.cache
%find_lang glib20
#remove rpath
chrpath -d %{buildroot}%{_libexecdir}/installed-tests/glib/gdbus-peer
mkdir -p $RPM_BUILD_ROOT/etc/ld.so.conf.d
echo %{_libexecdir}/installed-tests/glib > $RPM_BUILD_ROOT/etc/ld.so.conf.d/%{name}-%{_arch}.conf
%ldconfig_scriptlets devel
%transfiletriggerin -- %{_libdir}/gio/modules
gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules &> /dev/null || :
@ -118,6 +161,8 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%{_bindir}/gapplication
%files devel
%defattr(-,root,root)
%config(noreplace) /etc/ld.so.conf.d/*
%{_libdir}/lib*.so
%{_libdir}/glib-2.0
%{_libdir}/pkgconfig/*
@ -145,13 +190,24 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%{_bindir}/glib-compile-resources
%{_bindir}/gresource
%attr (0755, root, root) %{_bindir}/gtester-report
%ifarch i686
%exclude %{_libexecdir}/installed-tests/glib/libgdbus-example-objectmanager.a
%exclude %{_datadir}/glib-2.0/codegen/__pycache__
%exclude %{_datadir}/glib-2.0/gdb/__pycache__
%exclude %{_datadir}/installed-tests/glib/static-link.test
%endif
%ifnarch i686
%files help
%defattr(-,root,root)
%{_mandir}/man1/*
%doc %{_datadir}/gtk-doc/html/*
%endif
%changelog
* Fri May 21 2021 hanhui<hanhui15@huawei.com> - 2.62.5-7
- add i686 optionsround community patches
* Tue Apr 13 2021 hanhui<hanhui15@huawei.com> - 2.62.5-6
- Type:cve
- Id:CVE-2021-28153
@ -225,4 +281,4 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
- DESC:fix CVE-2019-12450 CVE-2019-13012
* Thu Sep 19 2019 Lijin Yang <yanglijin@huawei.com> - 2.58.1-2
- Package init
- Package init