diff --git a/glib-2.74.1-revert-fd-handling.patch b/glib-2.74.1-revert-fd-handling.patch new file mode 100644 index 0000000000000000000000000000000000000000..2e996235d10f77ece5d56f80fa909fe1763baf71 --- /dev/null +++ b/glib-2.74.1-revert-fd-handling.patch @@ -0,0 +1,150 @@ +From 2a36bb4b7e46f9ac043561c61f9a790786a5440c Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 28 Oct 2022 11:21:04 -0400 +Subject: [PATCH 1/2] Revert "Handling collision between standard i/o file + descriptors and newly created ones" + +g_unix_open_pipe tries to avoid the standard io fd range +when getting pipe fds. This turns out to be a bad idea because +certain buggy programs rely on it using that range. + +This reverts commit d9ba6150909818beb05573f54f26232063492c5b + +Closes: #2795 +Reopens: #16 +--- + glib/glib-unix.c | 24 ------------------------ + 1 file changed, 24 deletions(-) + +diff --git a/glib/glib-unix.c b/glib/glib-unix.c +index 4710c51168..bc152d7663 100644 +--- a/glib/glib-unix.c ++++ b/glib/glib-unix.c +@@ -108,17 +108,6 @@ g_unix_open_pipe (int *fds, + ecode = pipe2 (fds, pipe2_flags); + if (ecode == -1 && errno != ENOSYS) + return g_unix_set_error_from_errno (error, errno); +- /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */ +- else if (fds[0] < 3 || fds[1] < 3) +- { +- int old_fds[2] = { fds[0], fds[1] }; +- gboolean result = g_unix_open_pipe (fds, flags, error); +- close (old_fds[0]); +- close (old_fds[1]); +- +- if (!result) +- g_unix_set_error_from_errno (error, errno); +- } + else if (ecode == 0) + return TRUE; + /* Fall through on -ENOSYS, we must be running on an old kernel */ +@@ -127,19 +116,6 @@ g_unix_open_pipe (int *fds, + ecode = pipe (fds); + if (ecode == -1) + return g_unix_set_error_from_errno (error, errno); +- /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */ +- else if (fds[0] < 3 || fds[1] < 3) +- { +- int old_fds[2] = { fds[0], fds[1] }; +- gboolean result = g_unix_open_pipe (fds, flags, error); +- close (old_fds[0]); +- close (old_fds[1]); +- +- if (!result) +- g_unix_set_error_from_errno (error, errno); +- +- return result; +- } + + if (flags == 0) + return TRUE; +-- +GitLab + + +From 1c1c452ff2030135e4abc2816e81b7078a845580 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 31 Oct 2022 09:17:55 -0400 +Subject: [PATCH 2/2] glib-unix: Add test to make sure g_unix_open_pipe will + intrude standard range + +Now that we know it's a bad idea to avoid the standard io fd range +when getting pipe fds for g_unix_open_pipe, we should test to make sure +we don't inadvertently try to do it again. + +This commit adds that test. +--- + glib/tests/unix.c | 41 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +diff --git a/glib/tests/unix.c b/glib/tests/unix.c +index 2112cab6bf..6c4a59dee7 100644 +--- a/glib/tests/unix.c ++++ b/glib/tests/unix.c +@@ -24,8 +24,11 @@ + #include "config.h" + + #include "glib-unix.h" ++#include "gstdio.h" ++ + #include + #include ++#include + + static void + test_pipe (void) +@@ -52,6 +55,43 @@ test_pipe (void) + g_assert (g_str_has_prefix (buf, "hello")); + } + ++static void ++test_pipe_stdio_overwrite (void) ++{ ++ GError *error = NULL; ++ int pipefd[2], ret; ++ gboolean res; ++ int stdin_fd; ++ ++ ++ g_test_summary ("Test that g_unix_open_pipe() will use the first available FD, even if it’s stdin/stdout/stderr"); ++ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2795"); ++ ++ stdin_fd = dup (STDIN_FILENO); ++ g_assert_cmpint (stdin_fd, >, 0); ++ ++ g_close (STDIN_FILENO, &error); ++ g_assert_no_error (error); ++ ++ res = g_unix_open_pipe (pipefd, FD_CLOEXEC, &error); ++ g_assert_no_error (error); ++ g_assert_true (res); ++ ++ g_assert_cmpint (pipefd[0], ==, STDIN_FILENO); ++ ++ g_close (pipefd[0], &error); ++ g_assert_no_error (error); ++ ++ g_close (pipefd[1], &error); ++ g_assert_no_error (error); ++ ++ ret = dup2 (stdin_fd, STDIN_FILENO); ++ g_assert_cmpint (ret, >=, 0); ++ ++ g_close (stdin_fd, &error); ++ g_assert_no_error (error); ++} ++ + static void + test_error (void) + { +@@ -337,6 +377,7 @@ main (int argc, + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/glib-unix/pipe", test_pipe); ++ g_test_add_func ("/glib-unix/pipe-stdio-overwrite", test_pipe_stdio_overwrite); + g_test_add_func ("/glib-unix/error", test_error); + g_test_add_func ("/glib-unix/nonblocking", test_nonblocking); + g_test_add_func ("/glib-unix/sighup", test_sighup); +-- +GitLab + diff --git a/glib-2.73.2.tar.xz b/glib-2.74.1.tar.xz similarity index 41% rename from glib-2.73.2.tar.xz rename to glib-2.74.1.tar.xz index 409fd3dd7c7b124187a15a8fd108cf3048836894..24a7d6b64e5ce961cd3254ea7a4853fa62c8d0ed 100644 Binary files a/glib-2.73.2.tar.xz and b/glib-2.74.1.tar.xz differ diff --git a/glib2.spec b/glib2.spec index f06290b3ceb666f97cca9807f293b3ececa34a31..da3406d9be9cfe8555e39c5387c94067753e990e 100644 --- a/glib2.spec +++ b/glib2.spec @@ -1,16 +1,16 @@ %define anolis_release 1 +%define url_ver %(echo %{version} | cut -d. -f1,2) Name: glib2 -Version: 2.73.2 +Version: 2.74.1 Release: %{anolis_release}%{?dist} Summary: A library of handy utility functions License: LGPLv2+ URL: https://www.gtk.org -Source0: https://download.gnome.org/sources/glib/2.70/glib-%{version}.tar.xz - -# backend compact -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903 -Patch0: gnutls-hmac.patch +Source0: https://download.gnome.org/sources/glib/%{url_ver}/glib-%{version}.tar.xz +# upstream patch from +# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3039 +Patch1: glib-2.74.1-revert-fd-handling.patch BuildRequires: chrpath BuildRequires: gcc @@ -34,11 +34,6 @@ BuildRequires: pkgconfig(zlib) BuildRequires: python3-devel BuildRequires: /usr/bin/marshalparser -# For gnutls-hmac.patch. We now dlopen libgnutls.so.30 so that we can build a -# static glib2 without depending on a static build of GnuTLS as well. This will -# ensure we notice if the GnuTLS soname bumps, so that we can update our patch. -Requires: libgnutls.so.30()(64bit) - # Remove gamin dependency Obsoletes: glib2-fam < 2.67.1-3 @@ -56,7 +51,7 @@ as an event loop, threads, dynamic loading, and an object system. %package devel Summary: A library of handy utility functions -Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name} = %{version}-%{release} %description devel The glib2-devel package includes the header files for the GLib library. @@ -78,7 +73,7 @@ The %{name}-static subpackage contains static libraries for %{name}. %package tests Summary: Tests for the glib2 package -Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name} = %{version}-%{release} %description tests The glib2-tests package contains tests that can be used to verify @@ -96,7 +91,6 @@ the functionality of the installed glib2 package. -Dglib_debug=disabled \ -Dgtk_doc=true \ -Dinstalled_tests=true \ - -Dgnutls=true \ --default-library=both \ %{nil} @@ -162,6 +156,7 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_bindir}/gsettings %{_bindir}/gdbus %{_bindir}/gapplication +%{_libexecdir}/gio-launch-desktop %{_mandir}/man1/gio.1* %{_mandir}/man1/gio-querymodules.1* %{_mandir}/man1/glib-compile-schemas.1* @@ -219,6 +214,10 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_datadir}/installed-tests %changelog +* Wed Nov 23 2022 Funda Wang - 2.74.1-1 +- New version 2.74.1 +- Drop gnutls-hmac patch as it won't be accepted upstream + * Mon Aug 15 2022 mgb01105731 - 2.73.2-1 - update to 2.73.2 - Replace pcre to pcre2 diff --git a/gnutls-hmac.patch b/gnutls-hmac.patch deleted file mode 100644 index 16b02b7dd1a48449901e169843f30ad7107b5ca3..0000000000000000000000000000000000000000 --- a/gnutls-hmac.patch +++ /dev/null @@ -1,1090 +0,0 @@ -From 4fb2d2ba67cbf97a728ef5fe8b29e1f3df0a7f85 Mon Sep 17 00:00:00 2001 -From: Colin Walters -Date: Fri, 7 Jun 2019 18:44:43 +0000 -Subject: [PATCH 1/4] ghmac: Split off wrapper functions into ghmac-utils.c - -Prep for adding a GnuTLS HMAC implementation; these are just -utility functions that call the "core" API. ---- - glib/ghmac-utils.c | 145 +++++++++++++++++++++++++++++++++++++++++++++ - glib/ghmac.c | 112 ---------------------------------- - glib/meson.build | 1 + - 3 files changed, 146 insertions(+), 112 deletions(-) - create mode 100644 glib/ghmac-utils.c - -diff --git a/glib/ghmac-utils.c b/glib/ghmac-utils.c -new file mode 100644 -index 000000000..a17359ff1 ---- /dev/null -+++ b/glib/ghmac-utils.c -@@ -0,0 +1,145 @@ -+/* ghmac.h - data hashing functions -+ * -+ * Copyright (C) 2011 Collabora Ltd. -+ * Copyright (C) 2019 Red Hat, Inc. -+ * -+ * 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 . -+ */ -+ -+#include "config.h" -+ -+#include -+ -+#include "ghmac.h" -+ -+#include "glib/galloca.h" -+#include "gatomic.h" -+#include "gslice.h" -+#include "gmem.h" -+#include "gstrfuncs.h" -+#include "gtestutils.h" -+#include "gtypes.h" -+#include "glibintl.h" -+ -+/** -+ * g_compute_hmac_for_data: -+ * @digest_type: a #GChecksumType to use for the HMAC -+ * @key: (array length=key_len): the key to use in the HMAC -+ * @key_len: the length of the key -+ * @data: (array length=length): binary blob to compute the HMAC of -+ * @length: length of @data -+ * -+ * Computes the HMAC for a binary @data of @length. This is a -+ * convenience wrapper for g_hmac_new(), g_hmac_get_string() -+ * and g_hmac_unref(). -+ * -+ * The hexadecimal string returned will be in lower case. -+ * -+ * Returns: the HMAC of the binary data as a string in hexadecimal. -+ * The returned string should be freed with g_free() when done using it. -+ * -+ * Since: 2.30 -+ */ -+gchar * -+g_compute_hmac_for_data (GChecksumType digest_type, -+ const guchar *key, -+ gsize key_len, -+ const guchar *data, -+ gsize length) -+{ -+ GHmac *hmac; -+ gchar *retval; -+ -+ g_return_val_if_fail (length == 0 || data != NULL, NULL); -+ -+ hmac = g_hmac_new (digest_type, key, key_len); -+ if (!hmac) -+ return NULL; -+ -+ g_hmac_update (hmac, data, length); -+ retval = g_strdup (g_hmac_get_string (hmac)); -+ g_hmac_unref (hmac); -+ -+ return retval; -+} -+ -+/** -+ * g_compute_hmac_for_bytes: -+ * @digest_type: a #GChecksumType to use for the HMAC -+ * @key: the key to use in the HMAC -+ * @data: binary blob to compute the HMAC of -+ * -+ * Computes the HMAC for a binary @data. This is a -+ * convenience wrapper for g_hmac_new(), g_hmac_get_string() -+ * and g_hmac_unref(). -+ * -+ * The hexadecimal string returned will be in lower case. -+ * -+ * Returns: the HMAC of the binary data as a string in hexadecimal. -+ * The returned string should be freed with g_free() when done using it. -+ * -+ * Since: 2.50 -+ */ -+gchar * -+g_compute_hmac_for_bytes (GChecksumType digest_type, -+ GBytes *key, -+ GBytes *data) -+{ -+ gconstpointer byte_data; -+ gsize length; -+ gconstpointer key_data; -+ gsize key_len; -+ -+ g_return_val_if_fail (data != NULL, NULL); -+ g_return_val_if_fail (key != NULL, NULL); -+ -+ byte_data = g_bytes_get_data (data, &length); -+ key_data = g_bytes_get_data (key, &key_len); -+ return g_compute_hmac_for_data (digest_type, key_data, key_len, byte_data, length); -+} -+ -+ -+/** -+ * g_compute_hmac_for_string: -+ * @digest_type: a #GChecksumType to use for the HMAC -+ * @key: (array length=key_len): the key to use in the HMAC -+ * @key_len: the length of the key -+ * @str: the string to compute the HMAC for -+ * @length: the length of the string, or -1 if the string is nul-terminated -+ * -+ * Computes the HMAC for a string. -+ * -+ * The hexadecimal string returned will be in lower case. -+ * -+ * Returns: the HMAC as a hexadecimal string. -+ * The returned string should be freed with g_free() -+ * when done using it. -+ * -+ * Since: 2.30 -+ */ -+gchar * -+g_compute_hmac_for_string (GChecksumType digest_type, -+ const guchar *key, -+ gsize key_len, -+ const gchar *str, -+ gssize length) -+{ -+ g_return_val_if_fail (length == 0 || str != NULL, NULL); -+ -+ if (length < 0) -+ length = strlen (str); -+ -+ return g_compute_hmac_for_data (digest_type, key, key_len, -+ (const guchar *) str, length); -+} -diff --git a/glib/ghmac.c b/glib/ghmac.c -index 7ad28d6f0..516b01b24 100644 ---- a/glib/ghmac.c -+++ b/glib/ghmac.c -@@ -353,115 +353,3 @@ g_hmac_get_digest (GHmac *hmac, - g_checksum_update (hmac->digesto, buffer, len_signed); - g_checksum_get_digest (hmac->digesto, buffer, digest_len); - } -- --/** -- * g_compute_hmac_for_data: -- * @digest_type: a #GChecksumType to use for the HMAC -- * @key: (array length=key_len): the key to use in the HMAC -- * @key_len: the length of the key -- * @data: (array length=length): binary blob to compute the HMAC of -- * @length: length of @data -- * -- * Computes the HMAC for a binary @data of @length. This is a -- * convenience wrapper for g_hmac_new(), g_hmac_get_string() -- * and g_hmac_unref(). -- * -- * The hexadecimal string returned will be in lower case. -- * -- * Returns: the HMAC of the binary data as a string in hexadecimal. -- * The returned string should be freed with g_free() when done using it. -- * -- * Since: 2.30 -- */ --gchar * --g_compute_hmac_for_data (GChecksumType digest_type, -- const guchar *key, -- gsize key_len, -- const guchar *data, -- gsize length) --{ -- GHmac *hmac; -- gchar *retval; -- -- g_return_val_if_fail (length == 0 || data != NULL, NULL); -- -- hmac = g_hmac_new (digest_type, key, key_len); -- if (!hmac) -- return NULL; -- -- g_hmac_update (hmac, data, length); -- retval = g_strdup (g_hmac_get_string (hmac)); -- g_hmac_unref (hmac); -- -- return retval; --} -- --/** -- * g_compute_hmac_for_bytes: -- * @digest_type: a #GChecksumType to use for the HMAC -- * @key: the key to use in the HMAC -- * @data: binary blob to compute the HMAC of -- * -- * Computes the HMAC for a binary @data. This is a -- * convenience wrapper for g_hmac_new(), g_hmac_get_string() -- * and g_hmac_unref(). -- * -- * The hexadecimal string returned will be in lower case. -- * -- * Returns: the HMAC of the binary data as a string in hexadecimal. -- * The returned string should be freed with g_free() when done using it. -- * -- * Since: 2.50 -- */ --gchar * --g_compute_hmac_for_bytes (GChecksumType digest_type, -- GBytes *key, -- GBytes *data) --{ -- gconstpointer byte_data; -- gsize length; -- gconstpointer key_data; -- gsize key_len; -- -- g_return_val_if_fail (data != NULL, NULL); -- g_return_val_if_fail (key != NULL, NULL); -- -- byte_data = g_bytes_get_data (data, &length); -- key_data = g_bytes_get_data (key, &key_len); -- return g_compute_hmac_for_data (digest_type, key_data, key_len, byte_data, length); --} -- -- --/** -- * g_compute_hmac_for_string: -- * @digest_type: a #GChecksumType to use for the HMAC -- * @key: (array length=key_len): the key to use in the HMAC -- * @key_len: the length of the key -- * @str: the string to compute the HMAC for -- * @length: the length of the string, or -1 if the string is nul-terminated -- * -- * Computes the HMAC for a string. -- * -- * The hexadecimal string returned will be in lower case. -- * -- * Returns: the HMAC as a hexadecimal string. -- * The returned string should be freed with g_free() -- * when done using it. -- * -- * Since: 2.30 -- */ --gchar * --g_compute_hmac_for_string (GChecksumType digest_type, -- const guchar *key, -- gsize key_len, -- const gchar *str, -- gssize length) --{ -- g_return_val_if_fail (length == 0 || str != NULL, NULL); -- -- if (length < 0) -- length = strlen (str); -- -- return g_compute_hmac_for_data (digest_type, key, key_len, -- (const guchar *) str, length); --} -diff --git a/glib/meson.build b/glib/meson.build -index 6062c11a1..6624dab48 100644 ---- a/glib/meson.build -+++ b/glib/meson.build -@@ -248,6 +248,7 @@ glib_sources = files( - 'ggettext.c', - 'ghash.c', - 'ghmac.c', -+ 'ghmac-utils.c', - 'ghook.c', - 'ghostutils.c', - 'giochannel.c', --- -2.36.1 - - -From 9df3337f963e2317ae23e7fc8dabf536c218c629 Mon Sep 17 00:00:00 2001 -From: Colin Walters -Date: Fri, 7 Jun 2019 19:36:54 +0000 -Subject: [PATCH 2/4] Add a gnutls backend for GHmac - -For RHEL we want apps to use FIPS-certified crypto libraries, -and HMAC apparently counts as "keyed" and hence needs to -be validated. - -Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1630260 -Replaces: https://gitlab.gnome.org/GNOME/glib/merge_requests/897 - -This is a build-time option that backs the GHmac API with GnuTLS. -Most distributors ship glib-networking built with GnuTLS, and -most apps use glib-networking, so this isn't a net-new library -in most cases. - -======================================================================= - -mcatanzaro note: - -I've updated Colin's original patch with several enhancements: - -Implement g_hmac_copy() using gnutls_hmac_copy(), which didn't exist -when Colin developed this patch. - -Removed use of GSlice - -Better error checking in g_hmac_new(). It is possible for -gnutls_hmac_init() to fail if running in FIPS mode and an MD5 digest is -requested. In this case, we should return NULL rather than returning a -broken GHmac with a NULL gnutls_hmac_hd_t. This was leading to a later -null pointer dereference inside gnutls_hmac_update(). Applications are -responsible for checking to ensure the return value of g_hmac_new() is -not NULL since it is annotated as nullable. Added documentation to -indicate this possibility. - -Properly handle length -1 in g_hmac_update(). This means we've been -given a NUL-terminated string and should use strlen(). GnuTLS doesn't -accept -1, so let's call strlen() ourselves. - -Crash the application with g_error() if gnutls_hmac() fails for any -reason. This is necessary because g_hmac_update() is not fallible, so we -have no way to indicate error. Crashing seems better than returning the -wrong result later when g_hmac_get_string() or g_hmac_get_digest() is -later called. (Those functions are also not fallible.) Fortunately, I -don't think this error should actually be hit in practice. - -https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903 ---- - glib/gchecksum.c | 9 +- - glib/gchecksumprivate.h | 32 +++++++ - glib/ghmac-gnutls.c | 187 ++++++++++++++++++++++++++++++++++++++++ - glib/ghmac.c | 15 ++++ - glib/meson.build | 10 ++- - meson.build | 7 ++ - meson_options.txt | 5 ++ - 7 files changed, 259 insertions(+), 6 deletions(-) - create mode 100644 glib/gchecksumprivate.h - create mode 100644 glib/ghmac-gnutls.c - -diff --git a/glib/gchecksum.c b/glib/gchecksum.c -index fea7803cd..3c443840e 100644 ---- a/glib/gchecksum.c -+++ b/glib/gchecksum.c -@@ -22,7 +22,7 @@ - - #include - --#include "gchecksum.h" -+#include "gchecksumprivate.h" - - #include "gslice.h" - #include "gmem.h" -@@ -175,9 +175,9 @@ sha_byte_reverse (guint32 *buffer, - } - #endif /* G_BYTE_ORDER == G_BIG_ENDIAN */ - --static gchar * --digest_to_string (guint8 *digest, -- gsize digest_len) -+gchar * -+gchecksum_digest_to_string (guint8 *digest, -+ gsize digest_len) - { - gsize i, len = digest_len * 2; - gchar *retval; -@@ -196,6 +196,7 @@ digest_to_string (guint8 *digest, - - return retval; - } -+#define digest_to_string gchecksum_digest_to_string - - /* - * MD5 Checksum -diff --git a/glib/gchecksumprivate.h b/glib/gchecksumprivate.h -new file mode 100644 -index 000000000..86c7a3b61 ---- /dev/null -+++ b/glib/gchecksumprivate.h -@@ -0,0 +1,32 @@ -+/* gstdioprivate.h - Private GLib stdio functions -+ * -+ * Copyright 2017 Руслан Ижбулатов -+ * -+ * 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 . -+ */ -+ -+#ifndef __G_CHECKSUMPRIVATE_H__ -+#define __G_CHECKSUMPRIVATE_H__ -+ -+#include "gchecksum.h" -+ -+G_BEGIN_DECLS -+ -+gchar * -+gchecksum_digest_to_string (guint8 *digest, -+ gsize digest_len); -+ -+G_END_DECLS -+ -+#endif -\ No newline at end of file -diff --git a/glib/ghmac-gnutls.c b/glib/ghmac-gnutls.c -new file mode 100644 -index 000000000..9fb775f89 ---- /dev/null -+++ b/glib/ghmac-gnutls.c -@@ -0,0 +1,187 @@ -+/* ghmac.h - data hashing functions -+ * -+ * Copyright (C) 2011 Collabora Ltd. -+ * Copyright (C) 2019 Red Hat, Inc. -+ * -+ * 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 . -+ */ -+ -+#include "config.h" -+ -+#include -+#include -+ -+#include "ghmac.h" -+ -+#include "glib/galloca.h" -+#include "gatomic.h" -+#include "gslice.h" -+#include "gmem.h" -+#include "gstrfuncs.h" -+#include "gchecksumprivate.h" -+#include "gtestutils.h" -+#include "gtypes.h" -+#include "glibintl.h" -+ -+#ifndef HAVE_GNUTLS -+#error "build configuration error" -+#endif -+ -+struct _GHmac -+{ -+ int ref_count; -+ GChecksumType digest_type; -+ gnutls_hmac_hd_t hmac; -+ gchar *digest_str; -+}; -+ -+GHmac * -+g_hmac_new (GChecksumType digest_type, -+ const guchar *key, -+ gsize key_len) -+{ -+ gnutls_mac_algorithm_t algo; -+ GHmac *hmac = g_new0 (GHmac, 1); -+ int ret; -+ -+ hmac->ref_count = 1; -+ hmac->digest_type = digest_type; -+ -+ switch (digest_type) -+ { -+ case G_CHECKSUM_MD5: -+ algo = GNUTLS_MAC_MD5; -+ break; -+ case G_CHECKSUM_SHA1: -+ algo = GNUTLS_MAC_SHA1; -+ break; -+ case G_CHECKSUM_SHA256: -+ algo = GNUTLS_MAC_SHA256; -+ break; -+ case G_CHECKSUM_SHA384: -+ algo = GNUTLS_MAC_SHA384; -+ break; -+ case G_CHECKSUM_SHA512: -+ algo = GNUTLS_MAC_SHA512; -+ break; -+ default: -+ g_free (hmac); -+ g_return_val_if_reached (NULL); -+ } -+ -+ ret = gnutls_hmac_init (&hmac->hmac, algo, key, key_len); -+ if (ret != 0) -+ { -+ /* There is no way to report an error here, but one possible cause of -+ * failure is that the requested digest may be disabled by FIPS mode. -+ */ -+ g_free (hmac); -+ return NULL; -+ } -+ -+ return hmac; -+} -+ -+GHmac * -+g_hmac_copy (const GHmac *hmac) -+{ -+ GHmac *copy; -+ -+ g_return_val_if_fail (hmac != NULL, NULL); -+ -+ copy = g_new0 (GHmac, 1); -+ copy->ref_count = 1; -+ copy->digest_type = hmac->digest_type; -+ copy->hmac = gnutls_hmac_copy (hmac->hmac); -+ -+ /* g_hmac_copy is not allowed to fail, so we'll have to crash on error. */ -+ if (!copy->hmac) -+ g_error ("gnutls_hmac_copy failed"); -+ -+ return copy; -+} -+ -+GHmac * -+g_hmac_ref (GHmac *hmac) -+{ -+ g_return_val_if_fail (hmac != NULL, NULL); -+ -+ g_atomic_int_inc (&hmac->ref_count); -+ -+ return hmac; -+} -+ -+void -+g_hmac_unref (GHmac *hmac) -+{ -+ g_return_if_fail (hmac != NULL); -+ -+ if (g_atomic_int_dec_and_test (&hmac->ref_count)) -+ { -+ gnutls_hmac_deinit (hmac->hmac, NULL); -+ g_free (hmac->digest_str); -+ g_free (hmac); -+ } -+} -+ -+ -+void -+g_hmac_update (GHmac *hmac, -+ const guchar *data, -+ gssize length) -+{ -+ int ret; -+ -+ g_return_if_fail (hmac != NULL); -+ g_return_if_fail (length == 0 || data != NULL); -+ -+ if (length == -1) -+ length = strlen ((const char *)data); -+ -+ /* g_hmac_update is not allowed to fail, so we'll have to crash on error. */ -+ ret = gnutls_hmac (hmac->hmac, data, length); -+ if (ret != 0) -+ g_error ("gnutls_hmac failed: %s", gnutls_strerror (ret)); -+} -+ -+const gchar * -+g_hmac_get_string (GHmac *hmac) -+{ -+ guint8 *buffer; -+ gsize digest_len; -+ -+ g_return_val_if_fail (hmac != NULL, NULL); -+ -+ if (hmac->digest_str) -+ return hmac->digest_str; -+ -+ digest_len = g_checksum_type_get_length (hmac->digest_type); -+ buffer = g_alloca (digest_len); -+ -+ gnutls_hmac_output (hmac->hmac, buffer); -+ hmac->digest_str = gchecksum_digest_to_string (buffer, digest_len); -+ return hmac->digest_str; -+} -+ -+ -+void -+g_hmac_get_digest (GHmac *hmac, -+ guint8 *buffer, -+ gsize *digest_len) -+{ -+ g_return_if_fail (hmac != NULL); -+ -+ gnutls_hmac_output (hmac->hmac, buffer); -+ *digest_len = g_checksum_type_get_length (hmac->digest_type); -+} -diff --git a/glib/ghmac.c b/glib/ghmac.c -index 516b01b24..a4851cc64 100644 ---- a/glib/ghmac.c -+++ b/glib/ghmac.c -@@ -35,6 +35,9 @@ - #include "gtypes.h" - #include "glibintl.h" - -+#ifdef HAVE_GNUTLS -+#error "build configuration error" -+#endif - - /** - * SECTION:hmac -@@ -86,6 +89,18 @@ struct _GHmac - * Support for digests of type %G_CHECKSUM_SHA512 has been added in GLib 2.42. - * Support for %G_CHECKSUM_SHA384 was added in GLib 2.52. - * -+ * Note that #GHmac creation may fail, in which case this function will -+ * return %NULL. Since there is no error parameter, it is not possible -+ * to indicate why. -+ * -+ * In Fedora, CentOS Stream, and Red Hat Enterprise Linux, GLib is -+ * configured to use GnuTLS to implement #GHmac in order to support FIPS -+ * compliance. This introduces additional failure possibilities that are -+ * not present in upstream GLib. For example, the creation of a #GHmac -+ * will fail if @digest_type is %G_CHECKSUM_MD5 and the system is -+ * running in FIPS mode. #GHmac creation may also fail if GLib is unable -+ * to load GnuTLS. -+ * - * Returns: the newly created #GHmac, or %NULL. - * Use g_hmac_unref() to free the memory allocated by it. - * -diff --git a/glib/meson.build b/glib/meson.build -index 6624dab48..4e3365f61 100644 ---- a/glib/meson.build -+++ b/glib/meson.build -@@ -247,7 +247,6 @@ glib_sources = files( - 'gfileutils.c', - 'ggettext.c', - 'ghash.c', -- 'ghmac.c', - 'ghmac-utils.c', - 'ghook.c', - 'ghostutils.c', -@@ -303,6 +302,7 @@ glib_sources = files( - 'guriprivate.h', - 'gutils.c', - 'gutilsprivate.h', -+ 'gchecksumprivate.h', - 'guuid.c', - 'gvariant.c', - 'gvariant-core.c', -@@ -358,6 +358,12 @@ else - glib_dtrace_hdr = [] - endif - -+if get_option('gnutls') -+ glib_sources += files('ghmac-gnutls.c') -+else -+ glib_sources += files('ghmac.c') -+endif -+ - pcre2_static_args = [] - - if use_pcre2_static_flag -@@ -376,7 +382,7 @@ libglib = library('glib-2.0', - link_args : [noseh_link_args, glib_link_flags, win32_ldflags], - include_directories : configinc, - link_with: [charset_lib, gnulib_lib], -- dependencies : [pcre2, thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep], -+ dependencies : [pcre2, thread_dep, librt] + libgnutls_dep + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep], - c_args : glib_c_args, - objc_args : glib_c_args, - ) -diff --git a/meson.build b/meson.build -index b3dea2ea1..464e59e09 100644 ---- a/meson.build -+++ b/meson.build -@@ -2113,6 +2113,13 @@ if host_system == 'linux' - glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found()) - endif - -+# gnutls is used optionally by ghmac -+libgnutls_dep = [] -+if get_option('gnutls') -+ libgnutls_dep = [dependency('gnutls', version : '>=3.6.9', required : true)] -+ glib_conf.set('HAVE_GNUTLS', 1) -+endif -+ - if host_system == 'windows' - winsock2 = cc.find_library('ws2_32') - else -diff --git a/meson_options.txt b/meson_options.txt -index a52eed9d2..4eb577798 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -34,6 +34,11 @@ option('libmount', - value : 'auto', - description : 'build with libmount support') - -+option('gnutls', -+ type : 'boolean', -+ value : false, -+ description : 'build with gnutls support') -+ - option('man', - type : 'boolean', - value : false, --- -2.36.1 - - -From 019c4323d379c80344a0146e1fee2008fd6d3b51 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Wed, 16 Jun 2021 20:35:00 -0500 -Subject: [PATCH 3/4] dlopen GnuTLS instead of linking directly - -I'd like to enable our GnuTLS GHmac patchset in Fedora in order to -ensure it is receiving sufficient real-world testing, since we've -discovered several bugs thus far. Problem is Fedora has one requirement -that RHEL does not: it needs to build glib as a static lib. This is -needed by QEMU in Fedora for complicated technical reasons that I don't -understand. However, nothing in RHEL needs it. This means we failed to -notice that glib2-static is broken in RHEL, because there is no -gnutls-static! We could fix this by adding a gnutls-static package, but -that seems like overkill, and adding more static libraries where they're -not truly necessary is not the direction we want to move in anyway. So -instead, let's just dlopen GnuTLS to sidestep this problem entirely. - -This would not be a good solution for upstream, but upstream has made -clear that this patchset is already non-upstreamable, so it will be fine -for our purposes. ---- - glib/ghmac-gnutls.c | 101 ++++++++++++++++++++++++++++++++++++++++++-- - glib/ghmac.c | 2 +- - glib/meson.build | 2 +- - meson.build | 6 +-- - 4 files changed, 102 insertions(+), 9 deletions(-) - -diff --git a/glib/ghmac-gnutls.c b/glib/ghmac-gnutls.c -index 9fb775f89..1800fc2e0 100644 ---- a/glib/ghmac-gnutls.c -+++ b/glib/ghmac-gnutls.c -@@ -19,8 +19,8 @@ - - #include "config.h" - -+#include - #include --#include - - #include "ghmac.h" - -@@ -31,13 +31,16 @@ - #include "gstrfuncs.h" - #include "gchecksumprivate.h" - #include "gtestutils.h" -+#include "gthread.h" - #include "gtypes.h" - #include "glibintl.h" - --#ifndef HAVE_GNUTLS -+#ifndef USE_GNUTLS - #error "build configuration error" - #endif - -+typedef gpointer gnutls_hmac_hd_t; -+ - struct _GHmac - { - int ref_count; -@@ -46,15 +49,107 @@ struct _GHmac - gchar *digest_str; - }; - -+typedef enum -+{ -+ GNUTLS_MAC_MD5 = 2, -+ GNUTLS_MAC_SHA1 = 3, -+ GNUTLS_MAC_SHA256 = 6, -+ GNUTLS_MAC_SHA384 = 7, -+ GNUTLS_MAC_SHA512 = 8, -+} gnutls_mac_algorithm_t; -+ -+/* Why are we dlopening GnuTLS instead of linking to it directly? Because we -+ * want to be able to build GLib as a static library without depending on a -+ * static build of GnuTLS. QEMU depends on static linking with GLib, but Fedora -+ * does not ship a static build of GnuTLS, and this allows us to avoid changing -+ * that. -+ */ -+static int (*gnutls_hmac_init) (gnutls_hmac_hd_t *dig, gnutls_mac_algorithm_t algorithm, const void *key, size_t keylen); -+static gnutls_hmac_hd_t (*gnutls_hmac_copy) (gnutls_hmac_hd_t handle); -+static void (*gnutls_hmac_deinit) (gnutls_hmac_hd_t handle, void *digest); -+static int (*gnutls_hmac) (gnutls_hmac_hd_t handle, const void *ptext, size_t ptext_len); -+static void (*gnutls_hmac_output) (gnutls_hmac_hd_t handle, void *digest); -+static const char * (*gnutls_strerror) (int error); -+ -+static gsize gnutls_initialize_attempted = 0; -+static gboolean gnutls_initialize_successful = FALSE; -+ -+static void -+initialize_gnutls (void) -+{ -+ gpointer libgnutls; -+ -+ libgnutls = dlopen ("libgnutls.so.30", RTLD_LAZY | RTLD_GLOBAL); -+ if (!libgnutls) -+ { -+ g_warning ("Cannot use GHmac: failed to load libgnutls.so.30: %s", dlerror ()); -+ return; -+ } -+ -+ gnutls_hmac_init = dlsym (libgnutls, "gnutls_hmac_init"); -+ if (!gnutls_hmac_init) -+ { -+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_init: %s", dlerror ()); -+ return; -+ } -+ -+ gnutls_hmac_copy = dlsym (libgnutls, "gnutls_hmac_copy"); -+ if (!gnutls_hmac_copy) -+ { -+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_copy: %s", dlerror ()); -+ return; -+ } -+ -+ gnutls_hmac_deinit = dlsym (libgnutls, "gnutls_hmac_deinit"); -+ if (!gnutls_hmac_deinit) -+ { -+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_deinit: %s", dlerror ()); -+ return; -+ } -+ -+ gnutls_hmac = dlsym (libgnutls, "gnutls_hmac"); -+ if (!gnutls_hmac) -+ { -+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac: %s", dlerror ()); -+ return; -+ } -+ -+ gnutls_hmac_output = dlsym (libgnutls, "gnutls_hmac_output"); -+ if (!gnutls_hmac_output) -+ { -+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_output: %s", dlerror ()); -+ return; -+ } -+ -+ gnutls_strerror = dlsym (libgnutls, "gnutls_strerror"); -+ if (!gnutls_strerror) -+ { -+ g_warning ("Cannot use GHmac: failed to load gnutls_strerror: %s", dlerror ()); -+ return; -+ } -+ -+ gnutls_initialize_successful = TRUE; -+} -+ - GHmac * - g_hmac_new (GChecksumType digest_type, - const guchar *key, - gsize key_len) - { - gnutls_mac_algorithm_t algo; -- GHmac *hmac = g_new0 (GHmac, 1); -+ GHmac *hmac; - int ret; - -+ if (g_once_init_enter (&gnutls_initialize_attempted)) -+ { -+ initialize_gnutls (); -+ g_once_init_leave (&gnutls_initialize_attempted, 1); -+ } -+ -+ if (!gnutls_initialize_successful) -+ return NULL; -+ -+ hmac = g_new0 (GHmac, 1); - hmac->ref_count = 1; - hmac->digest_type = digest_type; - -diff --git a/glib/ghmac.c b/glib/ghmac.c -index a4851cc64..20e64fd00 100644 ---- a/glib/ghmac.c -+++ b/glib/ghmac.c -@@ -35,7 +35,7 @@ - #include "gtypes.h" - #include "glibintl.h" - --#ifdef HAVE_GNUTLS -+#ifdef USE_GNUTLS - #error "build configuration error" - #endif - -diff --git a/glib/meson.build b/glib/meson.build -index 4e3365f61..3b2a246c4 100644 ---- a/glib/meson.build -+++ b/glib/meson.build -@@ -382,7 +382,7 @@ libglib = library('glib-2.0', - link_args : [noseh_link_args, glib_link_flags, win32_ldflags], - include_directories : configinc, - link_with: [charset_lib, gnulib_lib], -- dependencies : [pcre2, thread_dep, librt] + libgnutls_dep + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep], -+ dependencies : [pcre2, thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep] + [libdl_dep], - c_args : glib_c_args, - objc_args : glib_c_args, - ) -diff --git a/meson.build b/meson.build -index 464e59e09..366c35fef 100644 ---- a/meson.build -+++ b/meson.build -@@ -2113,11 +2113,9 @@ if host_system == 'linux' - glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found()) - endif - --# gnutls is used optionally by ghmac --libgnutls_dep = [] -+# gnutls is used optionally by GHmac - if get_option('gnutls') -- libgnutls_dep = [dependency('gnutls', version : '>=3.6.9', required : true)] -- glib_conf.set('HAVE_GNUTLS', 1) -+ glib_conf.set('USE_GNUTLS', 1) - endif - - if host_system == 'windows' --- -2.36.1 - - -From 67f0f37e072b8629644efd4a657f73ce72da042b Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Wed, 16 Jun 2021 20:46:24 -0500 -Subject: [PATCH 4/4] Add test for GHmac in FIPS mode - -This will test a few problems that we hit recently: - -g_hmac_copy() is broken, https://bugzilla.redhat.com/show_bug.cgi?id=1786538 - -Crash in g_hmac_update() in FIPS mode, https://bugzilla.redhat.com/show_bug.cgi?id=1971533 - -Crash when passing -1 length to g_hmac_update() (discovered in #1971533) - -We'll also test to ensure MD5 fails, and stop compiling the other MD5 -tests. ---- - glib/tests/hmac.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 46 insertions(+) - -diff --git a/glib/tests/hmac.c b/glib/tests/hmac.c -index 3ac3206df..2fa447984 100644 ---- a/glib/tests/hmac.c -+++ b/glib/tests/hmac.c -@@ -1,7 +1,10 @@ -+#include "config.h" -+ - #include - #include - #include - -+#ifndef USE_GNUTLS - /* HMAC-MD5 test vectors as per RFC 2202 */ - - /* Test 1 */ -@@ -81,6 +84,7 @@ guint8 key_md5_test7[] = { - guint8 result_md5_test7[] = { - 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 0x1f, 0xb1, - 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e }; -+#endif - - /* HMAC-SHA1, HMAC-SHA256, HMAC-SHA384 and HMAC-SHA512 test vectors - * as per RFCs 2202 and 4868. -@@ -299,6 +303,7 @@ typedef struct { - gconstpointer result; - } HmacCase; - -+#ifndef USE_GNUTLS - HmacCase hmac_md5_tests[] = { - { G_CHECKSUM_MD5, key_md5_test1, 16, "Hi There", 8, result_md5_test1 }, - { G_CHECKSUM_MD5, "Jefe", 4, "what do ya want for nothing?", 28, -@@ -317,6 +322,7 @@ HmacCase hmac_md5_tests[] = { - 73, result_md5_test7 }, - { -1, NULL, 0, NULL, 0, NULL }, - }; -+#endif - - HmacCase hmac_sha1_tests[] = { - { G_CHECKSUM_SHA1, key_sha_test1, 20, "Hi There", 8, result_sha1_test1 }, -@@ -493,11 +499,45 @@ test_hmac_for_bytes (void) - g_bytes_unref (data); - } - -+#ifdef USE_GNUTLS -+static void -+test_gnutls_fips_mode (void) -+{ -+ GHmac *hmac; -+ GHmac *copy; -+ -+ /* No MD5 in FIPS mode. */ -+ hmac = g_hmac_new (G_CHECKSUM_MD5, (guchar *)"abc123", sizeof ("abc123")); -+ g_assert_null (hmac); -+ -+ /* SHA-256 should be good. */ -+ hmac = g_hmac_new (G_CHECKSUM_SHA256, (guchar *)"abc123", sizeof ("abc123")); -+ g_assert_nonnull (hmac); -+ -+ /* Ensure g_hmac_update() does not crash when called with -1. */ -+ g_hmac_update (hmac, (guchar *)"You win again, gravity!", -1); -+ -+ /* Ensure g_hmac_copy() does not crash. */ -+ copy = g_hmac_copy (hmac); -+ g_assert_nonnull (hmac); -+ g_hmac_unref (hmac); -+ -+ g_assert_cmpstr (g_hmac_get_string (copy), ==, "795ba6900bcb22e8ce65c2ec02db4e85697da921deb960ee3143bf88a4a60f83"); -+ g_hmac_unref (copy); -+} -+#endif -+ - int - main (int argc, - char **argv) - { - int i; -+ -+#ifdef USE_GNUTLS -+ /* This has to happen before GnuTLS is dlopened. */ -+ g_setenv ("GNUTLS_FORCE_FIPS_MODE", "1", FALSE); -+#endif -+ - g_test_init (&argc, &argv, NULL); - - for (i = 0 ; hmac_sha1_tests[i].key_len > 0 ; i++) -@@ -532,6 +572,7 @@ main (int argc, - g_free (name); - } - -+#ifndef USE_GNUTLS - for (i = 0 ; hmac_md5_tests[i].key_len > 0 ; i++) - { - gchar *name = g_strdup_printf ("/hmac/md5-%d", i + 1); -@@ -539,6 +580,7 @@ main (int argc, - (void (*)(const void *)) test_hmac); - g_free (name); - } -+#endif - - g_test_add_func ("/hmac/ref-unref", test_hmac_ref_unref); - g_test_add_func ("/hmac/copy", test_hmac_copy); -@@ -546,5 +588,9 @@ main (int argc, - g_test_add_func ("/hmac/for-string", test_hmac_for_string); - g_test_add_func ("/hmac/for-bytes", test_hmac_for_bytes); - -+#ifdef USE_GNUTLS -+ g_test_add_func ("/hmac/gnutls-fips-mode", test_gnutls_fips_mode); -+#endif -+ - return g_test_run (); - } --- -2.36.1 -