From 130c359084fa9d91e15bb9ccb16da7d03c841253 Mon Sep 17 00:00:00 2001 From: Raven Date: Sat, 15 Mar 2025 12:54:35 +0600 Subject: [PATCH] cleanup --- base/rx-glib2/1965.patch | 222 -- base/rx-glib2/1968.patch | 1052 ------ base/rx-glib2/2194.patch | 920 ----- base/rx-glib2/2222.patch | 739 ---- base/rx-glib2/2244.patch | 49 - base/rx-glib2/2291.patch | 129 - base/rx-glib2/2408.patch | 391 -- base/rx-glib2/2435.patch | 132 - base/rx-glib2/2826.patch | 278 -- base/rx-glib2/3126.patch | 3021 --------------- base/rx-glib2/3136.patch | 65 - base/rx-glib2/3163.patch | 199 - base/rx-glib2/3272.patch | 141 - base/rx-glib2/3353.patch | 1078 ------ base/rx-glib2/3845.patch | 195 - base/rx-glib2/4038.patch | 3359 ----------------- base/rx-glib2/glib-change-version.patch | 2133 ----------- base/rx-glib2/glib2.spec | 1012 ----- base/rx-glib2/gnutls-hmac.patch | 1086 ------ extras/qemu/0001-sgx-stub-fix.patch | 27 - extras/qemu/0004-Initial-redhat-build.patch | 313 -- ...0005-Enable-disable-devices-for-RHEL.patch | 629 --- ...Machine-type-related-general-changes.patch | 619 --- .../qemu/0007-Add-aarch64-machine-types.patch | 352 -- .../qemu/0008-Add-ppc64-machine-types.patch | 380 -- .../qemu/0009-Add-s390x-machine-types.patch | 186 - .../qemu/0010-Add-x86_64-machine-types.patch | 714 ---- extras/qemu/0011-Enable-make-check.patch | 186 - ...mber-of-devices-that-can-be-assigned.patch | 104 - ...Add-support-statement-to-help-output.patch | 55 - ...lly-limit-the-maximum-number-of-CPUs.patch | 45 - ...documentation-instead-of-qemu-system.patch | 61 - ...ct-scsi-cd-if-data-plane-enabled-RHE.patch | 66 - ...e-at-least-64kiB-pages-for-downstrea.patch | 60 - ...on-warning-when-opening-v2-images-rw.patch | 77 - ...oduce-RHEL-9.0.0-hw-compat-structure.patch | 135 - ...90x-machine-type-compatibility-for-r.patch | 38 - ...ve-s3-s4-suspend-disabling-to-compat.patch | 70 - extras/qemu/95-kvm-memlock.conf | 12 - extras/qemu/99-qemu-guest-agent.rules | 2 - extras/qemu/README.tests | 39 - extras/qemu/bridge.conf | 1 - extras/qemu/kvm-s390x.conf | 19 - extras/qemu/kvm-x86.conf | 12 - extras/qemu/kvm.conf | 3 - extras/qemu/qemu-ga.sysconfig | 19 - extras/qemu/qemu-guest-agent.service | 19 - extras/qemu/qemu.spec | 2608 ------------- extras/qemu/vhost.conf | 3 - 49 files changed, 23055 deletions(-) delete mode 100644 base/rx-glib2/1965.patch delete mode 100644 base/rx-glib2/1968.patch delete mode 100644 base/rx-glib2/2194.patch delete mode 100644 base/rx-glib2/2222.patch delete mode 100644 base/rx-glib2/2244.patch delete mode 100644 base/rx-glib2/2291.patch delete mode 100644 base/rx-glib2/2408.patch delete mode 100644 base/rx-glib2/2435.patch delete mode 100644 base/rx-glib2/2826.patch delete mode 100644 base/rx-glib2/3126.patch delete mode 100644 base/rx-glib2/3136.patch delete mode 100644 base/rx-glib2/3163.patch delete mode 100644 base/rx-glib2/3272.patch delete mode 100644 base/rx-glib2/3353.patch delete mode 100644 base/rx-glib2/3845.patch delete mode 100644 base/rx-glib2/4038.patch delete mode 100644 base/rx-glib2/glib-change-version.patch delete mode 100644 base/rx-glib2/glib2.spec delete mode 100644 base/rx-glib2/gnutls-hmac.patch delete mode 100644 extras/qemu/0001-sgx-stub-fix.patch delete mode 100644 extras/qemu/0004-Initial-redhat-build.patch delete mode 100644 extras/qemu/0005-Enable-disable-devices-for-RHEL.patch delete mode 100644 extras/qemu/0006-Machine-type-related-general-changes.patch delete mode 100644 extras/qemu/0007-Add-aarch64-machine-types.patch delete mode 100644 extras/qemu/0008-Add-ppc64-machine-types.patch delete mode 100644 extras/qemu/0009-Add-s390x-machine-types.patch delete mode 100644 extras/qemu/0010-Add-x86_64-machine-types.patch delete mode 100644 extras/qemu/0011-Enable-make-check.patch delete mode 100644 extras/qemu/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch delete mode 100644 extras/qemu/0013-Add-support-statement-to-help-output.patch delete mode 100644 extras/qemu/0014-globally-limit-the-maximum-number-of-CPUs.patch delete mode 100644 extras/qemu/0015-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch delete mode 100644 extras/qemu/0016-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch delete mode 100644 extras/qemu/0017-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch delete mode 100644 extras/qemu/0018-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch delete mode 100644 extras/qemu/0019-WRB-Introduce-RHEL-9.0.0-hw-compat-structure.patch delete mode 100644 extras/qemu/0020-redhat-Update-s390x-machine-type-compatibility-for-r.patch delete mode 100644 extras/qemu/0021-pc-Move-s3-s4-suspend-disabling-to-compat.patch delete mode 100644 extras/qemu/95-kvm-memlock.conf delete mode 100644 extras/qemu/99-qemu-guest-agent.rules delete mode 100644 extras/qemu/README.tests delete mode 100644 extras/qemu/bridge.conf delete mode 100644 extras/qemu/kvm-s390x.conf delete mode 100644 extras/qemu/kvm-x86.conf delete mode 100644 extras/qemu/kvm.conf delete mode 100644 extras/qemu/qemu-ga.sysconfig delete mode 100644 extras/qemu/qemu-guest-agent.service delete mode 100644 extras/qemu/qemu.spec delete mode 100644 extras/qemu/vhost.conf diff --git a/base/rx-glib2/1965.patch b/base/rx-glib2/1965.patch deleted file mode 100644 index 59d7cb8..0000000 --- a/base/rx-glib2/1965.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 1248b642ad32b0bdf296211c1a0a8817bebf1c66 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Thu, 25 Feb 2021 10:35:36 +0000 -Subject: [PATCH 1/2] gversionmacros: Add version macros for GLib 2.70 - -Signed-off-by: Simon McVittie ---- - docs/reference/gio/gio-docs.xml | 4 +++ - docs/reference/glib/glib-docs.xml | 4 +++ - docs/reference/glib/glib-sections.txt | 14 ++++++++ - docs/reference/gobject/gobject-docs.xml | 4 +++ - docs/reference/meson.build | 2 +- - glib/gversionmacros.h | 44 +++++++++++++++++++++++++ - 6 files changed, 71 insertions(+), 1 deletion(-) - -diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml -index 9cd3d0e39..a09d6d31d 100644 ---- a/docs/reference/gio/gio-docs.xml -+++ b/docs/reference/gio/gio-docs.xml -@@ -389,6 +389,10 @@ - Index of new symbols in 2.68 - - -+ -+ Index of new symbols in 2.70 -+ -+ - - - -diff --git a/docs/reference/glib/glib-docs.xml b/docs/reference/glib/glib-docs.xml -index e464fb792..2f5de9e31 100644 ---- a/docs/reference/glib/glib-docs.xml -+++ b/docs/reference/glib/glib-docs.xml -@@ -288,6 +288,10 @@ - Index of new symbols in 2.68 - - -+ -+ Index of new symbols in 2.70 -+ -+ - - - -diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt -index 460a299bf..75994e889 100644 ---- a/docs/reference/glib/glib-sections.txt -+++ b/docs/reference/glib/glib-sections.txt -@@ -138,6 +138,7 @@ GLIB_VERSION_2_62 - GLIB_VERSION_2_64 - GLIB_VERSION_2_66 - GLIB_VERSION_2_68 -+GLIB_VERSION_2_70 - GLIB_VERSION_CUR_STABLE - GLIB_VERSION_PREV_STABLE - GLIB_VERSION_MIN_REQUIRED -@@ -168,6 +169,7 @@ GLIB_AVAILABLE_ENUMERATOR_IN_2_62 - GLIB_AVAILABLE_ENUMERATOR_IN_2_64 - GLIB_AVAILABLE_ENUMERATOR_IN_2_66 - GLIB_AVAILABLE_ENUMERATOR_IN_2_68 -+GLIB_AVAILABLE_ENUMERATOR_IN_2_70 - GLIB_AVAILABLE_IN_ALL - GLIB_AVAILABLE_IN_2_26 - GLIB_AVAILABLE_IN_2_28 -@@ -191,6 +193,7 @@ GLIB_AVAILABLE_IN_2_62 - GLIB_AVAILABLE_IN_2_64 - GLIB_AVAILABLE_IN_2_66 - GLIB_AVAILABLE_IN_2_68 -+GLIB_AVAILABLE_IN_2_70 - GLIB_AVAILABLE_MACRO_IN_2_26 - GLIB_AVAILABLE_MACRO_IN_2_28 - GLIB_AVAILABLE_MACRO_IN_2_30 -@@ -213,12 +216,14 @@ GLIB_AVAILABLE_MACRO_IN_2_62 - GLIB_AVAILABLE_MACRO_IN_2_64 - GLIB_AVAILABLE_MACRO_IN_2_66 - GLIB_AVAILABLE_MACRO_IN_2_68 -+GLIB_AVAILABLE_MACRO_IN_2_70 - GLIB_AVAILABLE_STATIC_INLINE_IN_2_44 - GLIB_AVAILABLE_STATIC_INLINE_IN_2_60 - GLIB_AVAILABLE_STATIC_INLINE_IN_2_62 - GLIB_AVAILABLE_STATIC_INLINE_IN_2_64 - GLIB_AVAILABLE_STATIC_INLINE_IN_2_66 - GLIB_AVAILABLE_STATIC_INLINE_IN_2_68 -+GLIB_AVAILABLE_STATIC_INLINE_IN_2_70 - GLIB_AVAILABLE_TYPE_IN_2_26 - GLIB_AVAILABLE_TYPE_IN_2_28 - GLIB_AVAILABLE_TYPE_IN_2_30 -@@ -241,6 +246,7 @@ GLIB_AVAILABLE_TYPE_IN_2_62 - GLIB_AVAILABLE_TYPE_IN_2_64 - GLIB_AVAILABLE_TYPE_IN_2_66 - GLIB_AVAILABLE_TYPE_IN_2_68 -+GLIB_AVAILABLE_TYPE_IN_2_70 - GLIB_DEPRECATED_ENUMERATOR - GLIB_DEPRECATED_ENUMERATOR_FOR - GLIB_DEPRECATED_ENUMERATOR_IN_2_26 -@@ -287,6 +293,8 @@ GLIB_DEPRECATED_ENUMERATOR_IN_2_66 - GLIB_DEPRECATED_ENUMERATOR_IN_2_66_FOR - GLIB_DEPRECATED_ENUMERATOR_IN_2_68 - GLIB_DEPRECATED_ENUMERATOR_IN_2_68_FOR -+GLIB_DEPRECATED_ENUMERATOR_IN_2_70 -+GLIB_DEPRECATED_ENUMERATOR_IN_2_70_FOR - GLIB_DEPRECATED_IN_2_26 - GLIB_DEPRECATED_IN_2_26_FOR - GLIB_DEPRECATED_IN_2_28 -@@ -331,6 +339,8 @@ GLIB_DEPRECATED_IN_2_66 - GLIB_DEPRECATED_IN_2_66_FOR - GLIB_DEPRECATED_IN_2_68 - GLIB_DEPRECATED_IN_2_68_FOR -+GLIB_DEPRECATED_IN_2_70 -+GLIB_DEPRECATED_IN_2_70_FOR - GLIB_DEPRECATED_MACRO - GLIB_DEPRECATED_MACRO_FOR - GLIB_DEPRECATED_MACRO_IN_2_26 -@@ -377,6 +387,8 @@ GLIB_DEPRECATED_MACRO_IN_2_66 - GLIB_DEPRECATED_MACRO_IN_2_66_FOR - GLIB_DEPRECATED_MACRO_IN_2_68 - GLIB_DEPRECATED_MACRO_IN_2_68_FOR -+GLIB_DEPRECATED_MACRO_IN_2_70 -+GLIB_DEPRECATED_MACRO_IN_2_70_FOR - GLIB_DEPRECATED_TYPE - GLIB_DEPRECATED_TYPE_FOR - GLIB_DEPRECATED_TYPE_IN_2_26 -@@ -423,6 +435,8 @@ GLIB_DEPRECATED_TYPE_IN_2_66 - GLIB_DEPRECATED_TYPE_IN_2_66_FOR - GLIB_DEPRECATED_TYPE_IN_2_68 - GLIB_DEPRECATED_TYPE_IN_2_68_FOR -+GLIB_DEPRECATED_TYPE_IN_2_70 -+GLIB_DEPRECATED_TYPE_IN_2_70_FOR - GLIB_VERSION_CUR_STABLE - GLIB_VERSION_PREV_STABLE - -diff --git a/docs/reference/gobject/gobject-docs.xml b/docs/reference/gobject/gobject-docs.xml -index ddbc9f274..e8e7c76d9 100644 ---- a/docs/reference/gobject/gobject-docs.xml -+++ b/docs/reference/gobject/gobject-docs.xml -@@ -208,6 +208,10 @@ - Index of new symbols in 2.68 - - -+ -+ Index of new symbols in 2.70 -+ -+ - - - -diff --git a/docs/reference/meson.build b/docs/reference/meson.build -index 3f09be555..53ca12ff8 100644 ---- a/docs/reference/meson.build -+++ b/docs/reference/meson.build -@@ -7,7 +7,7 @@ - stable_2_series_versions = [ - '26', '28', '30', '32', '34', '36', '38', - '40', '42', '44', '46', '48', '50', '52', '54', '56', '58', -- '60', '62', '64', '66', '68', -+ '60', '62', '64', '66', '68', '70', - ] - - ignore_decorators = [ -diff --git a/glib/gversionmacros.h b/glib/gversionmacros.h -index 77486eafb..d052709cf 100644 ---- a/glib/gversionmacros.h -+++ b/glib/gversionmacros.h -@@ -255,6 +255,16 @@ - */ - #define GLIB_VERSION_2_68 (G_ENCODE_VERSION (2, 68)) - -+/** -+ * GLIB_VERSION_2_70: -+ * -+ * A macro that evaluates to the 2.70 version of GLib, in a format -+ * that can be used by the C pre-processor. -+ * -+ * Since: 2.70 -+ */ -+#define GLIB_VERSION_2_70 (G_ENCODE_VERSION (2, 70)) -+ - /** - * GLIB_VERSION_CUR_STABLE: - * -@@ -1076,4 +1086,38 @@ - # define GLIB_AVAILABLE_TYPE_IN_2_68 - #endif - -+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_70 -+# define GLIB_DEPRECATED_IN_2_70 GLIB_DEPRECATED -+# define GLIB_DEPRECATED_IN_2_70_FOR(f) GLIB_DEPRECATED_FOR(f) -+# define GLIB_DEPRECATED_MACRO_IN_2_70 GLIB_DEPRECATED_MACRO -+# define GLIB_DEPRECATED_MACRO_IN_2_70_FOR(f) GLIB_DEPRECATED_MACRO_FOR(f) -+# define GLIB_DEPRECATED_ENUMERATOR_IN_2_70 GLIB_DEPRECATED_ENUMERATOR -+# define GLIB_DEPRECATED_ENUMERATOR_IN_2_70_FOR(f) GLIB_DEPRECATED_ENUMERATOR_FOR(f) -+# define GLIB_DEPRECATED_TYPE_IN_2_70 GLIB_DEPRECATED_TYPE -+# define GLIB_DEPRECATED_TYPE_IN_2_70_FOR(f) GLIB_DEPRECATED_TYPE_FOR(f) -+#else -+# define GLIB_DEPRECATED_IN_2_70 _GLIB_EXTERN -+# define GLIB_DEPRECATED_IN_2_70_FOR(f) _GLIB_EXTERN -+# define GLIB_DEPRECATED_MACRO_IN_2_70 -+# define GLIB_DEPRECATED_MACRO_IN_2_70_FOR(f) -+# define GLIB_DEPRECATED_ENUMERATOR_IN_2_70 -+# define GLIB_DEPRECATED_ENUMERATOR_IN_2_70_FOR(f) -+# define GLIB_DEPRECATED_TYPE_IN_2_70 -+# define GLIB_DEPRECATED_TYPE_IN_2_70_FOR(f) -+#endif -+ -+#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_70 -+# define GLIB_AVAILABLE_IN_2_70 GLIB_UNAVAILABLE(2, 70) -+# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_70 GLIB_UNAVAILABLE_STATIC_INLINE(2, 70) -+# define GLIB_AVAILABLE_MACRO_IN_2_70 GLIB_UNAVAILABLE_MACRO(2, 70) -+# define GLIB_AVAILABLE_ENUMERATOR_IN_2_70 GLIB_UNAVAILABLE_ENUMERATOR(2, 70) -+# define GLIB_AVAILABLE_TYPE_IN_2_70 GLIB_UNAVAILABLE_TYPE(2, 70) -+#else -+# define GLIB_AVAILABLE_IN_2_70 _GLIB_EXTERN -+# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_70 -+# define GLIB_AVAILABLE_MACRO_IN_2_70 -+# define GLIB_AVAILABLE_ENUMERATOR_IN_2_70 -+# define GLIB_AVAILABLE_TYPE_IN_2_70 -+#endif -+ - #endif /* __G_VERSION_MACROS_H__ */ --- -GitLab diff --git a/base/rx-glib2/1968.patch b/base/rx-glib2/1968.patch deleted file mode 100644 index 1809214..0000000 --- a/base/rx-glib2/1968.patch +++ /dev/null @@ -1,1052 +0,0 @@ -From 9e69f8b280afe8eccd9188cc53b8117e1b238db7 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Tue, 12 Oct 2021 15:52:18 -0500 -Subject: [PATCH 01/10] gspawn: use close_and_invalidate more - ---- - glib/gspawn.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index a15fb1ca1..5d8422869 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -1710,7 +1710,7 @@ do_exec (gint child_err_report_fd, - child_err_report_fd = safe_dup (child_err_report_fd); - - safe_dup2 (source_fds[i], target_fds[i]); -- (void) close (source_fds[i]); -+ close_and_invalidate (&source_fds[i]); - } - } - } --- -2.33.1 - -From fe2148fd5dd4f2e5c413c5cc0bb56c4a19304887 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Thu, 14 Oct 2021 10:43:52 -0500 -Subject: [PATCH 02/10] gspawn: Improve error message when dup fails - -This error message is no longer accurate now that we allow arbitrary fd -remapping. ---- - glib/gspawn.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index 5d8422869..e214a3998 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -2363,7 +2363,7 @@ fork_exec (gboolean intermediate_child, - g_set_error (error, - G_SPAWN_ERROR, - G_SPAWN_ERROR_FAILED, -- _("Failed to redirect output or input of child process (%s)"), -+ _("Failed to duplicate file descriptor for child process (%s)"), - g_strerror (buf[1])); - - break; --- -2.33.1 - -From 566eccdb0a2594b4d3ec13c7443028d968b41af8 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Tue, 12 Oct 2021 15:33:59 -0500 -Subject: [PATCH 03/10] gspawn: fix hangs when duping child_err_report_fd - -In case child_err_report_fd conflicts with one of the target_fds, the -code here is careful to dup child_err_report_fd in order to avoid -conflating the two. It was a good idea, but evidently was not tested, -because the newly-created fd is not created with CLOEXEC set. This means -it stays open in the child process, causing the parent to hang forever -waiting to read from the other end of the pipe. Oops! - -The fix is simple: just set CLOEXEC. This removes our only usage of the -safe_dup() function, so it can be dropped. - -Fixes #2506 ---- - glib/gspawn.c | 16 +--------------- - 1 file changed, 1 insertion(+), 15 deletions(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index e214a3998..8bbe573f7 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -1500,20 +1500,6 @@ safe_closefrom (int lowfd) - #endif - } - --/* This function is called between fork() and exec() and hence must be -- * async-signal-safe (see signal-safety(7)). */ --static gint --safe_dup (gint fd) --{ -- gint ret; -- -- do -- ret = dup (fd); -- while (ret < 0 && (errno == EINTR || errno == EBUSY)); -- -- return ret; --} -- - /* This function is called between fork() and exec() and hence must be - * async-signal-safe (see signal-safety(7)). */ - static gint -@@ -1707,7 +1693,7 @@ do_exec (gint child_err_report_fd, - else - { - if (target_fds[i] == child_err_report_fd) -- child_err_report_fd = safe_dup (child_err_report_fd); -+ child_err_report_fd = dupfd_cloexec (child_err_report_fd); - - safe_dup2 (source_fds[i], target_fds[i]); - close_and_invalidate (&source_fds[i]); --- -2.33.1 - -From b703fa8b760ac9272c5a0ed3e3763b2f71ecf574 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Thu, 14 Oct 2021 10:44:57 -0500 -Subject: [PATCH 04/10] gspawn: fix fd remapping conflation issue - -We currently dup all source fds to avoid possible conflation with the -target fds, but fail to consider that the result of a dup might itself -conflict with one of the target fds. Solve this the easy way by duping -all source_fds to values that are greater than the largest fd in -target_fds. - -Fixes #2503 ---- - glib/gspawn.c | 43 +++++++++++++++++++++++++------------------ - 1 file changed, 25 insertions(+), 18 deletions(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index 8bbe573f7..2b48b5600 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -1258,13 +1258,13 @@ unset_cloexec (int fd) - /* This function is called between fork() and exec() and hence must be - * async-signal-safe (see signal-safety(7)). */ - static int --dupfd_cloexec (int parent_fd) -+dupfd_cloexec (int old_fd, int new_fd_min) - { - int fd, errsv; - #ifdef F_DUPFD_CLOEXEC - do - { -- fd = fcntl (parent_fd, F_DUPFD_CLOEXEC, 3); -+ fd = fcntl (old_fd, F_DUPFD_CLOEXEC, new_fd_min); - errsv = errno; - } - while (fd == -1 && errsv == EINTR); -@@ -1275,7 +1275,7 @@ dupfd_cloexec (int parent_fd) - int result, flags; - do - { -- fd = fcntl (parent_fd, F_DUPFD, 3); -+ fd = fcntl (old_fd, F_DUPFD, new_fd_min); - errsv = errno; - } - while (fd == -1 && errsv == EINTR); -@@ -1563,6 +1563,7 @@ do_exec (gint child_err_report_fd, - gpointer user_data) - { - gsize i; -+ gint max_target_fd = 0; - - if (working_directory && chdir (working_directory) < 0) - write_err_and_exit (child_err_report_fd, -@@ -1661,39 +1662,45 @@ do_exec (gint child_err_report_fd, - /* - * Work through the @source_fds and @target_fds mapping. - * -- * Based on code derived from -+ * Based on code originally derived from - * gnome-terminal:src/terminal-screen.c:terminal_screen_child_setup(), -- * used under the LGPLv2+ with permission from author. -+ * used under the LGPLv2+ with permission from author. (The code has -+ * since migrated to vte:src/spawn.cc:SpawnContext::exec and is no longer -+ * terribly similar to what we have here.) - */ - -- /* Basic fd assignments (where source == target) we can just unset FD_CLOEXEC -- * -- * If we're doing remapping fd assignments, we need to handle -- * the case where the user has specified e.g.: -- * 5 -> 4, 4 -> 6 -- * -- * We do this by duping the source fds temporarily in a first pass. -- * -- * If any of the @target_fds conflict with @child_err_report_fd, dup the -- * latter so it doesn’t get conflated. -- */ - if (n_fds > 0) - { -+ for (i = 0; i < n_fds; i++) -+ max_target_fd = MAX (max_target_fd, target_fds[i]); -+ -+ /* If we're doing remapping fd assignments, we need to handle -+ * the case where the user has specified e.g. 5 -> 4, 4 -> 6. -+ * We do this by duping all source fds, taking care to ensure the new -+ * fds are larger than any target fd to avoid introducing new conflicts. -+ */ - for (i = 0; i < n_fds; i++) - { - if (source_fds[i] != target_fds[i]) -- source_fds[i] = dupfd_cloexec (source_fds[i]); -+ source_fds[i] = dupfd_cloexec (source_fds[i], max_target_fd + 1); - } -+ - for (i = 0; i < n_fds; i++) - { -+ /* For basic fd assignments (where source == target), we can just -+ * unset FD_CLOEXEC. -+ */ - if (source_fds[i] == target_fds[i]) - { - unset_cloexec (source_fds[i]); - } - else - { -+ /* If any of the @target_fds conflict with @child_err_report_fd, -+ * dup it so it doesn’t get conflated. -+ */ - if (target_fds[i] == child_err_report_fd) -- child_err_report_fd = dupfd_cloexec (child_err_report_fd); -+ child_err_report_fd = dupfd_cloexec (child_err_report_fd, max_target_fd + 1); - - safe_dup2 (source_fds[i], target_fds[i]); - close_and_invalidate (&source_fds[i]); --- -2.33.1 - -From ecc3538a942760e8b403c319d359711c8e166778 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Thu, 25 Feb 2021 12:20:39 -0600 -Subject: [PATCH 05/10] gspawn: Implement fd remapping for posix_spawn codepath - -This means that GSubprocess will (sometimes) be able to use the -optimized posix_spawn codepath instead of having to fall back to -fork/exec. ---- - glib/gspawn.c | 65 +++++++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 58 insertions(+), 7 deletions(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index 2b48b5600..9ef78dbe1 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -1786,9 +1786,14 @@ do_posix_spawn (const gchar * const *argv, - gint *child_close_fds, - gint stdin_fd, - gint stdout_fd, -- gint stderr_fd) -+ gint stderr_fd, -+ const gint *source_fds, -+ const gint *target_fds, -+ gsize n_fds) - { - pid_t pid; -+ gint *duped_source_fds = NULL; -+ gint max_target_fd = 0; - const gchar * const *argv_pass; - posix_spawnattr_t attr; - posix_spawn_file_actions_t file_actions; -@@ -1797,7 +1802,8 @@ do_posix_spawn (const gchar * const *argv, - GSList *child_close = NULL; - GSList *elem; - sigset_t mask; -- int i, r; -+ size_t i; -+ int r; - - if (*argv[0] == '\0') - { -@@ -1911,6 +1917,43 @@ do_posix_spawn (const gchar * const *argv, - goto out_close_fds; - } - -+ /* If source_fds[i] != target_fds[i], we need to handle the case -+ * where the user has specified, e.g., 5 -> 4, 4 -> 6. We do this -+ * by duping the source fds, taking care to ensure the new fds are -+ * larger than any target fd to avoid introducing new conflicts. -+ * -+ * If source_fds[i] == target_fds[i], then we just need to leak -+ * the fd into the child process, which we *could* do by temporarily -+ * unsetting CLOEXEC and then setting it again after we spawn if -+ * it was originally set. POSIX requires that the addup2 action unset -+ * CLOEXEC if source and target are identical, so you'd think doing it -+ * manually wouldn't be needed, but unfortunately as of 2021 many -+ * libcs still don't do so. Example nonconforming libcs: -+ * Bionic: https://android.googlesource.com/platform/bionic/+/f6e5b582604715729b09db3e36a7aeb8c24b36a4/libc/bionic/spawn.cpp#71 -+ * uclibc-ng: https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/librt/spawn.c?id=7c36bcae09d66bbaa35cbb02253ae0556f42677e#n88 -+ * -+ * Anyway, unsetting CLOEXEC ourselves would open a small race window -+ * where the fd could be inherited into a child process if another -+ * thread spawns something at the same time, because we have not -+ * called fork() and are multithreaded here. This race is avoidable by -+ * using dupfd_cloexec, which we already have to do to handle the -+ * source_fds[i] != target_fds[i] case. So let's always do it! -+ */ -+ -+ for (i = 0; i < n_fds; i++) -+ max_target_fd = MAX (max_target_fd, target_fds[i]); -+ -+ duped_source_fds = g_new (gint, n_fds); -+ for (i = 0; i < n_fds; i++) -+ duped_source_fds[i] = dupfd_cloexec (source_fds[i], max_target_fd + 1); -+ -+ for (i = 0; i < n_fds; i++) -+ { -+ r = posix_spawn_file_actions_adddup2 (&file_actions, duped_source_fds[i], target_fds[i]); -+ if (r != 0) -+ goto out_close_fds; -+ } -+ - /* Intentionally close the fds in the child as the last file action, - * having been careful not to add the same fd to this list twice. - * -@@ -1940,9 +1983,16 @@ do_posix_spawn (const gchar * const *argv, - *child_pid = pid; - - out_close_fds: -- for (i = 0; i < num_parent_close_fds; i++) -+ for (i = 0; i < (size_t) num_parent_close_fds; i++) - close_and_invalidate (&parent_close_fds [i]); - -+ if (duped_source_fds != NULL) -+ { -+ for (i = 0; i < n_fds; i++) -+ close_and_invalidate (&duped_source_fds[i]); -+ g_free (duped_source_fds); -+ } -+ - posix_spawn_file_actions_destroy (&file_actions); - out_free_spawnattr: - posix_spawnattr_destroy (&attr); -@@ -2030,10 +2080,8 @@ fork_exec (gboolean intermediate_child, - child_close_fds[n_child_close_fds++] = -1; - - #ifdef POSIX_SPAWN_AVAILABLE -- /* FIXME: Handle @source_fds and @target_fds in do_posix_spawn() using the -- * file actions API. */ - if (!intermediate_child && working_directory == NULL && !close_descriptors && -- !search_path_from_envp && child_setup == NULL && n_fds == 0) -+ !search_path_from_envp && child_setup == NULL) - { - g_trace_mark (G_TRACE_CURRENT_TIME, 0, - "GLib", "posix_spawn", -@@ -2050,7 +2098,10 @@ fork_exec (gboolean intermediate_child, - child_close_fds, - stdin_fd, - stdout_fd, -- stderr_fd); -+ stderr_fd, -+ source_fds, -+ target_fds, -+ n_fds); - if (status == 0) - goto success; - --- -2.33.1 - -From 731d6c32105dc97f2b777ef9a34c6b76d1489c04 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Thu, 25 Feb 2021 12:21:38 -0600 -Subject: [PATCH 06/10] gsubprocess: ensure we test fd remapping on the - posix_spawn() codepath - -We should run test_pass_fd twice, once using gspawn's fork/exec codepath -and once attempting to use its posix_spawn() codepath. There's no -guarantee we'll actually get the posix_spawn() codepath, but it works -for now on Linux. - -For good measure, run it a third time with no flags at all. - -This causes the test to fail if I separately break the fd remapping -implementation. Without this, we fail to test fd remapping on the -posix_spawn() codepath. ---- - gio/tests/gsubprocess.c | 44 ++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 41 insertions(+), 3 deletions(-) - -diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c -index 7e22678ec..ba49c1c43 100644 ---- a/gio/tests/gsubprocess.c -+++ b/gio/tests/gsubprocess.c -@@ -1697,7 +1697,8 @@ test_child_setup (void) - } - - static void --test_pass_fd (void) -+do_test_pass_fd (GSubprocessFlags flags, -+ GSpawnChildSetupFunc child_setup) - { - GError *local_error = NULL; - GError **error = &local_error; -@@ -1722,9 +1723,11 @@ test_pass_fd (void) - needdup_fd_str = g_strdup_printf ("%d", needdup_pipefds[1] + 1); - - args = get_test_subprocess_args ("write-to-fds", basic_fd_str, needdup_fd_str, NULL); -- launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); -+ launcher = g_subprocess_launcher_new (flags); - g_subprocess_launcher_take_fd (launcher, basic_pipefds[1], basic_pipefds[1]); - g_subprocess_launcher_take_fd (launcher, needdup_pipefds[1], needdup_pipefds[1] + 1); -+ if (child_setup != NULL) -+ g_subprocess_launcher_set_child_setup (launcher, child_setup, NULL, NULL); - proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); - g_ptr_array_free (args, TRUE); - g_assert_no_error (local_error); -@@ -1754,6 +1757,39 @@ test_pass_fd (void) - g_object_unref (proc); - } - -+static void -+test_pass_fd (void) -+{ -+ do_test_pass_fd (G_SUBPROCESS_FLAGS_NONE, NULL); -+} -+ -+static void -+empty_child_setup (gpointer user_data) -+{ -+} -+ -+static void -+test_pass_fd_empty_child_setup (void) -+{ -+ /* Using a child setup function forces gspawn to use fork/exec -+ * rather than posix_spawn. -+ */ -+ do_test_pass_fd (G_SUBPROCESS_FLAGS_NONE, empty_child_setup); -+} -+ -+static void -+test_pass_fd_inherit_fds (void) -+{ -+ /* Try to test the optimized posix_spawn codepath instead of -+ * fork/exec. Currently this requires using INHERIT_FDS since gspawn's -+ * posix_spawn codepath does not currently handle closing -+ * non-inherited fds. Note that using INHERIT_FDS means our testing of -+ * g_subprocess_launcher_take_fd() is less-comprehensive than when -+ * using G_SUBPROCESS_FLAGS_NONE. -+ */ -+ do_test_pass_fd (G_SUBPROCESS_FLAGS_INHERIT_FDS, NULL); -+} -+ - #endif - - static void -@@ -1891,7 +1927,9 @@ main (int argc, char **argv) - g_test_add_func ("/gsubprocess/stdout-file", test_stdout_file); - g_test_add_func ("/gsubprocess/stdout-fd", test_stdout_fd); - g_test_add_func ("/gsubprocess/child-setup", test_child_setup); -- g_test_add_func ("/gsubprocess/pass-fd", test_pass_fd); -+ g_test_add_func ("/gsubprocess/pass-fd/basic", test_pass_fd); -+ g_test_add_func ("/gsubprocess/pass-fd/empty-child-setup", test_pass_fd_empty_child_setup); -+ g_test_add_func ("/gsubprocess/pass-fd/inherit-fds", test_pass_fd_inherit_fds); - #endif - g_test_add_func ("/gsubprocess/launcher-environment", test_launcher_environment); - --- -2.33.1 - -From 4608940466a04a32d4e6e71dbe872cfecb136118 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Thu, 14 Oct 2021 11:01:33 -0500 -Subject: [PATCH 07/10] gspawn: Check from errors from safe_dup2() and - dupfd_cloexec() - -Although unlikely, these functions can fail, e.g. if we run out of file -descriptors. Check for errors to improve robustness. This is especially -important now that I changed our use of dupfd_cloexec() to avoid -returning fds smaller than the largest fd in target_fds. An application -that attempts to remap to the highest-allowed fd value deserves at least -some sort of attempt at error reporting, not silent failure. ---- - glib/gspawn.c | 40 +++++++++++++++++++++++++++++----------- - 1 file changed, 29 insertions(+), 11 deletions(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index 9ef78dbe1..7ef678047 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -1572,7 +1572,6 @@ do_exec (gint child_err_report_fd, - /* Redirect pipes as required */ - if (stdin_fd >= 0) - { -- /* dup2 can't actually fail here I don't think */ - if (safe_dup2 (stdin_fd, 0) < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -@@ -1588,13 +1587,14 @@ do_exec (gint child_err_report_fd, - if (read_null < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -- safe_dup2 (read_null, 0); -+ if (safe_dup2 (read_null, 0) < 0) -+ write_err_and_exit (child_err_report_fd, -+ CHILD_DUP2_FAILED); - close_and_invalidate (&read_null); - } - - if (stdout_fd >= 0) - { -- /* dup2 can't actually fail here I don't think */ - if (safe_dup2 (stdout_fd, 1) < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -@@ -1609,13 +1609,14 @@ do_exec (gint child_err_report_fd, - if (write_null < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -- safe_dup2 (write_null, 1); -+ if (safe_dup2 (write_null, 1) < 0) -+ write_err_and_exit (child_err_report_fd, -+ CHILD_DUP2_FAILED); - close_and_invalidate (&write_null); - } - - if (stderr_fd >= 0) - { -- /* dup2 can't actually fail here I don't think */ - if (safe_dup2 (stderr_fd, 2) < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -@@ -1630,7 +1631,9 @@ do_exec (gint child_err_report_fd, - if (write_null < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -- safe_dup2 (write_null, 2); -+ if (safe_dup2 (write_null, 2) < 0) -+ write_err_and_exit (child_err_report_fd, -+ CHILD_DUP2_FAILED); - close_and_invalidate (&write_null); - } - -@@ -1643,7 +1646,8 @@ do_exec (gint child_err_report_fd, - { - if (child_setup == NULL && n_fds == 0) - { -- safe_dup2 (child_err_report_fd, 3); -+ if (safe_dup2 (child_err_report_fd, 3) < 0) -+ write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED); - set_cloexec (GINT_TO_POINTER (0), 3); - safe_closefrom (4); - child_err_report_fd = 3; -@@ -1682,7 +1686,11 @@ do_exec (gint child_err_report_fd, - for (i = 0; i < n_fds; i++) - { - if (source_fds[i] != target_fds[i]) -- source_fds[i] = dupfd_cloexec (source_fds[i], max_target_fd + 1); -+ { -+ source_fds[i] = dupfd_cloexec (source_fds[i], max_target_fd + 1); -+ if (source_fds[i] < 0) -+ write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED); -+ } - } - - for (i = 0; i < n_fds; i++) -@@ -1700,9 +1708,15 @@ do_exec (gint child_err_report_fd, - * dup it so it doesn’t get conflated. - */ - if (target_fds[i] == child_err_report_fd) -- child_err_report_fd = dupfd_cloexec (child_err_report_fd, max_target_fd + 1); -+ { -+ child_err_report_fd = dupfd_cloexec (child_err_report_fd, max_target_fd + 1); -+ if (child_err_report_fd < 0) -+ write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED); -+ } -+ -+ if (safe_dup2 (source_fds[i], target_fds[i]) < 0) -+ write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED); - -- safe_dup2 (source_fds[i], target_fds[i]); - close_and_invalidate (&source_fds[i]); - } - } -@@ -1945,7 +1959,11 @@ do_posix_spawn (const gchar * const *argv, - - duped_source_fds = g_new (gint, n_fds); - for (i = 0; i < n_fds; i++) -- duped_source_fds[i] = dupfd_cloexec (source_fds[i], max_target_fd + 1); -+ { -+ duped_source_fds[i] = dupfd_cloexec (source_fds[i], max_target_fd + 1); -+ if (duped_source_fds[i] < 0) -+ goto out_close_fds; -+ } - - for (i = 0; i < n_fds; i++) - { --- -2.33.1 - -From 0198b6a1c8c215f524d7c6ed2d240fb1b31d9865 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Wed, 20 Oct 2021 16:51:44 -0500 -Subject: [PATCH 08/10] gspawn: add new error message for open() failures - -Reporting these as dup2() failures is bogus. ---- - glib/gspawn.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index 7ef678047..c2fe306dc 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -1532,6 +1532,7 @@ enum - { - CHILD_CHDIR_FAILED, - CHILD_EXEC_FAILED, -+ CHILD_OPEN_FAILED, - CHILD_DUP2_FAILED, - CHILD_FORK_FAILED - }; -@@ -1586,7 +1587,7 @@ do_exec (gint child_err_report_fd, - gint read_null = safe_open ("/dev/null", O_RDONLY); - if (read_null < 0) - write_err_and_exit (child_err_report_fd, -- CHILD_DUP2_FAILED); -+ CHILD_OPEN_FAILED); - if (safe_dup2 (read_null, 0) < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -@@ -1608,7 +1609,7 @@ do_exec (gint child_err_report_fd, - gint write_null = safe_open ("/dev/null", O_WRONLY); - if (write_null < 0) - write_err_and_exit (child_err_report_fd, -- CHILD_DUP2_FAILED); -+ CHILD_OPEN_FAILED); - if (safe_dup2 (write_null, 1) < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -@@ -1630,7 +1631,7 @@ do_exec (gint child_err_report_fd, - gint write_null = safe_open ("/dev/null", O_WRONLY); - if (write_null < 0) - write_err_and_exit (child_err_report_fd, -- CHILD_DUP2_FAILED); -+ CHILD_OPEN_FAILED); - if (safe_dup2 (write_null, 2) < 0) - write_err_and_exit (child_err_report_fd, - CHILD_DUP2_FAILED); -@@ -2420,7 +2421,15 @@ fork_exec (gboolean intermediate_child, - g_strerror (buf[1])); - - break; -- -+ -+ case CHILD_OPEN_FAILED: -+ g_set_error (error, -+ G_SPAWN_ERROR, -+ G_SPAWN_ERROR_FAILED, -+ _("Failed to open file to remap file descriptor (%s)"), -+ g_strerror (buf[1])); -+ break; -+ - case CHILD_DUP2_FAILED: - g_set_error (error, - G_SPAWN_ERROR, --- -2.33.1 - -From e4abb5f3db85b2f730e192e6398f26934e41ba21 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Tue, 26 Oct 2021 21:27:15 -0500 -Subject: [PATCH 09/10] Add tests for GSubprocess fd conflation issues - -This tests for #2503. It's fragile, but there is no non-fragile way to -test this. If the test breaks in the future, it will pass without -successfully testing the bug, not fail spuriously, so I think this is -OK. ---- - gio/tests/gsubprocess-testprog.c | 53 +++++++++++- - gio/tests/gsubprocess.c | 144 +++++++++++++++++++++++++++++++ - 2 files changed, 195 insertions(+), 2 deletions(-) - -diff --git a/gio/tests/gsubprocess-testprog.c b/gio/tests/gsubprocess-testprog.c -index c9b06c2a2..58cb1c71d 100644 ---- a/gio/tests/gsubprocess-testprog.c -+++ b/gio/tests/gsubprocess-testprog.c -@@ -5,8 +5,6 @@ - #include - #ifdef G_OS_UNIX - #include --#include --#include - #else - #include - #endif -@@ -150,6 +148,55 @@ write_to_fds (int argc, char **argv) - return 0; - } - -+static int -+read_from_fd (int argc, char **argv) -+{ -+ int fd; -+ const char expectedResult[] = "Yay success!"; -+ guint8 buf[sizeof (expectedResult) + 1]; -+ gsize bytes_read; -+ FILE *f; -+ -+ if (argc != 3) -+ { -+ g_print ("Usage: %s read-from-fd FD\n", argv[0]); -+ return 1; -+ } -+ -+ fd = atoi (argv[2]); -+ if (fd == 0) -+ { -+ g_warning ("Argument \"%s\" does not look like a valid nonzero file descriptor", argv[2]); -+ return 1; -+ } -+ -+ f = fdopen (fd, "r"); -+ if (f == NULL) -+ { -+ g_warning ("Failed to open fd %d: %s", fd, g_strerror (errno)); -+ return 1; -+ } -+ -+ bytes_read = fread (buf, 1, sizeof (buf), f); -+ if (bytes_read != sizeof (expectedResult)) -+ { -+ g_warning ("Read %zu bytes, but expected %zu", bytes_read, sizeof (expectedResult)); -+ return 1; -+ } -+ -+ if (memcmp (expectedResult, buf, sizeof (expectedResult)) != 0) -+ { -+ buf[sizeof (expectedResult)] = '\0'; -+ g_warning ("Expected \"%s\" but read \"%s\"", expectedResult, (char *)buf); -+ return 1; -+ } -+ -+ if (fclose (f) == -1) -+ g_assert_not_reached (); -+ -+ return 0; -+} -+ - static int - env_mode (int argc, char **argv) - { -@@ -242,6 +289,8 @@ main (int argc, char **argv) - return sleep_forever_mode (argc, argv); - else if (strcmp (mode, "write-to-fds") == 0) - return write_to_fds (argc, argv); -+ else if (strcmp (mode, "read-from-fd") == 0) -+ return read_from_fd (argc, argv); - else if (strcmp (mode, "env") == 0) - return env_mode (argc, argv); - else if (strcmp (mode, "cwd") == 0) -diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c -index ba49c1c43..a6e24c2e8 100644 ---- a/gio/tests/gsubprocess.c -+++ b/gio/tests/gsubprocess.c -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1790,6 +1791,146 @@ test_pass_fd_inherit_fds (void) - do_test_pass_fd (G_SUBPROCESS_FLAGS_INHERIT_FDS, NULL); - } - -+static void -+do_test_fd_conflation (GSubprocessFlags flags, -+ GSpawnChildSetupFunc child_setup) -+{ -+ char success_message[] = "Yay success!"; -+ GError *error = NULL; -+ GOutputStream *output_stream; -+ GSubprocessLauncher *launcher; -+ GSubprocess *proc; -+ GPtrArray *args; -+ int unused_pipefds[2]; -+ int pipefds[2]; -+ gsize bytes_written; -+ gboolean success; -+ char *fd_str; -+ -+ /* This test must run in a new process because it is extremely sensitive to -+ * order of opened fds. -+ */ -+ if (!g_test_subprocess ()) -+ { -+ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR); -+ g_test_trap_assert_passed (); -+ return; -+ } -+ -+ g_unix_open_pipe (unused_pipefds, FD_CLOEXEC, &error); -+ g_assert_no_error (error); -+ -+ g_unix_open_pipe (pipefds, FD_CLOEXEC, &error); -+ g_assert_no_error (error); -+ -+ /* The fds should be sequential since we are in a new process. */ -+ g_assert_cmpint (unused_pipefds[0] /* 3 */, ==, unused_pipefds[1] - 1); -+ g_assert_cmpint (unused_pipefds[1] /* 4 */, ==, pipefds[0] - 1); -+ g_assert_cmpint (pipefds[0] /* 5 */, ==, pipefds[1] /* 6 */ - 1); -+ -+ /* Because GSubprocess allows arbitrary remapping of fds, it has to be careful -+ * to avoid fd conflation issues, e.g. it should properly handle 5 -> 4 and -+ * 4 -> 5 at the same time. GIO previously attempted to handle this by naively -+ * dup'ing the source fds, but this was not good enough because it was -+ * possible that the dup'ed result could still conflict with one of the target -+ * fds. For example: -+ * -+ * source_fd 5 -> target_fd 9, source_fd 3 -> target_fd 7 -+ * -+ * dup(5) -> dup returns 8 -+ * dup(3) -> dup returns 9 -+ * -+ * After dup'ing, we wind up with: 8 -> 9, 9 -> 7. That means that after we -+ * dup2(8, 9), we have clobbered fd 9 before we dup2(9, 7). The end result is -+ * we have remapped 5 -> 9 as expected, but then remapped 5 -> 7 instead of -+ * 3 -> 7 as the application intended. -+ * -+ * This issue has been fixed in the simplest way possible, by passing a -+ * minimum fd value when using F_DUPFD_CLOEXEC that is higher than any of the -+ * target fds, to guarantee all source fds are different than all target fds, -+ * eliminating any possibility of conflation. -+ * -+ * Anyway, that is why we have the unused_pipefds here. We need to open fds in -+ * a certain order in order to trick older GSubprocess into conflating the -+ * fds. The primary goal of this test is to ensure this particular conflation -+ * issue is not reintroduced. See glib#2503. -+ * -+ * Be aware this test is necessarily extremely fragile. To reproduce these -+ * bugs, it relies on internals of gspawn and gmain that will likely change -+ * in the future, eventually causing this test to no longer test the the bugs -+ * it was originally designed to test. That is OK! If the test fails, at -+ * least you know *something* is wrong. -+ */ -+ launcher = g_subprocess_launcher_new (flags); -+ g_subprocess_launcher_take_fd (launcher, pipefds[0] /* 5 */, pipefds[1] + 3 /* 9 */); -+ g_subprocess_launcher_take_fd (launcher, unused_pipefds[0] /* 3 */, pipefds[1] + 1 /* 7 */); -+ if (child_setup != NULL) -+ g_subprocess_launcher_set_child_setup (launcher, child_setup, NULL, NULL); -+ fd_str = g_strdup_printf ("%d", pipefds[1] + 3); -+ args = get_test_subprocess_args ("read-from-fd", fd_str, NULL); -+ proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, &error); -+ g_assert_no_error (error); -+ g_assert_nonnull (proc); -+ g_ptr_array_free (args, TRUE); -+ g_object_unref (launcher); -+ g_free (fd_str); -+ -+ /* Close the read ends of the pipes. */ -+ close (unused_pipefds[0]); -+ close (pipefds[0]); -+ -+ /* Also close the write end of the unused pipe. */ -+ close (unused_pipefds[1]); -+ -+ /* So now pipefds[0] should be inherited into the subprocess as -+ * pipefds[1] + 2, and unused_pipefds[0] should be inherited as -+ * pipefds[1] + 1. We will write to pipefds[1] and the subprocess will verify -+ * that it reads the expected data. But older broken GIO will accidentally -+ * clobber pipefds[1] + 2 with pipefds[1] + 1! This will cause the subprocess -+ * to hang trying to read from the wrong pipe. -+ */ -+ output_stream = g_unix_output_stream_new (pipefds[1], TRUE); -+ success = g_output_stream_write_all (output_stream, -+ success_message, sizeof (success_message), -+ &bytes_written, -+ NULL, -+ &error); -+ g_assert_no_error (error); -+ g_assert_cmpint (bytes_written, ==, sizeof (success_message)); -+ g_assert_true (success); -+ g_object_unref (output_stream); -+ -+ success = g_subprocess_wait_check (proc, NULL, &error); -+ g_assert_no_error (error); -+ g_object_unref (proc); -+} -+ -+static void -+test_fd_conflation (void) -+{ -+ do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, NULL); -+} -+ -+static void -+test_fd_conflation_empty_child_setup (void) -+{ -+ /* Using a child setup function forces gspawn to use fork/exec -+ * rather than posix_spawn. -+ */ -+ do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, empty_child_setup); -+} -+ -+static void -+test_fd_conflation_inherit_fds (void) -+{ -+ /* Try to test the optimized posix_spawn codepath instead of -+ * fork/exec. Currently this requires using INHERIT_FDS since gspawn's -+ * posix_spawn codepath does not currently handle closing -+ * non-inherited fds. -+ */ -+ do_test_fd_conflation (G_SUBPROCESS_FLAGS_INHERIT_FDS, NULL); -+} -+ - #endif - - static void -@@ -1930,6 +2071,9 @@ main (int argc, char **argv) - g_test_add_func ("/gsubprocess/pass-fd/basic", test_pass_fd); - g_test_add_func ("/gsubprocess/pass-fd/empty-child-setup", test_pass_fd_empty_child_setup); - g_test_add_func ("/gsubprocess/pass-fd/inherit-fds", test_pass_fd_inherit_fds); -+ g_test_add_func ("/gsubprocess/fd-conflation/basic", test_fd_conflation); -+ g_test_add_func ("/gsubprocess/fd-conflation/empty-child-setup", test_fd_conflation_empty_child_setup); -+ g_test_add_func ("/gsubprocess/fd-conflation/inherit-fds", test_fd_conflation_inherit_fds); - #endif - g_test_add_func ("/gsubprocess/launcher-environment", test_launcher_environment); - --- -2.33.1 - -From 5542612c805857a244561ec160e904dd302ae799 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Wed, 27 Oct 2021 18:30:47 -0500 -Subject: [PATCH 10/10] Add test for child_err_report_fd conflation with target - fds - -This tests for glib#2506. ---- - gio/tests/gsubprocess.c | 42 ++++++++++++++++++++++++++++++++++------- - 1 file changed, 35 insertions(+), 7 deletions(-) - -diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c -index a6e24c2e8..4629cdea7 100644 ---- a/gio/tests/gsubprocess.c -+++ b/gio/tests/gsubprocess.c -@@ -1793,7 +1793,8 @@ test_pass_fd_inherit_fds (void) - - static void - do_test_fd_conflation (GSubprocessFlags flags, -- GSpawnChildSetupFunc child_setup) -+ GSpawnChildSetupFunc child_setup, -+ gboolean test_child_err_report_fd) - { - char success_message[] = "Yay success!"; - GError *error = NULL; -@@ -1803,6 +1804,7 @@ do_test_fd_conflation (GSubprocessFlags flags, - GPtrArray *args; - int unused_pipefds[2]; - int pipefds[2]; -+ int fd_to_pass_to_child; - gsize bytes_written; - gboolean success; - char *fd_str; -@@ -1855,18 +1857,26 @@ do_test_fd_conflation (GSubprocessFlags flags, - * fds. The primary goal of this test is to ensure this particular conflation - * issue is not reintroduced. See glib#2503. - * -+ * This test also has an alternate mode of operation where it instead tests -+ * for conflation with gspawn's child_err_report_fd, glib#2506. -+ * - * Be aware this test is necessarily extremely fragile. To reproduce these - * bugs, it relies on internals of gspawn and gmain that will likely change - * in the future, eventually causing this test to no longer test the the bugs - * it was originally designed to test. That is OK! If the test fails, at - * least you know *something* is wrong. - */ -+ if (test_child_err_report_fd) -+ fd_to_pass_to_child = pipefds[1] + 2 /* 8 */; -+ else -+ fd_to_pass_to_child = pipefds[1] + 3 /* 9 */; -+ - launcher = g_subprocess_launcher_new (flags); -- g_subprocess_launcher_take_fd (launcher, pipefds[0] /* 5 */, pipefds[1] + 3 /* 9 */); -+ g_subprocess_launcher_take_fd (launcher, pipefds[0] /* 5 */, fd_to_pass_to_child); - g_subprocess_launcher_take_fd (launcher, unused_pipefds[0] /* 3 */, pipefds[1] + 1 /* 7 */); - if (child_setup != NULL) - g_subprocess_launcher_set_child_setup (launcher, child_setup, NULL, NULL); -- fd_str = g_strdup_printf ("%d", pipefds[1] + 3); -+ fd_str = g_strdup_printf ("%d", fd_to_pass_to_child); - args = get_test_subprocess_args ("read-from-fd", fd_str, NULL); - proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, &error); - g_assert_no_error (error); -@@ -1882,12 +1892,20 @@ do_test_fd_conflation (GSubprocessFlags flags, - /* Also close the write end of the unused pipe. */ - close (unused_pipefds[1]); - -- /* So now pipefds[0] should be inherited into the subprocess as -+ /* If doing our normal test: -+ * -+ * So now pipefds[0] should be inherited into the subprocess as - * pipefds[1] + 2, and unused_pipefds[0] should be inherited as - * pipefds[1] + 1. We will write to pipefds[1] and the subprocess will verify - * that it reads the expected data. But older broken GIO will accidentally - * clobber pipefds[1] + 2 with pipefds[1] + 1! This will cause the subprocess - * to hang trying to read from the wrong pipe. -+ * -+ * If testing conflation with child_err_report_fd: -+ * -+ * We are actually already done. The real test succeeded if we made it this -+ * far without hanging while spawning the child. But let's continue with our -+ * write and read anyway, to ensure things are good. - */ - output_stream = g_unix_output_stream_new (pipefds[1], TRUE); - success = g_output_stream_write_all (output_stream, -@@ -1908,7 +1926,7 @@ do_test_fd_conflation (GSubprocessFlags flags, - static void - test_fd_conflation (void) - { -- do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, NULL); -+ do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, NULL, FALSE); - } - - static void -@@ -1917,7 +1935,7 @@ test_fd_conflation_empty_child_setup (void) - /* Using a child setup function forces gspawn to use fork/exec - * rather than posix_spawn. - */ -- do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, empty_child_setup); -+ do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, empty_child_setup, FALSE); - } - - static void -@@ -1928,7 +1946,16 @@ test_fd_conflation_inherit_fds (void) - * posix_spawn codepath does not currently handle closing - * non-inherited fds. - */ -- do_test_fd_conflation (G_SUBPROCESS_FLAGS_INHERIT_FDS, NULL); -+ do_test_fd_conflation (G_SUBPROCESS_FLAGS_INHERIT_FDS, NULL, FALSE); -+} -+ -+static void -+test_fd_conflation_child_err_report_fd (void) -+{ -+ /* Using a child setup function forces gspawn to use fork/exec -+ * rather than posix_spawn. -+ */ -+ do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, empty_child_setup, TRUE); - } - - #endif -@@ -2074,6 +2101,7 @@ main (int argc, char **argv) - g_test_add_func ("/gsubprocess/fd-conflation/basic", test_fd_conflation); - g_test_add_func ("/gsubprocess/fd-conflation/empty-child-setup", test_fd_conflation_empty_child_setup); - g_test_add_func ("/gsubprocess/fd-conflation/inherit-fds", test_fd_conflation_inherit_fds); -+ g_test_add_func ("/gsubprocess/fd-conflation/child-err-report-fd", test_fd_conflation_child_err_report_fd); - #endif - g_test_add_func ("/gsubprocess/launcher-environment", test_launcher_environment); - --- -2.33.1 - diff --git a/base/rx-glib2/2194.patch b/base/rx-glib2/2194.patch deleted file mode 100644 index 5c9aaf2..0000000 --- a/base/rx-glib2/2194.patch +++ /dev/null @@ -1,920 +0,0 @@ -From 2e500304e304e45042a59855319ff0379b1978b3 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Tue, 27 Jul 2021 17:24:17 +0200 -Subject: [PATCH 1/4] tests: Remove unused constant in GMemoryMonitor test - ---- - gio/tests/memory-monitor-dbus.py.in | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/gio/tests/memory-monitor-dbus.py.in b/gio/tests/memory-monitor-dbus.py.in -index cd16cf4e3..7823e7309 100755 ---- a/gio/tests/memory-monitor-dbus.py.in -+++ b/gio/tests/memory-monitor-dbus.py.in -@@ -31,9 +31,6 @@ try: - - dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - -- # XDG_DESKTOP_PORTAL_PATH = os.path.expanduser("~/.cache/jhbuild/build/xdg-desktop-portal/xdg-desktop-portal") -- XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal" -- - class TestLowMemoryMonitor(dbusmock.DBusTestCase): - '''Test GMemoryMonitorDBus''' - --- -GitLab - - -From a7000cd989438b01e599b2cfa8b6d5a360bfd102 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Wed, 28 Jul 2021 15:10:16 +0200 -Subject: [PATCH 2/4] gio: g_clear_signal_handler() can handle NULL args - ---- - gio/gmemorymonitordbus.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/gio/gmemorymonitordbus.c b/gio/gmemorymonitordbus.c -index a34a58d3b..08dc53df1 100644 ---- a/gio/gmemorymonitordbus.c -+++ b/gio/gmemorymonitordbus.c -@@ -115,8 +115,7 @@ lmm_vanished_cb (GDBusConnection *connection, - { - GMemoryMonitorDBus *dbus = user_data; - -- if (dbus->proxy != NULL) -- g_clear_signal_handler (&dbus->signal_id, dbus->proxy); -+ g_clear_signal_handler (&dbus->signal_id, dbus->proxy); - g_clear_object (&dbus->proxy); - } - -@@ -143,8 +142,7 @@ g_memory_monitor_dbus_finalize (GObject *object) - { - GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (object); - -- if (dbus->proxy != NULL) -- g_clear_signal_handler (&dbus->signal_id, dbus->proxy); -+ g_clear_signal_handler (&dbus->signal_id, dbus->proxy); - g_clear_object (&dbus->proxy); - g_clear_handle_id (&dbus->watch_id, g_bus_unwatch_name); - --- -GitLab - - -From 92399e7114e590f0371b1a5d71f478f840cb4074 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Wed, 28 Jul 2021 15:30:15 +0200 -Subject: [PATCH 3/4] gio: Do not block when low-memory-monitor daemon appears - ---- - gio/gmemorymonitordbus.c | 42 +++++++++++++++++++++++++++------------- - 1 file changed, 29 insertions(+), 13 deletions(-) - -diff --git a/gio/gmemorymonitordbus.c b/gio/gmemorymonitordbus.c -index 08dc53df1..739b83214 100644 ---- a/gio/gmemorymonitordbus.c -+++ b/gio/gmemorymonitordbus.c -@@ -25,6 +25,7 @@ - #include "giomodule-priv.h" - #include "glibintl.h" - #include "glib/gstdio.h" -+#include "gcancellable.h" - #include "gdbusproxy.h" - #include "gdbusnamewatching.h" - -@@ -38,6 +39,7 @@ struct _GMemoryMonitorDBus - GObject parent_instance; - - guint watch_id; -+ GCancellable *cancellable; - GDBusProxy *proxy; - gulong signal_id; - }; -@@ -77,24 +79,15 @@ proxy_signal_cb (GDBusProxy *proxy, - } - - static void --lmm_appeared_cb (GDBusConnection *connection, -- const gchar *name, -- const gchar *name_owner, -- gpointer user_data) -+lmm_proxy_cb (GObject *source_object, -+ GAsyncResult *res, -+ gpointer user_data) - { - GMemoryMonitorDBus *dbus = user_data; - GDBusProxy *proxy; - GError *error = NULL; - -- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, -- G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, -- NULL, -- "org.freedesktop.LowMemoryMonitor", -- "/org/freedesktop/LowMemoryMonitor", -- "org.freedesktop.LowMemoryMonitor", -- NULL, -- &error); -- -+ proxy = g_dbus_proxy_new_finish (res, &error); - if (!proxy) - { - g_debug ("Failed to create LowMemoryMonitor D-Bus proxy: %s", -@@ -106,6 +99,26 @@ lmm_appeared_cb (GDBusConnection *connection, - dbus->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal", - G_CALLBACK (proxy_signal_cb), dbus); - dbus->proxy = proxy; -+ -+} -+ -+static void -+lmm_appeared_cb (GDBusConnection *connection, -+ const gchar *name, -+ const gchar *name_owner, -+ gpointer user_data) -+{ -+ GMemoryMonitorDBus *dbus = user_data; -+ -+ g_dbus_proxy_new (connection, -+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, -+ NULL, -+ "org.freedesktop.LowMemoryMonitor", -+ "/org/freedesktop/LowMemoryMonitor", -+ "org.freedesktop.LowMemoryMonitor", -+ dbus->cancellable, -+ lmm_proxy_cb, -+ dbus); - } - - static void -@@ -126,6 +139,7 @@ g_memory_monitor_dbus_initable_init (GInitable *initable, - { - GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (initable); - -+ dbus->cancellable = g_cancellable_new (); - dbus->watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, - "org.freedesktop.LowMemoryMonitor", - G_BUS_NAME_WATCHER_FLAGS_AUTO_START, -@@ -142,6 +156,8 @@ g_memory_monitor_dbus_finalize (GObject *object) - { - GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (object); - -+ g_cancellable_cancel (dbus->cancellable); -+ g_clear_object (&dbus->cancellable); - g_clear_signal_handler (&dbus->signal_id, dbus->proxy); - g_clear_object (&dbus->proxy); - g_clear_handle_id (&dbus->watch_id, g_bus_unwatch_name); --- -GitLab - - -From 889bdb994fed44344a84ad01aa5633a1b1b62b19 Mon Sep 17 00:00:00 2001 -From: Patrick Griffis -Date: Tue, 20 Jul 2021 16:04:31 -0500 -Subject: [PATCH 4/4] Add GPowerProfileMonitor - ---- - docs/reference/gio/gio-docs.xml | 1 + - docs/reference/gio/gio-sections-common.txt | 18 ++ - docs/reference/gio/meson.build | 1 + - gio/gio.h | 1 + - gio/giomodule.c | 7 + - gio/gpowerprofilemonitor.c | 141 ++++++++++++ - gio/gpowerprofilemonitor.h | 63 ++++++ - gio/gpowerprofilemonitordbus.c | 240 +++++++++++++++++++++ - gio/gpowerprofilemonitordbus.h | 32 +++ - gio/meson.build | 3 + - gio/tests/meson.build | 1 + - gio/tests/power-profile-monitor.c | 79 +++++++ - 12 files changed, 587 insertions(+) - create mode 100644 gio/gpowerprofilemonitor.c - create mode 100644 gio/gpowerprofilemonitor.h - create mode 100644 gio/gpowerprofilemonitordbus.c - create mode 100644 gio/gpowerprofilemonitordbus.h - create mode 100644 gio/tests/power-profile-monitor.c - -diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml -index a09d6d31d..b01133900 100644 ---- a/docs/reference/gio/gio-docs.xml -+++ b/docs/reference/gio/gio-docs.xml -@@ -238,6 +238,7 @@ - - - -+ - - - Extending GIO -diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt -index 250491a42..a7addedc2 100644 ---- a/docs/reference/gio/gio-sections-common.txt -+++ b/docs/reference/gio/gio-sections-common.txt -@@ -4247,6 +4247,24 @@ G_NETWORK_MONITOR_GET_INTERFACE - g_network_connectivity_get_type - - -+
-+gpowerprofilemonitor -+GPowerProfileMonitor -+GPowerProfileMonitor -+GPowerProfileMonitorInterface -+G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME -+g_power_profile_monitor_dup_default -+g_power_profile_monitor_get_power_saver_enabled -+ -+g_power_profile_monitor_get_type -+G_TYPE_POWER_PROFILE_MONITOR -+G_POWER_PROFILE_MONITOR -+G_IS_POWER_PROFILE_MONITOR -+G_POWER_PROFILE_MONITOR_GET_INTERFACE -+G_TYPE_POWER_PROFILE_LEVEL -+g_power_profile_level_get_type -+
-+ -
- gmenuexporter - g_dbus_connection_export_menu_model -diff --git a/docs/reference/gio/meson.build b/docs/reference/gio/meson.build -index 4d0364819..fbabd25ca 100644 ---- a/docs/reference/gio/meson.build -+++ b/docs/reference/gio/meson.build -@@ -65,6 +65,7 @@ if get_option('gtk_doc') - 'gopenuriportal.h', - 'gpollfilemonitor.h', - 'gportalsupport.h', -+ 'gpowerprofilemonitordbus.h', - 'gproxyresolverportal.h', - 'gregistrysettingsbackend.h', - 'gresourcefile.h', -diff --git a/gio/gio.h b/gio/gio.h -index f5d2dd5a3..e9afab666 100644 ---- a/gio/gio.h -+++ b/gio/gio.h -@@ -120,6 +120,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/gio/giomodule.c b/gio/giomodule.c -index c1d451b5c..dfd895717 100644 ---- a/gio/giomodule.c -+++ b/gio/giomodule.c -@@ -48,6 +48,8 @@ - #include "gmemorymonitor.h" - #include "gmemorymonitorportal.h" - #include "gmemorymonitordbus.h" -+#include "gpowerprofilemonitor.h" -+#include "gpowerprofilemonitordbus.h" - #ifdef G_OS_WIN32 - #include "gregistrysettingsbackend.h" - #include "giowin32-priv.h" -@@ -1077,6 +1079,7 @@ extern GType _g_network_monitor_nm_get_type (void); - - extern GType g_memory_monitor_dbus_get_type (void); - extern GType g_memory_monitor_portal_get_type (void); -+extern GType g_power_profile_monitor_dbus_get_type (void); - - #ifdef G_OS_UNIX - extern GType g_fdo_notification_backend_get_type (void); -@@ -1187,6 +1190,9 @@ _g_io_modules_ensure_extension_points_registered (void) - - ep = g_io_extension_point_register (G_MEMORY_MONITOR_EXTENSION_POINT_NAME); - g_io_extension_point_set_required_type (ep, G_TYPE_MEMORY_MONITOR); -+ -+ ep = g_io_extension_point_register (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME); -+ g_io_extension_point_set_required_type (ep, G_TYPE_POWER_PROFILE_MONITOR); - } - - G_UNLOCK (registered_extensions); -@@ -1272,6 +1278,7 @@ _g_io_modules_ensure_loaded (void) - g_type_ensure (g_null_settings_backend_get_type ()); - g_type_ensure (g_memory_settings_backend_get_type ()); - g_type_ensure (g_keyfile_settings_backend_get_type ()); -+ g_type_ensure (g_power_profile_monitor_dbus_get_type ()); - #if defined(HAVE_INOTIFY_INIT1) - g_type_ensure (g_inotify_file_monitor_get_type ()); - #endif -diff --git a/gio/gpowerprofilemonitor.c b/gio/gpowerprofilemonitor.c -new file mode 100644 -index 000000000..f5028b3e8 ---- /dev/null -+++ b/gio/gpowerprofilemonitor.c -@@ -0,0 +1,141 @@ -+/* GIO - GLib Input, Output and Streaming Library -+ * -+ * Copyright 2019 Red Hat, Inc -+ * Copyright 2021 Igalia S.L. -+ * -+ * 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 "glib.h" -+#include "glibintl.h" -+ -+#include "gpowerprofilemonitor.h" -+#include "ginetaddress.h" -+#include "ginetsocketaddress.h" -+#include "ginitable.h" -+#include "gioenumtypes.h" -+#include "giomodule-priv.h" -+#include "gtask.h" -+ -+/** -+ * SECTION:gpowerprofilemonitor -+ * @title: GPowerProfileMonitor -+ * @short_description: Power profile monitor -+ * @include: gio/gio.h -+ * -+ * #GPowerProfileMonitor makes it possible for applications as well as OS components -+ * to monitor system power profiles and act upon them. It currently only exports -+ * whether the system is in “Power Saver” mode (known as “Low Power” mode on -+ * some systems). -+ * -+ * When in “Low Power” mode, it is recommended that applications: -+ * - disabling automatic downloads -+ * - reduce the rate of refresh from online sources such as calendar or -+ * email synchronisation -+ * - if the application has expensive visual effects, reduce them -+ * -+ * It is also likely that OS components providing services to applications will -+ * lower their own background activity, for the sake of the system. -+ * -+ * There are a variety of tools that exist for power consumption analysis, but those -+ * usually depend on the OS and hardware used. On Linux, one could use `upower` to -+ * monitor the battery discharge rate, `powertop` to check on the background activity -+ * or activity at all), `sysprof` to inspect CPU usage, and `intel_gpu_time` to -+ * profile GPU usage. -+ * -+ * Don't forget to disconnect the #GPowerProfileMonitor::notify::power-saver-enabled -+ * signal, and unref the #GPowerProfileMonitor itself when exiting. -+ * -+ * Since: 2.70 -+ */ -+ -+/** -+ * GPowerProfileMonitor: -+ * -+ * #GPowerProfileMonitor monitors system power profile and notifies on -+ * changes. -+ * -+ * Since: 2.70 -+ */ -+ -+/** -+ * GPowerProfileMonitorInterface: -+ * @g_iface: The parent interface. -+ * -+ * The virtual function table for #GPowerProfileMonitor. -+ * -+ * Since: 2.70 -+ */ -+ -+G_DEFINE_INTERFACE_WITH_CODE (GPowerProfileMonitor, g_power_profile_monitor, G_TYPE_OBJECT, -+ g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE)) -+ -+ -+/** -+ * g_power_profile_monitor_dup_default: -+ * -+ * Gets a reference to the default #GPowerProfileMonitor for the system. -+ * -+ * Returns: (not nullable) (transfer full): a new reference to the default #GPowerProfileMonitor -+ * -+ * Since: 2.70 -+ */ -+GPowerProfileMonitor * -+g_power_profile_monitor_dup_default (void) -+{ -+ return g_object_ref (_g_io_module_get_default (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME, -+ "GIO_USE_POWER_PROFILE_MONITOR", -+ NULL)); -+} -+ -+/** -+ * g_power_profile_monitor_get_power_saver_enabled: -+ * @monitor: a #GPowerProfileMonitor -+ * -+ * Gets whether the system is in “Power Saver” mode. -+ * -+ * You are expected to listen to the -+ * #GPowerProfileMonitor::notify::power-saver-enabled signal to know when the profile has -+ * changed. -+ * -+ * Returns: Whether the system is in “Power Saver” mode. -+ * -+ * Since: 2.70 -+ */ -+gboolean -+g_power_profile_monitor_get_power_saver_enabled (GPowerProfileMonitor *monitor) -+{ -+ gboolean enabled; -+ g_object_get (monitor, "power-saver-enabled", &enabled, NULL); -+ return enabled; -+} -+ -+static void -+g_power_profile_monitor_default_init (GPowerProfileMonitorInterface *iface) -+{ -+ /** -+ * GPowerProfileMonitor:power-saver-enabled: -+ * -+ * Whether “Power Saver” mode is enabled on the system. -+ * -+ * Since: 2.70 -+ */ -+ g_object_interface_install_property (iface, -+ g_param_spec_boolean ("power-saver-enabled", -+ "power-saver-enabled", -+ "Power Saver Enabled", -+ FALSE, -+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); -+} -diff --git a/gio/gpowerprofilemonitor.h b/gio/gpowerprofilemonitor.h -new file mode 100644 -index 000000000..0891fc3dc ---- /dev/null -+++ b/gio/gpowerprofilemonitor.h -@@ -0,0 +1,63 @@ -+/* GIO - GLib Input, Output and Streaming Library -+ * -+ * Copyright 2019 Red Hat, Inc. -+ * Copyright 2021 Igalia S.L. -+ * -+ * 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_POWER_PROFILE_MONITOR_H__ -+#define __G_POWER_PROFILE_MONITOR_H__ -+ -+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) -+#error "Only can be included directly." -+#endif -+ -+#include -+ -+G_BEGIN_DECLS -+ -+/** -+ * G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME: -+ * -+ * Extension point for power profile usage monitoring functionality. -+ * See [Extending GIO][extending-gio]. -+ * -+ * Since: 2.70 -+ */ -+#define G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME "gio-power-profile-monitor" -+ -+#define G_TYPE_POWER_PROFILE_MONITOR (g_power_profile_monitor_get_type ()) -+GLIB_AVAILABLE_IN_2_70 -+G_DECLARE_INTERFACE (GPowerProfileMonitor, g_power_profile_monitor, g, power_profile_monitor, GObject) -+ -+#define G_POWER_PROFILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_POWER_PROFILE_MONITOR, GPowerProfileMonitor)) -+#define G_IS_POWER_PROFILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_POWER_PROFILE_MONITOR)) -+#define G_POWER_PROFILE_MONITOR_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_POWER_PROFILE_MONITOR, GPowerProfileMonitorInterface)) -+ -+struct _GPowerProfileMonitorInterface -+{ -+ /*< private >*/ -+ GTypeInterface g_iface; -+}; -+ -+GLIB_AVAILABLE_IN_2_70 -+GPowerProfileMonitor *g_power_profile_monitor_dup_default (void); -+ -+GLIB_AVAILABLE_IN_2_70 -+gboolean g_power_profile_monitor_get_power_saver_enabled (GPowerProfileMonitor *monitor); -+ -+G_END_DECLS -+ -+#endif /* __G_POWER_PROFILE_MONITOR_H__ */ -diff --git a/gio/gpowerprofilemonitordbus.c b/gio/gpowerprofilemonitordbus.c -new file mode 100644 -index 000000000..8bbfe3acc ---- /dev/null -+++ b/gio/gpowerprofilemonitordbus.c -@@ -0,0 +1,240 @@ -+/* GIO - GLib Input, Output and Streaming Library -+ * -+ * Copyright 2019 Red Hat, Inc. -+ * Copyrgith 2021 Igalia S.L. -+ * -+ * 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 "gpowerprofilemonitor.h" -+#include "gpowerprofilemonitordbus.h" -+#include "gioerror.h" -+#include "ginitable.h" -+#include "giomodule-priv.h" -+#include "glibintl.h" -+#include "glib/gstdio.h" -+#include "gcancellable.h" -+#include "gdbusproxy.h" -+#include "gdbusnamewatching.h" -+ -+#define G_POWER_PROFILE_MONITOR_DBUS_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) -+ -+static void g_power_profile_monitor_dbus_iface_init (GPowerProfileMonitorInterface *iface); -+static void g_power_profile_monitor_dbus_initable_iface_init (GInitableIface *iface); -+ -+struct _GPowerProfileMonitorDBus -+{ -+ GObject parent_instance; -+ -+ guint watch_id; -+ GCancellable *cancellable; -+ GDBusProxy *proxy; -+ gulong signal_id; -+ -+ gboolean power_saver_enabled; -+}; -+ -+typedef enum -+{ -+ PROP_POWER_SAVER_ENABLED = 1, -+} GPowerProfileMonitorDBusProperty; -+ -+#define POWERPROFILES_DBUS_NAME "net.hadess.PowerProfiles" -+#define POWERPROFILES_DBUS_IFACE "net.hadess.PowerProfiles" -+#define POWERPROFILES_DBUS_PATH "/net/hadess/PowerProfiles" -+ -+G_DEFINE_TYPE_WITH_CODE (GPowerProfileMonitorDBus, g_power_profile_monitor_dbus, G_TYPE_OBJECT, -+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, -+ g_power_profile_monitor_dbus_initable_iface_init) -+ G_IMPLEMENT_INTERFACE (G_TYPE_POWER_PROFILE_MONITOR, -+ g_power_profile_monitor_dbus_iface_init) -+ _g_io_modules_ensure_extension_points_registered (); -+ g_io_extension_point_implement (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME, -+ g_define_type_id, -+ "dbus", -+ 30)) -+ -+static void -+g_power_profile_monitor_dbus_init (GPowerProfileMonitorDBus *dbus) -+{ -+ dbus->power_saver_enabled = FALSE; -+} -+ -+static void -+ppd_properties_changed_cb (GDBusProxy *proxy, -+ GVariant *changed_properties, -+ GStrv *invalidated_properties, -+ gpointer user_data) -+{ -+ GPowerProfileMonitorDBus *dbus = user_data; -+ const char *active_profile; -+ gboolean enabled; -+ -+ if (!g_variant_lookup (changed_properties, "ActiveProfile", "&s", &active_profile)) -+ return; -+ -+ enabled = g_strcmp0 (active_profile, "power-saver") == 0; -+ if (enabled == dbus->power_saver_enabled) -+ return; -+ -+ dbus->power_saver_enabled = enabled; -+ g_object_notify (G_OBJECT (dbus), "power-saver-enabled"); -+} -+ -+static void -+ppd_proxy_cb (GObject *source_object, -+ GAsyncResult *res, -+ gpointer user_data) -+{ -+ GPowerProfileMonitorDBus *dbus = user_data; -+ GVariant *active_profile_variant; -+ GDBusProxy *proxy; -+ GError *error = NULL; -+ const char *active_profile; -+ gboolean power_saver_enabled; -+ -+ proxy = g_dbus_proxy_new_finish (res, &error); -+ if (!proxy) -+ { -+ g_debug ("GPowerProfileMonitorDBus: Failed to create PowerProfiles D-Bus proxy: %s", -+ error->message); -+ g_error_free (error); -+ return; -+ } -+ -+ active_profile_variant = g_dbus_proxy_get_cached_property (proxy, "ActiveProfile"); -+ if (g_variant_is_of_type (active_profile_variant, G_VARIANT_TYPE_STRING)) -+ { -+ active_profile = g_variant_get_string (active_profile_variant, NULL); -+ power_saver_enabled = g_strcmp0 (active_profile, "power-saver") == 0; -+ if (power_saver_enabled != dbus->power_saver_enabled) -+ { -+ dbus->power_saver_enabled = power_saver_enabled; -+ g_object_notify (G_OBJECT (dbus), "power-saver-enabled"); -+ } -+ } -+ -+ dbus->signal_id = g_signal_connect (G_OBJECT (proxy), "g-properties-changed", -+ G_CALLBACK (ppd_properties_changed_cb), dbus); -+ dbus->proxy = g_steal_pointer (&proxy); -+} -+ -+static void -+ppd_appeared_cb (GDBusConnection *connection, -+ const gchar *name, -+ const gchar *name_owner, -+ gpointer user_data) -+{ -+ GPowerProfileMonitorDBus *dbus = user_data; -+ -+ g_dbus_proxy_new (connection, -+ G_DBUS_PROXY_FLAGS_NONE, -+ NULL, -+ POWERPROFILES_DBUS_NAME, -+ POWERPROFILES_DBUS_PATH, -+ POWERPROFILES_DBUS_IFACE, -+ dbus->cancellable, -+ ppd_proxy_cb, -+ dbus); -+} -+ -+static void -+ppd_vanished_cb (GDBusConnection *connection, -+ const gchar *name, -+ gpointer user_data) -+{ -+ GPowerProfileMonitorDBus *dbus = user_data; -+ -+ g_clear_signal_handler (&dbus->signal_id, dbus->proxy); -+ g_clear_object (&dbus->proxy); -+ -+ dbus->power_saver_enabled = FALSE; -+ g_object_notify (G_OBJECT (dbus), "power-saver-enabled"); -+} -+ -+static void -+g_power_profile_monitor_dbus_get_property (GObject *object, -+ guint prop_id, -+ GValue *value, -+ GParamSpec *pspec) -+{ -+ GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (object); -+ -+ switch ((GPowerProfileMonitorDBusProperty) prop_id) -+ { -+ case PROP_POWER_SAVER_ENABLED: -+ g_value_set_boolean (value, dbus->power_saver_enabled); -+ break; -+ -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ } -+} -+ -+static gboolean -+g_power_profile_monitor_dbus_initable_init (GInitable *initable, -+ GCancellable *cancellable, -+ GError **error) -+{ -+ GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (initable); -+ -+ dbus->cancellable = g_cancellable_new (); -+ dbus->watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, -+ POWERPROFILES_DBUS_NAME, -+ G_BUS_NAME_WATCHER_FLAGS_AUTO_START, -+ ppd_appeared_cb, -+ ppd_vanished_cb, -+ dbus, -+ NULL); -+ -+ return TRUE; -+} -+ -+static void -+g_power_profile_monitor_dbus_finalize (GObject *object) -+{ -+ GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (object); -+ -+ g_cancellable_cancel (dbus->cancellable); -+ g_clear_object (&dbus->cancellable); -+ g_clear_signal_handler (&dbus->signal_id, dbus->proxy); -+ g_clear_object (&dbus->proxy); -+ g_clear_handle_id (&dbus->watch_id, g_bus_unwatch_name); -+ -+ G_OBJECT_CLASS (g_power_profile_monitor_dbus_parent_class)->finalize (object); -+} -+ -+static void -+g_power_profile_monitor_dbus_class_init (GPowerProfileMonitorDBusClass *nl_class) -+{ -+ GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); -+ -+ gobject_class->get_property = g_power_profile_monitor_dbus_get_property; -+ gobject_class->finalize = g_power_profile_monitor_dbus_finalize; -+ -+ g_object_class_override_property (gobject_class, PROP_POWER_SAVER_ENABLED, "power-saver-enabled"); -+} -+ -+static void -+g_power_profile_monitor_dbus_iface_init (GPowerProfileMonitorInterface *monitor_iface) -+{ -+} -+ -+static void -+g_power_profile_monitor_dbus_initable_iface_init (GInitableIface *iface) -+{ -+ iface->init = g_power_profile_monitor_dbus_initable_init; -+} -diff --git a/gio/gpowerprofilemonitordbus.h b/gio/gpowerprofilemonitordbus.h -new file mode 100644 -index 000000000..ecf7246d1 ---- /dev/null -+++ b/gio/gpowerprofilemonitordbus.h -@@ -0,0 +1,32 @@ -+/* GIO - GLib Input, Output and Streaming Library -+ * -+ * Copyright 2019 Red Hat, Inc. -+ * Copyright 2021 Igalia S.L. -+ * -+ * 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_POWER_PROFILE_MONITOR_DBUS_H__ -+#define __G_POWER_PROFILE_MONITOR_DBUS_H__ -+ -+#include -+ -+G_BEGIN_DECLS -+ -+#define G_TYPE_POWER_PROFILE_MONITOR_DBUS (g_power_profile_monitor_dbus_get_type ()) -+G_DECLARE_FINAL_TYPE (GPowerProfileMonitorDBus, g_power_profile_monitor_dbus, G, POWER_PROFILE_MONITOR_DBUS, GObject) -+ -+G_END_DECLS -+ -+#endif /* __G_POWER_PROFILE_MONITOR_DBUS_H__ */ -diff --git a/gio/meson.build b/gio/meson.build -index 49a37a7bd..d5838ed8a 100644 ---- a/gio/meson.build -+++ b/gio/meson.build -@@ -533,6 +533,8 @@ gio_sources = files( - 'gpollableoutputstream.c', - 'gpollableutils.c', - 'gpollfilemonitor.c', -+ 'gpowerprofilemonitor.c', -+ 'gpowerprofilemonitordbus.c', - 'gproxy.c', - 'gproxyaddress.c', - 'gproxyaddressenumerator.c', -@@ -673,6 +675,7 @@ gio_headers = files( - 'gpollableinputstream.h', - 'gpollableoutputstream.h', - 'gpollableutils.h', -+ 'gpowerprofilemonitor.h', - 'gproxy.h', - 'gproxyaddress.h', - 'gproxyaddressenumerator.h', -diff --git a/gio/tests/meson.build b/gio/tests/meson.build -index 98d1401d0..fc2055101 100644 ---- a/gio/tests/meson.build -+++ b/gio/tests/meson.build -@@ -75,6 +75,7 @@ gio_tests = { - 'network-monitor-race' : {}, - 'permission' : {}, - 'pollable' : {'dependencies' : [libdl_dep]}, -+ 'power-profile-monitor' : {}, - 'proxy-test' : {}, - 'readwrite' : {}, - 'simple-async-result' : {}, -diff --git a/gio/tests/power-profile-monitor.c b/gio/tests/power-profile-monitor.c -new file mode 100644 -index 000000000..bb32f181f ---- /dev/null -+++ b/gio/tests/power-profile-monitor.c -@@ -0,0 +1,79 @@ -+/* GIO - GLib Input, Output and Streaming Library -+ * -+ * Copyright 2021 Igalia S.L. -+ * -+ * 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 -+ -+static void -+test_dup_default (void) -+{ -+ GPowerProfileMonitor *monitor; -+ -+ monitor = g_power_profile_monitor_dup_default (); -+ g_assert_nonnull (monitor); -+ g_object_unref (monitor); -+} -+ -+static void -+power_saver_enabled_cb (GPowerProfileMonitor *monitor, -+ GParamSpec *pspec, -+ gpointer user_data) -+{ -+ gboolean enabled; -+ -+ enabled = g_power_profile_monitor_get_power_saver_enabled (monitor); -+ g_debug ("Power Saver %s (%d)", enabled ? "enabled" : "disabled", enabled); -+} -+ -+static void -+do_watch_power_profile (void) -+{ -+ GPowerProfileMonitor *monitor; -+ GMainLoop *loop; -+ gulong signal_id; -+ -+ monitor = g_power_profile_monitor_dup_default (); -+ signal_id = g_signal_connect (G_OBJECT (monitor), "notify::power-saver-enabled", -+ G_CALLBACK (power_saver_enabled_cb), NULL); -+ -+ loop = g_main_loop_new (NULL, TRUE); -+ g_main_loop_run (loop); -+ -+ g_signal_handler_disconnect (monitor, signal_id); -+ g_object_unref (monitor); -+ g_main_loop_unref (loop); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int ret; -+ -+ if (argc == 2 && !strcmp (argv[1], "--watch")) -+ { -+ do_watch_power_profile (); -+ return 0; -+ } -+ -+ g_test_init (&argc, &argv, NULL); -+ -+ g_test_add_func ("/power-profile-monitor/default", test_dup_default); -+ -+ ret = g_test_run (); -+ -+ return ret; -+} --- -GitLab - diff --git a/base/rx-glib2/2222.patch b/base/rx-glib2/2222.patch deleted file mode 100644 index 0b6106f..0000000 --- a/base/rx-glib2/2222.patch +++ /dev/null @@ -1,739 +0,0 @@ -From 9645cbffa8ba1a08b73fdae50b31125d11aa5684 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Mon, 9 Aug 2021 23:19:17 +0200 -Subject: [PATCH 1/4] gio: Add portal version of GPowerProfileMonitor - ---- - docs/reference/gio/meson.build | 1 + - gio/giomodule.c | 2 + - gio/gpowerprofilemonitorportal.c | 182 +++++++++++++++++++++++++++++++ - gio/gpowerprofilemonitorportal.h | 31 ++++++ - gio/meson.build | 1 + - 5 files changed, 217 insertions(+) - create mode 100644 gio/gpowerprofilemonitorportal.c - create mode 100644 gio/gpowerprofilemonitorportal.h - -diff --git a/docs/reference/gio/meson.build b/docs/reference/gio/meson.build -index fbabd25ca..9aaafeed5 100644 ---- a/docs/reference/gio/meson.build -+++ b/docs/reference/gio/meson.build -@@ -66,6 +66,7 @@ if get_option('gtk_doc') - 'gpollfilemonitor.h', - 'gportalsupport.h', - 'gpowerprofilemonitordbus.h', -+ 'gpowerprofilemonitorportal.h', - 'gproxyresolverportal.h', - 'gregistrysettingsbackend.h', - 'gresourcefile.h', -diff --git a/gio/giomodule.c b/gio/giomodule.c -index dfd895717..d34037a45 100644 ---- a/gio/giomodule.c -+++ b/gio/giomodule.c -@@ -50,6 +50,7 @@ - #include "gmemorymonitordbus.h" - #include "gpowerprofilemonitor.h" - #include "gpowerprofilemonitordbus.h" -+#include "gpowerprofilemonitorportal.h" - #ifdef G_OS_WIN32 - #include "gregistrysettingsbackend.h" - #include "giowin32-priv.h" -@@ -1305,6 +1306,7 @@ _g_io_modules_ensure_loaded (void) - g_type_ensure (g_memory_monitor_dbus_get_type ()); - g_type_ensure (g_memory_monitor_portal_get_type ()); - g_type_ensure (g_network_monitor_portal_get_type ()); -+ g_type_ensure (g_power_profile_monitor_portal_get_type ()); - g_type_ensure (g_proxy_resolver_portal_get_type ()); - #endif - #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 -diff --git a/gio/gpowerprofilemonitorportal.c b/gio/gpowerprofilemonitorportal.c -new file mode 100644 -index 000000000..bb1b4fd15 ---- /dev/null -+++ b/gio/gpowerprofilemonitorportal.c -@@ -0,0 +1,182 @@ -+/* GIO - GLib Input, Output and Streaming Library -+ * -+ * Copyright 2021 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 "gpowerprofilemonitor.h" -+#include "gpowerprofilemonitorportal.h" -+#include "gdbuserror.h" -+#include "gdbusproxy.h" -+#include "ginitable.h" -+#include "gioerror.h" -+#include "giomodule-priv.h" -+#include "gportalsupport.h" -+ -+#define G_POWER_PROFILE_MONITOR_PORTAL_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) -+ -+static void g_power_profile_monitor_portal_iface_init (GPowerProfileMonitorInterface *iface); -+static void g_power_profile_monitor_portal_initable_iface_init (GInitableIface *iface); -+ -+typedef enum -+{ -+ PROP_POWER_SAVER_ENABLED = 1, -+} GPowerProfileMonitorPortalProperty; -+ -+struct _GPowerProfileMonitorPortal -+{ -+ GObject parent_instance; -+ -+ GDBusProxy *proxy; -+ gulong signal_id; -+ gboolean power_saver_enabled; -+}; -+ -+G_DEFINE_TYPE_WITH_CODE (GPowerProfileMonitorPortal, g_power_profile_monitor_portal, G_TYPE_OBJECT, -+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, -+ g_power_profile_monitor_portal_initable_iface_init) -+ G_IMPLEMENT_INTERFACE (G_TYPE_POWER_PROFILE_MONITOR, -+ g_power_profile_monitor_portal_iface_init) -+ _g_io_modules_ensure_extension_points_registered (); -+ g_io_extension_point_implement (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME, -+ g_define_type_id, -+ "portal", -+ 40)) -+ -+static void -+g_power_profile_monitor_portal_init (GPowerProfileMonitorPortal *portal) -+{ -+} -+ -+static void -+proxy_properties_changed (GDBusProxy *proxy, -+ GVariant *changed_properties, -+ GStrv invalidated_properties, -+ gpointer user_data) -+{ -+ GPowerProfileMonitorPortal *ppm = user_data; -+ gboolean power_saver_enabled; -+ -+ if (!g_variant_lookup (changed_properties, "power-saver-enabled", "b", &power_saver_enabled)) -+ return; -+ -+ if (power_saver_enabled == ppm->power_saver_enabled) -+ return; -+ -+ ppm->power_saver_enabled = power_saver_enabled; -+ g_object_notify (G_OBJECT (ppm), "power-saver-enabled"); -+} -+ -+static void -+g_power_profile_monitor_portal_get_property (GObject *object, -+ guint prop_id, -+ GValue *value, -+ GParamSpec *pspec) -+{ -+ GPowerProfileMonitorPortal *ppm = G_POWER_PROFILE_MONITOR_PORTAL (object); -+ -+ switch ((GPowerProfileMonitorPortalProperty) prop_id) -+ { -+ case PROP_POWER_SAVER_ENABLED: -+ g_value_set_boolean (value, ppm->power_saver_enabled); -+ break; -+ -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ } -+} -+ -+static gboolean -+g_power_profile_monitor_portal_initable_init (GInitable *initable, -+ GCancellable *cancellable, -+ GError **error) -+{ -+ GPowerProfileMonitorPortal *ppm = G_POWER_PROFILE_MONITOR_PORTAL (initable); -+ GDBusProxy *proxy; -+ gchar *name_owner; -+ -+ if (!glib_should_use_portal ()) -+ { -+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not using portals"); -+ return FALSE; -+ } -+ -+ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, -+ G_DBUS_PROXY_FLAGS_NONE, -+ NULL, -+ "org.freedesktop.portal.Desktop", -+ "/org/freedesktop/portal/desktop", -+ "org.freedesktop.portal.PowerProfileMonitor", -+ cancellable, -+ error); -+ if (!proxy) -+ return FALSE; -+ -+ name_owner = g_dbus_proxy_get_name_owner (proxy); -+ -+ if (name_owner == NULL) -+ { -+ g_object_unref (proxy); -+ g_set_error (error, -+ G_DBUS_ERROR, -+ G_DBUS_ERROR_NAME_HAS_NO_OWNER, -+ "Desktop portal not found"); -+ return FALSE; -+ } -+ -+ g_free (name_owner); -+ -+ ppm->signal_id = g_signal_connect (proxy, "g-properties-changed", -+ G_CALLBACK (proxy_properties_changed), ppm); -+ -+ ppm->proxy = g_steal_pointer (&proxy); -+ -+ return TRUE; -+} -+ -+static void -+g_power_profile_monitor_portal_finalize (GObject *object) -+{ -+ GPowerProfileMonitorPortal *ppm = G_POWER_PROFILE_MONITOR_PORTAL (object); -+ -+ g_clear_signal_handler (&ppm->signal_id, ppm->proxy); -+ g_clear_object (&ppm->proxy); -+ -+ G_OBJECT_CLASS (g_power_profile_monitor_portal_parent_class)->finalize (object); -+} -+ -+static void -+g_power_profile_monitor_portal_class_init (GPowerProfileMonitorPortalClass *nl_class) -+{ -+ GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); -+ -+ gobject_class->get_property = g_power_profile_monitor_portal_get_property; -+ gobject_class->finalize = g_power_profile_monitor_portal_finalize; -+ -+ g_object_class_override_property (gobject_class, PROP_POWER_SAVER_ENABLED, "power-saver-enabled"); -+} -+ -+static void -+g_power_profile_monitor_portal_iface_init (GPowerProfileMonitorInterface *monitor_iface) -+{ -+} -+ -+static void -+g_power_profile_monitor_portal_initable_iface_init (GInitableIface *iface) -+{ -+ iface->init = g_power_profile_monitor_portal_initable_init; -+} -diff --git a/gio/gpowerprofilemonitorportal.h b/gio/gpowerprofilemonitorportal.h -new file mode 100644 -index 000000000..b91a14610 ---- /dev/null -+++ b/gio/gpowerprofilemonitorportal.h -@@ -0,0 +1,31 @@ -+/* GIO - GLib Input, Output and Streaming Library -+ * -+ * Copyright 2021 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 . -+ */ -+ -+#ifndef __G_POWER_PROFILE_MONITOR_PORTAL_H__ -+#define __G_POWER_PROFILE_MONITOR_PORTAL_H__ -+ -+#include -+ -+G_BEGIN_DECLS -+ -+#define G_TYPE_POWER_PROFILE_MONITOR_PORTAL (g_power_profile_monitor_portal_get_type ()) -+G_DECLARE_FINAL_TYPE (GPowerProfileMonitorPortal, g_power_profile_monitor_portal, G, POWER_PROFILE_MONITOR_PORTAL, GObject) -+ -+G_END_DECLS -+ -+#endif /* __G_POWER_PROFILE_MONITOR_PORTAL_H__ */ -diff --git a/gio/meson.build b/gio/meson.build -index d5838ed8a..ac3373f2b 100644 ---- a/gio/meson.build -+++ b/gio/meson.build -@@ -383,6 +383,7 @@ if host_system != 'windows' - 'gopenuriportal.c', - 'gmemorymonitorportal.c', - 'gnetworkmonitorportal.c', -+ 'gpowerprofilemonitorportal.c', - 'gproxyresolverportal.c', - 'gtrashportal.c', - 'gportalsupport.c', --- -GitLab - - -From 18eb29897d80bf662d58bd11a89617ddd7ebfeed Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Tue, 10 Aug 2021 10:58:53 +0200 -Subject: [PATCH 2/4] gio: Add GPowerProfileMonitor tests - -Tests both the portal and direct D-Bus variants. ---- - gio/tests/meson.build | 14 ++- - gio/tests/power-profile-monitor-dbus.py.in | 107 ++++++++++++++++ - gio/tests/power-profile-monitor-portal.py.in | 126 +++++++++++++++++++ - 3 files changed, 241 insertions(+), 6 deletions(-) - create mode 100755 gio/tests/power-profile-monitor-dbus.py.in - create mode 100755 gio/tests/power-profile-monitor-portal.py.in - -diff --git a/gio/tests/meson.build b/gio/tests/meson.build -index fc2055101..5dbfb8e60 100644 ---- a/gio/tests/meson.build -+++ b/gio/tests/meson.build -@@ -541,27 +541,29 @@ if installed_tests_enabled - install_subdir('static-link', install_dir : installed_tests_execdir) - install_data('static-link.py', install_dir : installed_tests_execdir) - -- memory_monitor_tests = [ -+ monitor_tests = [ - 'memory-monitor-dbus', - 'memory-monitor-portal', -+ 'power-profile-monitor-dbus', -+ 'power-profile-monitor-portal' - ] - -- foreach memory_monitor_test : memory_monitor_tests -+ foreach monitor_test : monitor_tests - cdata = configuration_data() - cdata.set('installed_tests_dir', installed_tests_execdir) -- cdata.set('program', memory_monitor_test + '.py') -+ cdata.set('program', monitor_test + '.py') - cdata.set('env', '') - configure_file( - input: installed_tests_template_tap, -- output: memory_monitor_test + '.test', -+ output: monitor_test + '.test', - install_dir: installed_tests_metadir, - configuration: cdata - ) - cdata = configuration_data() - cdata.set('libexecdir', join_paths(glib_prefix, get_option('libexecdir'))) - configure_file( -- input: memory_monitor_test + '.py.in', -- output: memory_monitor_test + '.py', -+ input: monitor_test + '.py.in', -+ output: monitor_test + '.py', - install_dir : installed_tests_execdir, - configuration: cdata, - ) -diff --git a/gio/tests/power-profile-monitor-dbus.py.in b/gio/tests/power-profile-monitor-dbus.py.in -new file mode 100755 -index 000000000..06e594f4a ---- /dev/null -+++ b/gio/tests/power-profile-monitor-dbus.py.in -@@ -0,0 +1,107 @@ -+#!/usr/bin/python3 -+ -+# This program 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 3 of the License, or (at your option) any -+# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -+# of the license. -+ -+__author__ = 'Bastien Nocera' -+__email__ = 'hadess@hadess.net' -+__copyright__ = '(c) 2019, 2021 Red Hat Inc.' -+__license__ = 'LGPL 3+' -+ -+import unittest -+import sys -+import subprocess -+import fcntl -+import os -+import time -+ -+import taptestrunner -+ -+try: -+ # Do all non-standard imports here so we can skip the tests if any -+ # needed packages are not available. -+ import dbus -+ import dbus.mainloop.glib -+ import dbusmock -+ from gi.repository import GLib -+ from gi.repository import Gio -+ -+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) -+ -+ class TestPowerProfileMonitor(dbusmock.DBusTestCase): -+ '''Test GPowerProfileMonitorDBus''' -+ -+ @classmethod -+ def setUpClass(klass): -+ klass.start_system_bus() -+ klass.dbus_con = klass.get_dbus(True) -+ -+ def setUp(self): -+ try: -+ Gio.PowerProfileMonitor -+ except AttributeError: -+ raise unittest.SkipTest('Power Profile Monitor not in ' -+ 'introspection data. Requires ' -+ 'GObject-Introspection ≥ 1.63.2') # FIXME version -+ try: -+ (self.p_mock, self.obj_ppd) = self.spawn_server_template( -+ 'power_profiles_daemon', {}, stdout=subprocess.PIPE) -+ except ModuleNotFoundError: -+ raise unittest.SkipTest("power-profiles-daemon dbusmock template not " -+ "found. Requires dbusmock > 0.23.1.") # FIXME version -+ # set log to nonblocking -+ flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) -+ fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) -+ self.power_saver_enabled = False -+ self.dbus_props = dbus.Interface(self.obj_ppd, dbus.PROPERTIES_IFACE) -+ self.power_profile_monitor = Gio.PowerProfileMonitor.dup_default() -+ self.power_profile_monitor.connect("notify::power-saver-enabled", self.power_saver_enabled_cb) -+ self.mainloop = GLib.MainLoop() -+ self.main_context = self.mainloop.get_context() -+ -+ def tearDown(self): -+ self.p_mock.terminate() -+ self.p_mock.wait() -+ -+ def assertEventually(self, condition, message=None, timeout=50): -+ '''Assert that condition function eventually returns True. -+ -+ Timeout is in deciseconds, defaulting to 50 (5 seconds). message is -+ printed on failure. -+ ''' -+ while timeout >= 0: -+ context = GLib.MainContext.default() -+ while context.iteration(False): -+ pass -+ if condition(): -+ break -+ timeout -= 1 -+ time.sleep(0.1) -+ else: -+ self.fail(message or 'timed out waiting for ' + str(condition)) -+ -+ def power_saver_enabled_cb(self, spec, data): -+ self.power_saver_enabled = self.power_profile_monitor.get_power_saver_enabled() -+ self.main_context.wakeup() -+ -+ def test_power_profile_power_saver_enabled(self): -+ '''power-saver-enabled property''' -+ -+ self.assertEqual(self.power_profile_monitor.get_power_saver_enabled(), False) -+ self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('power-saver', variant_level=1)) -+ self.assertEventually(lambda: self.power_saver_enabled == True, "power-saver didn't become enabled", 10) -+ -+ self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('balanced', variant_level=1)) -+ self.assertEventually(lambda: self.power_saver_enabled == False, "power-saver didn't become disabled", 10) -+ -+except ImportError as e: -+ @unittest.skip("Cannot import %s" % e.name) -+ class TestPowerProfileMonitor(unittest.TestCase): -+ def test_power_profile_power_saver_enabled(self): -+ pass -+ -+if __name__ == '__main__': -+ unittest.main(testRunner=taptestrunner.TAPTestRunner()) -diff --git a/gio/tests/power-profile-monitor-portal.py.in b/gio/tests/power-profile-monitor-portal.py.in -new file mode 100755 -index 000000000..960a62232 ---- /dev/null -+++ b/gio/tests/power-profile-monitor-portal.py.in -@@ -0,0 +1,126 @@ -+#!/usr/bin/python3 -+ -+# This program 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 3 of the License, or (at your option) any -+# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -+# of the license. -+ -+__author__ = 'Bastien Nocera' -+__email__ = 'hadess@hadess.net' -+__copyright__ = '(c) 2021 Red Hat Inc.' -+__license__ = 'LGPL 3+' -+ -+import unittest -+import sys -+import subprocess -+import fcntl -+import os -+import time -+ -+import taptestrunner -+ -+try: -+ # Do all non-standard imports here so we can skip the tests if any -+ # needed packages are not available. -+ import dbus -+ import dbus.mainloop.glib -+ import dbusmock -+ from gi.repository import GLib -+ from gi.repository import Gio -+ -+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) -+ -+ # XDG_DESKTOP_PORTAL_PATH = os.path.expanduser("~/.cache/jhbuild/build/xdg-desktop-portal/xdg-desktop-portal") -+ XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal" -+ -+ class TestPowerProfileMonitorPortal(dbusmock.DBusTestCase): -+ '''Test GPowerProfileMonitorPortal''' -+ -+ @classmethod -+ def setUpClass(klass): -+ klass.start_system_bus() -+ klass.dbus_con = klass.get_dbus(True) -+ # Start session bus so that xdg-desktop-portal can run on it -+ klass.start_session_bus() -+ -+ def setUp(self): -+ try: -+ Gio.PowerProfileMonitor -+ except AttributeError: -+ raise unittest.SkipTest('Power Profile Monitor not in ' -+ 'introspection data. Requires ' -+ 'GObject-Introspection > 1.69.0') -+ try: -+ (self.p_mock, self.obj_ppd) = self.spawn_server_template( -+ 'power_profiles_daemon', {}, stdout=subprocess.PIPE) -+ except ModuleNotFoundError: -+ raise unittest.SkipTest("power-profiles-daemon dbusmock template not " -+ "found. Requires dbusmock > 0.23.1.") -+ # set log to nonblocking -+ flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) -+ fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) -+ self.power_saver_enabled = False -+ self.dbus_props = dbus.Interface(self.obj_ppd, dbus.PROPERTIES_IFACE) -+ try: -+ self.xdp = subprocess.Popen([XDG_DESKTOP_PORTAL_PATH]) -+ except FileNotFoundError: -+ raise unittest.SkipTest("xdg-desktop-portal not available") -+ -+ try: -+ self.wait_for_bus_object('org.freedesktop.portal.Desktop', -+ '/org/freedesktop/portal/desktop') -+ except: -+ raise -+ # subprocess.Popen(['gdbus', 'monitor', '--session', '--dest', 'org.freedesktop.portal.Desktop']) -+ -+ os.environ['GTK_USE_PORTAL'] = "1" -+ self.power_profile_monitor = Gio.PowerProfileMonitor.dup_default() -+ assert("GPowerProfileMonitorPortal" in str(self.power_profile_monitor)) -+ self.power_profile_monitor.connect("notify::power-saver-enabled", self.power_saver_enabled_cb) -+ self.mainloop = GLib.MainLoop() -+ self.main_context = self.mainloop.get_context() -+ -+ def tearDown(self): -+ self.p_mock.terminate() -+ self.p_mock.wait() -+ -+ def assertEventually(self, condition, message=None, timeout=50): -+ '''Assert that condition function eventually returns True. -+ -+ Timeout is in deciseconds, defaulting to 50 (5 seconds). message is -+ printed on failure. -+ ''' -+ while timeout >= 0: -+ context = GLib.MainContext.default() -+ while context.iteration(False): -+ pass -+ if condition(): -+ break -+ timeout -= 1 -+ time.sleep(0.1) -+ else: -+ self.fail(message or 'timed out waiting for ' + str(condition)) -+ -+ def power_saver_enabled_cb(self, spec, data): -+ self.power_saver_enabled = self.power_profile_monitor.get_power_saver_enabled() -+ self.main_context.wakeup() -+ -+ def test_power_profile_power_saver_enabled_portal(self): -+ '''power-saver-enabled property''' -+ -+ self.assertEqual(self.power_profile_monitor.get_power_saver_enabled(), False) -+ self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('power-saver', variant_level=1)) -+ self.assertEventually(lambda: self.power_saver_enabled == True, "power-saver didn't become enabled", 10) -+ -+ self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('balanced', variant_level=1)) -+ self.assertEventually(lambda: self.power_saver_enabled == False, "power-saver didn't become disabled", 10) -+ -+except ImportError as e: -+ @unittest.skip("Cannot import %s" % e.name) -+ class TestPowerProfileMonitorPortal(unittest.TestCase): -+ def test_power_profile_power_saver_enabled_portal(self): -+ pass -+ -+if __name__ == '__main__': -+ unittest.main(testRunner=taptestrunner.TAPTestRunner()) --- -GitLab - - -From 66acea8418eb3d8e46bb6f93dc0c3f13a1f7822b Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Wed, 11 Aug 2021 15:37:40 +0200 -Subject: [PATCH 3/4] gio: Remove left-over debug statement from memory monitor - portal test - ---- - gio/tests/memory-monitor-portal.py.in | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/gio/tests/memory-monitor-portal.py.in b/gio/tests/memory-monitor-portal.py.in -index cb4a960eb..f5fd2283f 100755 ---- a/gio/tests/memory-monitor-portal.py.in -+++ b/gio/tests/memory-monitor-portal.py.in -@@ -31,7 +31,6 @@ try: - - dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - -- # XDG_DESKTOP_PORTAL_PATH = os.path.expanduser("~/.cache/jhbuild/build/xdg-desktop-portal/xdg-desktop-portal") - XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal" - - class TestLowMemoryMonitorPortal(dbusmock.DBusTestCase): --- -GitLab - - -From 2e9842cafc73a7fb94cfde7937e125e1a91f35f8 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Wed, 11 Aug 2021 15:38:12 +0200 -Subject: [PATCH 4/4] gio: Simplify memory monitor tests by using - assertEventually() helper - -assertEventually is a helper used in a number of projects that use -dbusmock. - -See https://github.com/martinpitt/python-dbusmock/issues/82 ---- - gio/tests/memory-monitor-dbus.py.in | 31 ++++++++++++++++----------- - gio/tests/memory-monitor-portal.py.in | 31 ++++++++++++++++----------- - 2 files changed, 38 insertions(+), 24 deletions(-) - -diff --git a/gio/tests/memory-monitor-dbus.py.in b/gio/tests/memory-monitor-dbus.py.in -index 7823e7309..e8ac28faf 100755 ---- a/gio/tests/memory-monitor-dbus.py.in -+++ b/gio/tests/memory-monitor-dbus.py.in -@@ -66,6 +66,23 @@ try: - self.p_mock.terminate() - self.p_mock.wait() - -+ def assertEventually(self, condition, message=None, timeout=50): -+ '''Assert that condition function eventually returns True. -+ -+ Timeout is in deciseconds, defaulting to 50 (5 seconds). message is -+ printed on failure. -+ ''' -+ while timeout >= 0: -+ context = GLib.MainContext.default() -+ while context.iteration(False): -+ pass -+ if condition(): -+ break -+ timeout -= 1 -+ time.sleep(0.1) -+ else: -+ self.fail(message or 'timed out waiting for ' + str(condition)) -+ - def memory_warning_cb(self, monitor, level): - self.last_warning = level - self.main_context.wakeup() -@@ -82,21 +99,11 @@ try: - - self.dbusmock.EmitWarning(100) - # Wait 2 seconds or until warning -- timeout = 2 -- while timeout > 0 and self.last_warning != 100: -- time.sleep(0.5) -- timeout -= 0.5 -- self.main_context.iteration(False) -- self.assertEqual(self.last_warning, 100) -+ self.assertEventually(self.last_warning == 100, "'100' low-memory warning not received", 20) - - self.dbusmock.EmitWarning(255) - # Wait 2 seconds or until warning -- timeout = 2 -- while timeout > 0 and self.last_warning != 255: -- time.sleep(0.5) -- timeout -= 0.5 -- self.main_context.iteration(False) -- self.assertEqual(self.last_warning, 255) -+ self.assertEventually(self.last_warning == 255, "'255' low-memory warning not received", 20) - - except ImportError as e: - @unittest.skip("Cannot import %s" % e.name) -diff --git a/gio/tests/memory-monitor-portal.py.in b/gio/tests/memory-monitor-portal.py.in -index f5fd2283f..36d5094d3 100755 ---- a/gio/tests/memory-monitor-portal.py.in -+++ b/gio/tests/memory-monitor-portal.py.in -@@ -84,6 +84,23 @@ try: - self.p_mock.terminate() - self.p_mock.wait() - -+ def assertEventually(self, condition, message=None, timeout=50): -+ '''Assert that condition function eventually returns True. -+ -+ Timeout is in deciseconds, defaulting to 50 (5 seconds). message is -+ printed on failure. -+ ''' -+ while timeout >= 0: -+ context = GLib.MainContext.default() -+ while context.iteration(False): -+ pass -+ if condition(): -+ break -+ timeout -= 1 -+ time.sleep(0.1) -+ else: -+ self.fail(message or 'timed out waiting for ' + str(condition)) -+ - def portal_memory_warning_cb(self, monitor, level): - self.last_warning = level - self.main_context.wakeup() -@@ -100,21 +117,11 @@ try: - - self.dbusmock.EmitWarning(100) - # Wait 2 seconds or until warning -- timeout = 2 -- while timeout > 0 and self.last_warning != 100: -- time.sleep(0.5) -- timeout -= 0.5 -- self.main_context.iteration(False) -- self.assertEqual(self.last_warning, 100) -+ self.assertEventually(self.last_warning == 100, "'100' low-memory warning not received", 20) - - self.dbusmock.EmitWarning(255) - # Wait 2 seconds or until warning -- timeout = 2 -- while timeout > 0 and self.last_warning != 255: -- time.sleep(0.5) -- timeout -= 0.5 -- self.main_context.iteration(False) -- self.assertEqual(self.last_warning, 255) -+ self.assertEventually(self.last_warning == 255, "'255' low-memory warning not received", 20) - - except ImportError as e: - @unittest.skip("Cannot import %s" % e.name) --- -GitLab - diff --git a/base/rx-glib2/2244.patch b/base/rx-glib2/2244.patch deleted file mode 100644 index cb55031..0000000 --- a/base/rx-glib2/2244.patch +++ /dev/null @@ -1,49 +0,0 @@ -From b6036e23b0477be147211b4e21a6b49cd4d6c9a0 Mon Sep 17 00:00:00 2001 -From: Jamie Bainbridge -Date: Wed, 8 Sep 2021 12:08:17 +1000 -Subject: [PATCH] gutils: Avoid segfault in g_get_user_database_entry - -g_get_user_database_entry() uses variable pwd to store the contents of -the call to getpwnam_r(), then capitalises the first letter of pw_name -with g_ascii_toupper (pw->pw_name[0]). - -However, as per the getpwnam manpage, the result of that call "may point -to a static area". When this happens, GLib is trying to edit static -memory which belongs to a shared library, so segfaults. - -Instead, copy pw_name off to a temporary variable, set uppercase on -that variable, and use the variable to join into the desired string. -Free the new variable after it is no longer needed. - -Signed-off-by: Jamie Bainbridge ---- - glib/gutils.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/glib/gutils.c b/glib/gutils.c -index b7a2113d4..4bccd7229 100644 ---- a/glib/gutils.c -+++ b/glib/gutils.c -@@ -692,14 +692,17 @@ g_get_user_database_entry (void) - { - gchar **gecos_fields; - gchar **name_parts; -+ gchar *uppercase_pw_name; - - /* split the gecos field and substitute '&' */ - gecos_fields = g_strsplit (pw->pw_gecos, ",", 0); - name_parts = g_strsplit (gecos_fields[0], "&", 0); -- pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]); -- e.real_name = g_strjoinv (pw->pw_name, name_parts); -+ uppercase_pw_name = g_strdup (pw->pw_name); -+ uppercase_pw_name[0] = g_ascii_toupper (uppercase_pw_name[0]); -+ e.real_name = g_strjoinv (uppercase_pw_name, name_parts); - g_strfreev (gecos_fields); - g_strfreev (name_parts); -+ g_free (uppercase_pw_name); - } - #endif - --- -GitLab - diff --git a/base/rx-glib2/2291.patch b/base/rx-glib2/2291.patch deleted file mode 100644 index 2e4e44d..0000000 --- a/base/rx-glib2/2291.patch +++ /dev/null @@ -1,129 +0,0 @@ -From f419966808475cb6c0f0ba2f63967876218ffdaf Mon Sep 17 00:00:00 2001 -From: Julian Andres Klode -Date: Tue, 12 Oct 2021 12:01:50 +0200 -Subject: [PATCH 1/2] gnetworkmonitornm: Stop using removed PropertiesChanged - signal - -Use the org.freedesktop.DBus.Properties interface to listen -to PropertiesChanged signals on /org/freedesktop/NetworkManager. - -NetworkManager used to provide its own legacy PropertiesChanged -signal, but that was dropped in -https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/853 - -This requires NetworkManager >= 1.2 (2016) - -Fixes: #2505 -Bug-Ubuntu: https://bugs.launchpad.net/bugs/1946196 ---- - gio/gnetworkmonitornm.c | 29 +++++++---------------------- - 1 file changed, 7 insertions(+), 22 deletions(-) - -diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c -index 5a36a0ba1..6a6d1d666 100644 ---- a/gio/gnetworkmonitornm.c -+++ b/gio/gnetworkmonitornm.c -@@ -267,29 +267,14 @@ update_cached_property (GDBusProxy *proxy, - } - - static void --proxy_signal_cb (GDBusProxy *proxy, -- const gchar *sender_name, -- const gchar *signal_name, -- GVariant *parameters, -- GNetworkMonitorNM *nm) -+proxy_properties_changed_cb (GDBusProxy *proxy, -+ GVariant *changed_properties, -+ GStrv invalidated_properties, -+ GNetworkMonitorNM *nm) - { -- GVariant *asv; - GVariantDict *dict; - -- if (g_strcmp0 (signal_name, "PropertiesChanged") != 0) -- return; -- -- g_variant_get (parameters, "(@a{sv})", &asv); -- if (!asv) -- return; -- -- dict = g_variant_dict_new (asv); -- g_variant_unref (asv); -- if (!dict) -- { -- g_warning ("Failed to handle PropertiesChanged signal from NetworkManager"); -- return; -- } -+ dict = g_variant_dict_new (changed_properties); - - update_cached_property (nm->priv->proxy, "Connectivity", dict); - -@@ -361,8 +346,8 @@ g_network_monitor_nm_initable_init (GInitable *initable, - return FALSE; - } - -- nm->priv->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal", -- G_CALLBACK (proxy_signal_cb), nm); -+ nm->priv->signal_id = g_signal_connect (G_OBJECT (proxy), "g-properties-changed", -+ G_CALLBACK (proxy_properties_changed_cb), nm); - nm->priv->proxy = proxy; - sync_properties (nm, FALSE); - --- -GitLab - - -From 643fc7ea49e818310f6b3f6e4ebe621c7a4d6bd7 Mon Sep 17 00:00:00 2001 -From: Julian Andres Klode -Date: Tue, 12 Oct 2021 17:31:42 +0200 -Subject: [PATCH 2/2] gnetworkmonitornm: Do not re-update cached property - -GDBusProxy already takes care of updating the cached property -before emitting the signal, so there is no need to do this -a second time ourselves. ---- - gio/gnetworkmonitornm.c | 22 ---------------------- - 1 file changed, 22 deletions(-) - -diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c -index 6a6d1d666..a8040fb36 100644 ---- a/gio/gnetworkmonitornm.c -+++ b/gio/gnetworkmonitornm.c -@@ -252,34 +252,12 @@ sync_properties (GNetworkMonitorNM *nm, - } - } - --static void --update_cached_property (GDBusProxy *proxy, -- const char *property_name, -- GVariantDict *dict) --{ -- GVariant *v; -- -- v = g_variant_dict_lookup_value (dict, property_name, NULL); -- if (!v) -- return; -- g_dbus_proxy_set_cached_property (proxy, property_name, v); -- g_variant_unref (v); --} -- - static void - proxy_properties_changed_cb (GDBusProxy *proxy, - GVariant *changed_properties, - GStrv invalidated_properties, - GNetworkMonitorNM *nm) - { -- GVariantDict *dict; -- -- dict = g_variant_dict_new (changed_properties); -- -- update_cached_property (nm->priv->proxy, "Connectivity", dict); -- -- g_variant_dict_unref (dict); -- - sync_properties (nm, TRUE); - } - --- -GitLab - diff --git a/base/rx-glib2/2408.patch b/base/rx-glib2/2408.patch deleted file mode 100644 index 90d8953..0000000 --- a/base/rx-glib2/2408.patch +++ /dev/null @@ -1,391 +0,0 @@ -From 0bbd63bf1945c6f3e1c88232521e1618c21d44f2 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 23 Dec 2021 17:45:51 +0000 -Subject: [PATCH 1/4] gmain: Use waitid() on pidfds rather than a global - SIGCHLD handler -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When the system supports it (as all Linux kernels ≥ 5.3 should), it’s -preferable to use `pidfd_open()` and `waitid()` to be notified of -child processes exiting or being signalled, rather than installing a -default `SIGCHLD` handler. - -A default `SIGCHLD` handler is global, and can never interact well with -other code (from the application or other libraries) which also wants to -install a `SIGCHLD` handler. - -This use of `pidfd_open()` is racy (the PID may be reused between -`g_child_watch_source_new()` being called and `pidfd_open()` being -called), so it doesn’t improve behaviour there. For that, we’d need -continuous use of pidfds throughout GLib, from fork/spawn time until -here. See #1866 for that. - -The use of `waitid()` to get the process exit status could be expanded -in future to also work for stopped or continued processes (as per #175) -by adding `WSTOPPED | WCONTINUED` into the flags. That’s a behaviour -change which is outside the strict scope of adding pidfd support, -though. - -Signed-off-by: Philip Withnall - -Helps: #1866 -Fixes: #2216 ---- - glib/gmain.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++--- - meson.build | 14 ++++++ - 2 files changed, 125 insertions(+), 6 deletions(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index 15581ee7a..e9965f7f6 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -67,6 +67,12 @@ - #include - #include - -+#ifdef HAVE_PIDFD -+#include -+#include -+#include /* P_PIDFD */ -+#endif /* HAVE_PIDFD */ -+ - #ifdef G_OS_WIN32 - #define STRICT - #include -@@ -329,10 +335,11 @@ struct _GChildWatchSource - GSource source; - GPid pid; - gint child_status; --#ifdef G_OS_WIN32 -+ /* @poll is always used on Windows, and used on Unix iff @using_pidfd is set: */ - GPollFD poll; --#else /* G_OS_WIN32 */ -- gboolean child_exited; /* (atomic) */ -+#ifndef G_OS_WIN32 -+ gboolean child_exited; /* (atomic); not used iff @using_pidfd is set */ -+ gboolean using_pidfd; - #endif /* G_OS_WIN32 */ - }; - -@@ -5325,7 +5332,8 @@ dispatch_unix_signals_unlocked (void) - { - GChildWatchSource *source = node->data; - -- if (!g_atomic_int_get (&source->child_exited)) -+ if (!source->using_pidfd && -+ !g_atomic_int_get (&source->child_exited)) - { - pid_t pid; - do -@@ -5384,6 +5392,38 @@ g_child_watch_prepare (GSource *source, - return g_atomic_int_get (&child_watch_source->child_exited); - } - -+#ifdef HAVE_PIDFD -+static int -+siginfo_t_to_wait_status (const siginfo_t *info) -+{ -+ /* Each of these returns is essentially the inverse of WIFEXITED(), -+ * WIFSIGNALED(), etc. */ -+ switch (info->si_code) -+ { -+ case CLD_EXITED: -+ return W_EXITCODE (info->si_status, 0); -+ case CLD_KILLED: -+ return W_EXITCODE (0, info->si_status); -+ case CLD_DUMPED: -+#ifdef WCOREFLAG -+ return W_EXITCODE (0, info->si_status | WCOREFLAG); -+#else -+ g_assert_not_reached (); -+#endif -+ case CLD_CONTINUED: -+#ifdef __W_CONTINUED -+ return __W_CONTINUED; -+#else -+ g_assert_not_reached (); -+#endif -+ case CLD_STOPPED: -+ case CLD_TRAPPED: -+ default: -+ return W_STOPCODE (info->si_status); -+ } -+} -+#endif /* HAVE_PIDFD */ -+ - static gboolean - g_child_watch_check (GSource *source) - { -@@ -5391,6 +5431,34 @@ g_child_watch_check (GSource *source) - - child_watch_source = (GChildWatchSource *) source; - -+#ifdef HAVE_PIDFD -+ if (child_watch_source->using_pidfd) -+ { -+ gboolean child_exited = child_watch_source->poll.revents & G_IO_IN; -+ -+ if (child_exited) -+ { -+ siginfo_t child_info = { 0, }; -+ -+ /* Get the exit status */ -+ if (waitid (P_PIDFD, child_watch_source->poll.fd, &child_info, WEXITED | WNOHANG) >= 0 && -+ child_info.si_pid != 0) -+ { -+ /* waitid() helpfully provides the wait status in a decomposed -+ * form which is quite useful. Unfortunately we have to report it -+ * to the #GChildWatchFunc as a waitpid()-style platform-specific -+ * wait status, so that the user code in #GChildWatchFunc can then -+ * call WIFEXITED() (etc.) on it. That means re-composing the -+ * status information. */ -+ child_watch_source->child_status = siginfo_t_to_wait_status (&child_info); -+ child_watch_source->child_exited = TRUE; -+ } -+ } -+ -+ return child_exited; -+ } -+#endif /* HAVE_PIDFD */ -+ - return g_atomic_int_get (&child_watch_source->child_exited); - } - -@@ -5575,6 +5643,11 @@ g_unix_signal_watch_finalize (GSource *source) - static void - g_child_watch_finalize (GSource *source) - { -+ GChildWatchSource *child_watch_source = (GChildWatchSource *) source; -+ -+ if (child_watch_source->using_pidfd) -+ return; -+ - G_LOCK (unix_signal_lock); - unix_child_watches = g_slist_remove (unix_child_watches, source); - unref_unix_signal_handler_unlocked (SIGCHLD); -@@ -5676,6 +5749,9 @@ g_child_watch_source_new (GPid pid) - { - GSource *source; - GChildWatchSource *child_watch_source; -+#ifdef HAVE_PIDFD -+ int errsv; -+#endif - - #ifndef G_OS_WIN32 - g_return_val_if_fail (pid > 0, NULL); -@@ -5694,14 +5770,43 @@ g_child_watch_source_new (GPid pid) - child_watch_source->poll.events = G_IO_IN; - - g_source_add_poll (source, &child_watch_source->poll); --#else /* G_OS_WIN32 */ -+#else /* !G_OS_WIN32 */ -+ -+#ifdef HAVE_PIDFD -+ /* Use a pidfd, if possible, to avoid having to install a global SIGCHLD -+ * handler and potentially competing with any other library/code which wants -+ * to install one. -+ * -+ * Unfortunately this use of pidfd isn’t race-free (the PID could be recycled -+ * between the caller calling g_child_watch_source_new() and here), but it’s -+ * better than SIGCHLD. -+ */ -+ child_watch_source->poll.fd = (int) syscall (SYS_pidfd_open, pid, 0); -+ errsv = errno; -+ -+ if (child_watch_source->poll.fd >= 0) -+ { -+ child_watch_source->using_pidfd = TRUE; -+ child_watch_source->poll.events = G_IO_IN; -+ g_source_add_poll (source, &child_watch_source->poll); -+ -+ return source; -+ } -+ else -+ { -+ g_debug ("pidfd_open(%" G_PID_FORMAT ") failed with error: %s", -+ pid, g_strerror (errsv)); -+ /* Fall through; likely the kernel isn’t new enough to support pidfd_open() */ -+ } -+#endif /* HAVE_PIDFD */ -+ - G_LOCK (unix_signal_lock); - ref_unix_signal_handler_unlocked (SIGCHLD); - unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source); - if (waitpid (pid, &child_watch_source->child_status, WNOHANG) > 0) - child_watch_source->child_exited = TRUE; - G_UNLOCK (unix_signal_lock); --#endif /* G_OS_WIN32 */ -+#endif /* !G_OS_WIN32 */ - - return source; - } -diff --git a/meson.build b/meson.build -index a0223ce5b..1e1bd602c 100644 ---- a/meson.build -+++ b/meson.build -@@ -810,6 +810,20 @@ if cc.links('''#include - glib_conf.set('HAVE_EVENTFD', 1) - endif - -+# Check for pidfd_open(2) -+if cc.links('''#include -+ #include -+ #include -+ #include -+ int main (int argc, char ** argv) { -+ siginfo_t child_info = { 0, }; -+ syscall (SYS_pidfd_open, 0, 0); -+ waitid (P_PIDFD, 0, &child_info, WEXITED | WNOHANG); -+ return 0; -+ }''', name : 'pidfd_open(2) system call') -+ glib_conf.set('HAVE_PIDFD', 1) -+endif -+ - # Check for __uint128_t (gcc) by checking for 128-bit division - uint128_t_src = '''int main() { - static __uint128_t v1 = 100; --- -2.41.0 - - -From 13c62bc181c6da9f287b737f7a3238e0269b40b3 Mon Sep 17 00:00:00 2001 -From: Christian Hergert -Date: Tue, 2 Aug 2022 12:35:40 -0700 -Subject: [PATCH 2/4] gmain: close pidfd when finalizing GChildWatchSource - -A file-descriptor was created with the introduction of pidfd_getfd() but -nothing is closing it when the source finalizes. The GChildWatchSource is -the creator and consumer of this FD and therefore responsible for closing -it on finalization. - -The pidfd leak was introduced in !2408. - -This fixes issues with Builder where anon_inode:[pidfd] exhaust the -available FD limit for the process. - -Fixes #2708 ---- - glib/gmain.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index e9965f7f6..3ceec61ee 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -5646,7 +5646,11 @@ g_child_watch_finalize (GSource *source) - GChildWatchSource *child_watch_source = (GChildWatchSource *) source; - - if (child_watch_source->using_pidfd) -- return; -+ { -+ if (child_watch_source->poll.fd >= 0) -+ close (child_watch_source->poll.fd); -+ return; -+ } - - G_LOCK (unix_signal_lock); - unix_child_watches = g_slist_remove (unix_child_watches, source); --- -2.41.0 - - -From 378c72cbe12767b8f6aedc19c7ca46c07aa1ca73 Mon Sep 17 00:00:00 2001 -From: Owen Rafferty -Date: Tue, 12 Jul 2022 20:03:56 -0500 -Subject: [PATCH 3/4] gmain: define non-posix symbols - ---- - glib/gmain.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/glib/gmain.c b/glib/gmain.c -index 3ceec61ee..a2d7bb3ba 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -71,6 +71,12 @@ - #include - #include - #include /* P_PIDFD */ -+#ifndef W_EXITCODE -+#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) -+#endif -+#ifndef W_STOPCODE -+#define W_STOPCODE(sig) ((sig) << 8 | 0x7f) -+#endif - #endif /* HAVE_PIDFD */ - - #ifdef G_OS_WIN32 --- -2.41.0 - - -From aac37188ce26366bd86626700d49cee0cb121472 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Wed, 21 Dec 2022 12:11:46 +0000 -Subject: [PATCH 4/4] gmain: Define fallback values for siginfo_t constants for - musl -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -musl doesn’t define them itself, presumably because they’re not defined -in POSIX. glibc does define them. Thankfully, the values used in glibc -match the values used internally in other musl macros. - -Define the values as a fallback. As a result of this, we can get rid of -the `g_assert_if_reached()` checks in `siginfo_t_to_wait_status()`. - -This should fix catching signals from a subprocess when built against -musl. - -Signed-off-by: Philip Withnall - -Fixes: #2852 ---- - glib/gmain.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index a2d7bb3ba..f0cf700c0 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -77,6 +77,16 @@ - #ifndef W_STOPCODE - #define W_STOPCODE(sig) ((sig) << 8 | 0x7f) - #endif -+#ifndef WCOREFLAG -+/* musl doesn’t define WCOREFLAG while glibc does. Unfortunately, there’s no way -+ * to detect we’re building against musl, so just define it and hope. -+ * See https://git.musl-libc.org/cgit/musl/tree/include/sys/wait.h#n51 */ -+#define WCOREFLAG 0x80 -+#endif -+#ifndef __W_CONTINUED -+/* Same as above, for musl */ -+#define __W_CONTINUED 0xffff -+#endif - #endif /* HAVE_PIDFD */ - - #ifdef G_OS_WIN32 -@@ -5411,17 +5421,9 @@ siginfo_t_to_wait_status (const siginfo_t *info) - case CLD_KILLED: - return W_EXITCODE (0, info->si_status); - case CLD_DUMPED: --#ifdef WCOREFLAG - return W_EXITCODE (0, info->si_status | WCOREFLAG); --#else -- g_assert_not_reached (); --#endif - case CLD_CONTINUED: --#ifdef __W_CONTINUED - return __W_CONTINUED; --#else -- g_assert_not_reached (); --#endif - case CLD_STOPPED: - case CLD_TRAPPED: - default: --- -2.41.0 - diff --git a/base/rx-glib2/2435.patch b/base/rx-glib2/2435.patch deleted file mode 100644 index 862503b..0000000 --- a/base/rx-glib2/2435.patch +++ /dev/null @@ -1,132 +0,0 @@ -From a879d08e912a4421786b44af479f94f7b4503f5a Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Mon, 17 Jan 2022 15:27:24 +0000 -Subject: [PATCH] gspawn: Report errors with closing file descriptors between - fork/exec -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If a seccomp policy is set up incorrectly so that it returns `EPERM` for -`close_range()` rather than `ENOSYS` due to it not being recognised, no -error would previously be reported from GLib, but some file descriptors -wouldn’t be closed, and that would cause a hung zombie process. The -zombie process would be waiting for one half of a socket to be closed. - -Fix that by correctly propagating errors from `close_range()` back to the -parent process so they can be reported correctly. - -Distributions which aren’t yet carrying the Docker fix to correctly -return `ENOSYS` from unrecognised syscalls may want to temporarily carry -an additional patch to fall back to `safe_fdwalk()` if `close_range()` -fails with `EPERM`. This change will not be accepted upstream as `EPERM` -is not the right error for `close_range()` to be returning. - -Signed-off-by: Philip Withnall - -Fixes: #2580 ---- - glib/gspawn.c | 35 ++++++++++++++++++++++++++--------- - 1 file changed, 26 insertions(+), 9 deletions(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index c2fe306dc..9c2f7ba7b 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -1457,8 +1457,10 @@ safe_fdwalk (int (*cb)(void *data, int fd), void *data) - } - - /* This function is called between fork() and exec() and hence must be -- * async-signal-safe (see signal-safety(7)). */ --static void -+ * async-signal-safe (see signal-safety(7)). -+ * -+ * On failure, `-1` will be returned and errno will be set. */ -+static int - safe_closefrom (int lowfd) - { - #if defined(__FreeBSD__) || defined(__OpenBSD__) -@@ -1472,6 +1474,7 @@ safe_closefrom (int lowfd) - * should be safe to use. - */ - (void) closefrom (lowfd); -+ return 0; - #elif defined(__DragonFly__) - /* It is unclear whether closefrom function included in DragonFlyBSD libc_r - * is safe to use because it calls a lot of library functions. It is also -@@ -1479,12 +1482,13 @@ safe_closefrom (int lowfd) - * direct system call here ourselves to avoid possible issues. - */ - (void) syscall (SYS_closefrom, lowfd); -+ return 0; - #elif defined(F_CLOSEM) - /* NetBSD and AIX have a special fcntl command which does the same thing as - * closefrom. NetBSD also includes closefrom function, which seems to be a - * simple wrapper of the fcntl command. - */ -- (void) fcntl (lowfd, F_CLOSEM); -+ return fcntl (lowfd, F_CLOSEM); - #else - - #if defined(HAVE_CLOSE_RANGE) -@@ -1494,9 +1498,11 @@ safe_closefrom (int lowfd) - * - * Handle ENOSYS in case it’s supported in libc but not the kernel; if so, - * fall back to safe_fdwalk(). */ -- if (close_range (lowfd, G_MAXUINT, 0) != 0 && errno == ENOSYS) -+ int ret = close_range (lowfd, G_MAXUINT, 0); -+ if (ret == 0 || errno != ENOSYS) -+ return ret; - #endif /* HAVE_CLOSE_RANGE */ -- (void) safe_fdwalk (close_func, GINT_TO_POINTER (lowfd)); -+ return safe_fdwalk (close_func, GINT_TO_POINTER (lowfd)); - #endif - } - -@@ -1534,7 +1540,8 @@ enum - CHILD_EXEC_FAILED, - CHILD_OPEN_FAILED, - CHILD_DUP2_FAILED, -- CHILD_FORK_FAILED -+ CHILD_FORK_FAILED, -+ CHILD_CLOSE_FAILED, - }; - - /* This function is called between fork() and exec() and hence must be -@@ -1650,12 +1657,14 @@ do_exec (gint child_err_report_fd, - if (safe_dup2 (child_err_report_fd, 3) < 0) - write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED); - set_cloexec (GINT_TO_POINTER (0), 3); -- safe_closefrom (4); -+ if (safe_closefrom (4) < 0) -+ write_err_and_exit (child_err_report_fd, CHILD_CLOSE_FAILED); - child_err_report_fd = 3; - } - else - { -- safe_fdwalk (set_cloexec, GINT_TO_POINTER (3)); -+ if (safe_fdwalk (set_cloexec, GINT_TO_POINTER (3)) < 0) -+ write_err_and_exit (child_err_report_fd, CHILD_CLOSE_FAILED); - } - } - else -@@ -2446,7 +2455,15 @@ fork_exec (gboolean intermediate_child, - _("Failed to fork child process (%s)"), - g_strerror (buf[1])); - break; -- -+ -+ case CHILD_CLOSE_FAILED: -+ g_set_error (error, -+ G_SPAWN_ERROR, -+ G_SPAWN_ERROR_FAILED, -+ _("Failed to close file descriptor for child process (%s)"), -+ g_strerror (buf[1])); -+ break; -+ - default: - g_set_error (error, - G_SPAWN_ERROR, --- -2.34.1 - diff --git a/base/rx-glib2/2826.patch b/base/rx-glib2/2826.patch deleted file mode 100644 index 83d527a..0000000 --- a/base/rx-glib2/2826.patch +++ /dev/null @@ -1,278 +0,0 @@ -From 764f071909df70622e79ee71323973c18c055c8c Mon Sep 17 00:00:00 2001 -From: Giuseppe Scrivano -Date: Mon, 14 Sep 2020 16:28:10 +0200 -Subject: [PATCH 1/5] gdbusauth: empty DATA does not need a trailing space - -This is an interoperability fix. If the line is exactly "DATA\r\n", -the reference implementation of D-Bus treats this as equivalent to -"DATA \r\n", meaning the data block consists of zero hex-encoded bytes. -In practice, D-Bus clients send empty data blocks as "DATA\r\n", and -in fact sd-bus only accepts that, rejecting "DATA \r\n". - -[Originally part of a larger commit; commit message added by smcv] - -Signed-off-by: Giuseppe Scrivano -Co-authored-by: Simon McVittie -Signed-off-by: Simon McVittie ---- - gio/gdbusauth.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c -index ede21c8514..d2ca41a201 100644 ---- a/gio/gdbusauth.c -+++ b/gio/gdbusauth.c -@@ -783,13 +783,13 @@ _g_dbus_auth_run_client (GDBusAuth *auth, - if (line == NULL) - goto out; - debug_print ("CLIENT: WaitingForData, read='%s'", line); -- if (g_str_has_prefix (line, "DATA ")) -+ if (g_str_equal (line, "DATA") || g_str_has_prefix (line, "DATA ")) - { - gchar *encoded; - gchar *decoded_data; - gsize decoded_data_len = 0; - -- encoded = g_strdup (line + 5); -+ encoded = g_strdup (line + 4); - g_free (line); - g_strstrip (encoded); - decoded_data = hexdecode (encoded, &decoded_data_len, error); -@@ -1255,13 +1255,13 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - debug_print ("SERVER: WaitingForData, read '%s'", line); - if (line == NULL) - goto out; -- if (g_str_has_prefix (line, "DATA ")) -+ if (g_str_equal (line, "DATA") || g_str_has_prefix (line, "DATA ")) - { - gchar *encoded; - gchar *decoded_data; - gsize decoded_data_len = 0; - -- encoded = g_strdup (line + 5); -+ encoded = g_strdup (line + 4); - g_free (line); - g_strstrip (encoded); - decoded_data = hexdecode (encoded, &decoded_data_len, error); --- -GitLab - - -From a7d2e727eefcf883bb463ad559f5632e8e448757 Mon Sep 17 00:00:00 2001 -From: Giuseppe Scrivano -Date: Mon, 14 Sep 2020 16:28:10 +0200 -Subject: [PATCH 2/5] GDBusServer: If no initial response for EXTERNAL, send a - challenge - -Sending an "initial response" along with the AUTH command is meant -to be an optional optimization, and clients are allowed to omit it. -We must reply with our initial challenge, which in the case of EXTERNAL -is an empty string: the client responds to that with the authorization -identity. - -If we do not reply to the AUTH command, then the client will wait -forever for our reply, while we wait forever for the reply that we -expect the client to send, resulting in deadlock. - -D-Bus does not have a way to distinguish between an empty initial -response and the absence of an initial response, so clients that want -to use an empty authorization identity, such as systed's sd-bus, -cannot use the initial-response optimization and will fail to connect -to a GDBusServer that does not have this change. - -[Originally part of a larger commit; commit message added by smcv.] - -Signed-off-by: Simon McVittie ---- - gio/gdbusauthmechanismexternal.c | 23 ++++++++++++++++++----- - 1 file changed, 18 insertions(+), 5 deletions(-) - -diff --git a/gio/gdbusauthmechanismexternal.c b/gio/gdbusauthmechanismexternal.c -index 617fe1d0e5..ddd06cbd5e 100644 ---- a/gio/gdbusauthmechanismexternal.c -+++ b/gio/gdbusauthmechanismexternal.c -@@ -40,6 +40,7 @@ struct _GDBusAuthMechanismExternalPrivate - gboolean is_client; - gboolean is_server; - GDBusAuthMechanismState state; -+ gboolean empty_data_sent; - }; - - static gint mechanism_get_priority (void); -@@ -253,7 +254,9 @@ mechanism_server_initiate (GDBusAuthMechanism *mechanism, - } - else - { -- m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA; -+ /* The initial-response optimization was not used, so we need to -+ * send an empty challenge to prompt the client to respond. */ -+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND; - } - } - -@@ -288,12 +291,22 @@ mechanism_server_data_send (GDBusAuthMechanism *mechanism, - - g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL); - g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL); -- g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL); - -- /* can never end up here because we are never in the HAVE_DATA_TO_SEND state */ -- g_assert_not_reached (); -+ if (out_data_len) -+ *out_data_len = 0; - -- return NULL; -+ if (m->priv->empty_data_sent) -+ { -+ /* We have already sent an empty data response. -+ Reject the connection. */ -+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; -+ return NULL; -+ } -+ -+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA; -+ m->priv->empty_data_sent = TRUE; -+ -+ return g_strdup (""); - } - - static gchar * --- -GitLab - - -From b51e3ab09e39c590c65a7be6228ecfa48a6189f6 Mon Sep 17 00:00:00 2001 -From: Giuseppe Scrivano -Date: Mon, 14 Sep 2020 16:28:10 +0200 -Subject: [PATCH 3/5] GDBusServer: Accept empty authorization identity for - EXTERNAL mechanism - -RFC 4422 appendix A defines the empty authorization identity to mean -the identity that the server associated with its authentication -credentials. In this case, this means whatever uid is in the -GCredentials object. - -In particular, this means that clients in a different Linux user -namespace can authenticate against our server and will be authorized -as the version of their uid that is visible in the server's namespace, -even if the corresponding numeric uid returned by geteuid() in the -client's namespace was different. systemd's sd-bus has relied on this -since commit -https://github.com/systemd/systemd/commit/1ed4723d38cd0d1423c8fe650f90fa86007ddf55. - -[Originally part of a larger commit; commit message added by smcv] - -Signed-off-by: Simon McVittie ---- - gio/gdbusauthmechanismexternal.c | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/gio/gdbusauthmechanismexternal.c b/gio/gdbusauthmechanismexternal.c -index ddd06cbd5e..a465862d12 100644 ---- a/gio/gdbusauthmechanismexternal.c -+++ b/gio/gdbusauthmechanismexternal.c -@@ -201,14 +201,24 @@ data_matches_credentials (const gchar *data, - if (credentials == NULL) - goto out; - -- if (data == NULL || data_len == 0) -- goto out; -- - #if defined(G_OS_UNIX) - { - gint64 alleged_uid; - gchar *endp; - -+ /* If we were unable to find out the uid, then nothing -+ * can possibly match it. */ -+ if (g_credentials_get_unix_user (credentials, NULL) == (uid_t) -1) -+ goto out; -+ -+ /* An empty authorization identity means we want to be -+ * whatever identity the out-of-band credentials say we have -+ * (RFC 4422 appendix A.1). This effectively matches any uid. */ -+ if (data == NULL || data_len == 0) -+ { -+ match = TRUE; -+ goto out; -+ } - /* on UNIX, this is the uid as a string in base 10 */ - alleged_uid = g_ascii_strtoll (data, &endp, 10); - if (*endp == '\0') --- -GitLab - - -From 3f532af65c98e4ba8426c53f26c9ee15d3692f9c Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Mon, 18 Jul 2022 17:14:44 +0100 -Subject: [PATCH 4/5] gdbusauth: Represent empty data block as DATA\r\n, with - no space - -This is an interoperability fix. The reference implementation of D-Bus -treats "DATA\r\n" as equivalent to "DATA \r\n", but sd-bus does not, -and only accepts the former. - -Signed-off-by: Simon McVittie ---- - gio/gdbusauth.c | 34 ++++++++++++++++++++++++++-------- - 1 file changed, 26 insertions(+), 8 deletions(-) - -diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c -index d2ca41a201..89cbbf67c6 100644 ---- a/gio/gdbusauth.c -+++ b/gio/gdbusauth.c -@@ -807,11 +807,21 @@ _g_dbus_auth_run_client (GDBusAuth *auth, - { - gchar *data; - gsize data_len; -- gchar *encoded_data; -+ - data = _g_dbus_auth_mechanism_client_data_send (mech, &data_len); -- encoded_data = _g_dbus_hexencode (data, data_len); -- s = g_strdup_printf ("DATA %s\r\n", encoded_data); -- g_free (encoded_data); -+ -+ if (data_len == 0) -+ { -+ s = g_strdup ("DATA\r\n"); -+ } -+ else -+ { -+ gchar *encoded_data = _g_dbus_hexencode (data, data_len); -+ -+ s = g_strdup_printf ("DATA %s\r\n", encoded_data); -+ g_free (encoded_data); -+ } -+ - g_free (data); - debug_print ("CLIENT: writing '%s'", s); - if (!g_data_output_stream_put_string (dos, s, cancellable, error)) -@@ -1209,13 +1219,21 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - gsize data_len; - - data = _g_dbus_auth_mechanism_server_data_send (mech, &data_len); -+ - if (data != NULL) - { -- gchar *encoded_data; -+ if (data_len == 0) -+ { -+ s = g_strdup ("DATA\r\n"); -+ } -+ else -+ { -+ gchar *encoded_data = _g_dbus_hexencode (data, data_len); -+ -+ s = g_strdup_printf ("DATA %s\r\n", encoded_data); -+ g_free (encoded_data); -+ } - -- encoded_data = _g_dbus_hexencode (data, data_len); -- s = g_strdup_printf ("DATA %s\r\n", encoded_data); -- g_free (encoded_data); - g_free (data); - - debug_print ("SERVER: writing '%s'", s); --- -GitLab diff --git a/base/rx-glib2/3126.patch b/base/rx-glib2/3126.patch deleted file mode 100644 index 4bd6a17..0000000 --- a/base/rx-glib2/3126.patch +++ /dev/null @@ -1,3021 +0,0 @@ -From b4ae1179cbcb91992adc0d5d4fa13341bbcd6c28 Mon Sep 17 00:00:00 2001 -From: William Manley -Date: Tue, 23 Jun 2020 22:59:58 +0100 -Subject: [PATCH 01/19] gvariant-core: Consolidate construction of - `GVariantSerialised` - -So I only need to change it in one place. - -This introduces no functional changes. - -Helps: #2121 ---- - glib/gvariant-core.c | 49 ++++++++++++++++++++++---------------------- - 1 file changed, 25 insertions(+), 24 deletions(-) - -diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c -index b34ba8d8e..cd6a88768 100644 ---- a/glib/gvariant-core.c -+++ b/glib/gvariant-core.c -@@ -349,6 +349,27 @@ g_variant_ensure_size (GVariant *value) - } - } - -+/* < private > -+ * g_variant_to_serialised: -+ * @value: a #GVariant -+ * -+ * Gets a GVariantSerialised for a GVariant in state STATE_SERIALISED. -+ */ -+inline static GVariantSerialised -+g_variant_to_serialised (GVariant *value) -+{ -+ g_assert (value->state & STATE_SERIALISED); -+ { -+ GVariantSerialised serialised = { -+ value->type_info, -+ (gpointer) value->contents.serialised.data, -+ value->size, -+ value->depth, -+ }; -+ return serialised; -+ } -+} -+ - /* < private > - * g_variant_serialise: - * @value: a #GVariant -@@ -1007,16 +1028,8 @@ g_variant_n_children (GVariant *value) - g_variant_lock (value); - - if (value->state & STATE_SERIALISED) -- { -- GVariantSerialised serialised = { -- value->type_info, -- (gpointer) value->contents.serialised.data, -- value->size, -- value->depth, -- }; -- -- n_children = g_variant_serialised_n_children (serialised); -- } -+ n_children = g_variant_serialised_n_children ( -+ g_variant_to_serialised (value)); - else - n_children = value->contents.tree.n_children; - -@@ -1083,12 +1096,7 @@ g_variant_get_child_value (GVariant *value, - } - - { -- GVariantSerialised serialised = { -- value->type_info, -- (gpointer) value->contents.serialised.data, -- value->size, -- value->depth, -- }; -+ GVariantSerialised serialised = g_variant_to_serialised (value); - GVariantSerialised s_child; - GVariant *child; - -@@ -1201,14 +1209,7 @@ g_variant_is_normal_form (GVariant *value) - - if (value->state & STATE_SERIALISED) - { -- GVariantSerialised serialised = { -- value->type_info, -- (gpointer) value->contents.serialised.data, -- value->size, -- value->depth -- }; -- -- if (g_variant_serialised_is_normal (serialised)) -+ if (g_variant_serialised_is_normal (g_variant_to_serialised (value))) - value->state |= STATE_TRUSTED; - } - else --- -2.40.0 - -From d51c16a7c8c3a57f1bad4305363ad85914ecab2e Mon Sep 17 00:00:00 2001 -From: William Manley -Date: Thu, 25 Jun 2020 17:08:21 +0100 -Subject: [PATCH 02/19] gvariant-serialiser: Factor out functions for dealing - with framing offsets - -This introduces no functional changes. - -Helps: #2121 ---- - glib/gvariant-serialiser.c | 108 +++++++++++++++++++------------------ - 1 file changed, 57 insertions(+), 51 deletions(-) - -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index 06f419fe4..ab6a56eb6 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -633,30 +633,62 @@ gvs_calculate_total_size (gsize body_size, - return body_size + 8 * offsets; - } - -+struct Offsets -+{ -+ gsize data_size; -+ -+ guchar *array; -+ gsize length; -+ guint offset_size; -+ -+ gboolean is_normal; -+}; -+ - static gsize --gvs_variable_sized_array_n_children (GVariantSerialised value) -+gvs_offsets_get_offset_n (struct Offsets *offsets, -+ gsize n) -+{ -+ return gvs_read_unaligned_le ( -+ offsets->array + (offsets->offset_size * n), offsets->offset_size); -+} -+ -+static struct Offsets -+gvs_variable_sized_array_get_frame_offsets (GVariantSerialised value) - { -+ struct Offsets out = { 0, }; - gsize offsets_array_size; -- gsize offset_size; - gsize last_end; - - if (value.size == 0) -- return 0; -- -- offset_size = gvs_get_offset_size (value.size); -+ { -+ out.is_normal = TRUE; -+ return out; -+ } - -- last_end = gvs_read_unaligned_le (value.data + value.size - -- offset_size, offset_size); -+ out.offset_size = gvs_get_offset_size (value.size); -+ last_end = gvs_read_unaligned_le (value.data + value.size - out.offset_size, -+ out.offset_size); - - if (last_end > value.size) -- return 0; -+ return out; /* offsets not normal */ - - offsets_array_size = value.size - last_end; - -- if (offsets_array_size % offset_size) -- return 0; -+ if (offsets_array_size % out.offset_size) -+ return out; /* offsets not normal */ -+ -+ out.data_size = last_end; -+ out.array = value.data + last_end; -+ out.length = offsets_array_size / out.offset_size; -+ out.is_normal = TRUE; - -- return offsets_array_size / offset_size; -+ return out; -+} -+ -+static gsize -+gvs_variable_sized_array_n_children (GVariantSerialised value) -+{ -+ return gvs_variable_sized_array_get_frame_offsets (value).length; - } - - static GVariantSerialised -@@ -664,8 +696,9 @@ gvs_variable_sized_array_get_child (GVariantSerialised value, - gsize index_) - { - GVariantSerialised child = { 0, }; -- gsize offset_size; -- gsize last_end; -+ -+ struct Offsets offsets = gvs_variable_sized_array_get_frame_offsets (value); -+ - gsize start; - gsize end; - -@@ -673,18 +706,11 @@ gvs_variable_sized_array_get_child (GVariantSerialised value, - g_variant_type_info_ref (child.type_info); - child.depth = value.depth + 1; - -- offset_size = gvs_get_offset_size (value.size); -- -- last_end = gvs_read_unaligned_le (value.data + value.size - -- offset_size, offset_size); -- - if (index_ > 0) - { - guint alignment; - -- start = gvs_read_unaligned_le (value.data + last_end + -- (offset_size * (index_ - 1)), -- offset_size); -+ start = gvs_offsets_get_offset_n (&offsets, index_ - 1); - - g_variant_type_info_query (child.type_info, &alignment, NULL); - start += (-start) & alignment; -@@ -692,11 +718,9 @@ gvs_variable_sized_array_get_child (GVariantSerialised value, - else - start = 0; - -- end = gvs_read_unaligned_le (value.data + last_end + -- (offset_size * index_), -- offset_size); -+ end = gvs_offsets_get_offset_n (&offsets, index_); - -- if (start < end && end <= value.size && end <= last_end) -+ if (start < end && end <= value.size && end <= offsets.data_size) - { - child.data = value.data + start; - child.size = end - start; -@@ -768,34 +792,16 @@ static gboolean - gvs_variable_sized_array_is_normal (GVariantSerialised value) - { - GVariantSerialised child = { 0, }; -- gsize offsets_array_size; -- guchar *offsets_array; -- guint offset_size; - guint alignment; -- gsize last_end; -- gsize length; - gsize offset; - gsize i; - -- if (value.size == 0) -- return TRUE; -- -- offset_size = gvs_get_offset_size (value.size); -- last_end = gvs_read_unaligned_le (value.data + value.size - -- offset_size, offset_size); -+ struct Offsets offsets = gvs_variable_sized_array_get_frame_offsets (value); - -- if (last_end > value.size) -+ if (!offsets.is_normal) - return FALSE; - -- offsets_array_size = value.size - last_end; -- -- if (offsets_array_size % offset_size) -- return FALSE; -- -- offsets_array = value.data + value.size - offsets_array_size; -- length = offsets_array_size / offset_size; -- -- if (length == 0) -+ if (value.size != 0 && offsets.length == 0) - return FALSE; - - child.type_info = g_variant_type_info_element (value.type_info); -@@ -803,14 +809,14 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value) - child.depth = value.depth + 1; - offset = 0; - -- for (i = 0; i < length; i++) -+ for (i = 0; i < offsets.length; i++) - { - gsize this_end; - -- this_end = gvs_read_unaligned_le (offsets_array + offset_size * i, -- offset_size); -+ this_end = gvs_read_unaligned_le (offsets.array + offsets.offset_size * i, -+ offsets.offset_size); - -- if (this_end < offset || this_end > last_end) -+ if (this_end < offset || this_end > offsets.data_size) - return FALSE; - - while (offset & alignment) -@@ -832,7 +838,7 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value) - offset = this_end; - } - -- g_assert (offset == last_end); -+ g_assert (offset == offsets.data_size); - - return TRUE; - } --- -2.40.0 - -From fd215233ae37ce20cd84eb128c86b90c4dd610fa Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Tue, 25 Oct 2022 18:05:52 +0100 -Subject: [PATCH 03/19] gvariant: Zero-initialise various GVariantSerialised - objects - -The following few commits will add a couple of new fields to -`GVariantSerialised`, and they should be zero-filled by default. - -Try and pre-empt that a bit by zero-filling `GVariantSerialised` by -default in a few places. - -Signed-off-by: Philip Withnall - -Helps: #2121 ---- - glib/gvariant.c | 2 +- - glib/tests/gvariant.c | 12 ++++++------ - 2 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index e48dec1ad..8ebbaa662 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -5944,7 +5944,7 @@ g_variant_byteswap (GVariant *value) - if (alignment) - /* (potentially) contains multi-byte numeric data */ - { -- GVariantSerialised serialised; -+ GVariantSerialised serialised = { 0, }; - GVariant *trusted; - GBytes *bytes; - -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index 35434cae9..ebd617639 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -1438,7 +1438,7 @@ test_maybe (void) - - for (flavour = 0; flavour < 8; flavour += alignment) - { -- GVariantSerialised serialised; -+ GVariantSerialised serialised = { 0, }; - GVariantSerialised child; - - serialised.type_info = type_info; -@@ -1562,7 +1562,7 @@ test_array (void) - - for (flavour = 0; flavour < 8; flavour += alignment) - { -- GVariantSerialised serialised; -+ GVariantSerialised serialised = { 0, }; - - serialised.type_info = array_info; - serialised.data = flavoured_malloc (needed_size, flavour); -@@ -1726,7 +1726,7 @@ test_tuple (void) - - for (flavour = 0; flavour < 8; flavour += alignment) - { -- GVariantSerialised serialised; -+ GVariantSerialised serialised = { 0, }; - - serialised.type_info = type_info; - serialised.data = flavoured_malloc (needed_size, flavour); -@@ -1821,7 +1821,7 @@ test_variant (void) - - for (flavour = 0; flavour < 8; flavour += alignment) - { -- GVariantSerialised serialised; -+ GVariantSerialised serialised = { 0, }; - GVariantSerialised child; - - serialised.type_info = type_info; -@@ -2268,7 +2268,7 @@ serialise_tree (TreeInstance *tree, - static void - test_byteswap (void) - { -- GVariantSerialised one, two; -+ GVariantSerialised one = { 0, }, two = { 0, }; - TreeInstance *tree; - - tree = tree_instance_new (NULL, 3); -@@ -2342,7 +2342,7 @@ test_serialiser_children (void) - static void - test_fuzz (gdouble *fuzziness) - { -- GVariantSerialised serialised; -+ GVariantSerialised serialised = { 0, }; - TreeInstance *tree; - - /* make an instance */ --- -2.40.0 - -From 96e27afc7a1da0944d995ff0715679870ce8d503 Mon Sep 17 00:00:00 2001 -From: William Manley -Date: Mon, 29 Jun 2020 16:59:44 +0100 -Subject: [PATCH 04/19] =?UTF-8?q?gvariant:=20Don=E2=80=99t=20allow=20child?= - =?UTF-8?q?=20elements=20to=20overlap=20with=20each=20other?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If different elements of a variable sized array can overlap with each -other then we can cause a `GVariant` to normalise to a much larger type. - -This commit changes the behaviour of `GVariant` with non-normal form data. If -an invalid frame offset is found all subsequent elements are given their -default value. - -When retrieving an element at index `n` we scan the frame offsets up to index -`n` and if they are not in order we return an element with the default value -for that type. This guarantees that elements don't overlap with each -other. We remember the offset we've scanned up to so we don't need to -repeat this work on subsequent accesses. We skip these checks for trusted -data. - -Unfortunately this makes random access of untrusted data O(n) — at least -on first access. It doesn't affect the algorithmic complexity of accessing -elements in order, such as when using the `GVariantIter` interface. Also: -the cost of validation will be amortised as the `GVariant` instance is -continued to be used. - -I've implemented this with 4 different functions, 1 for each element size, -rather than looping calling `gvs_read_unaligned_le` in the hope that the -compiler will find it easy to optimise and should produce fairly tight -code. - -Fixes: #2121 ---- - glib/gvariant-core.c | 35 ++++++++++++++++ - glib/gvariant-serialiser.c | 86 ++++++++++++++++++++++++++++++++++++-- - glib/gvariant-serialiser.h | 9 ++++ - glib/tests/gvariant.c | 45 ++++++++++++++++++++ - 4 files changed, 172 insertions(+), 3 deletions(-) - -diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c -index cd6a88768..4bd7d0537 100644 ---- a/glib/gvariant-core.c -+++ b/glib/gvariant-core.c -@@ -65,6 +65,7 @@ struct _GVariant - { - GBytes *bytes; - gconstpointer data; -+ gsize ordered_offsets_up_to; - } serialised; - - struct -@@ -162,6 +163,24 @@ struct _GVariant - * if .data pointed to the appropriate number of nul - * bytes. - * -+ * .ordered_offsets_up_to: If ordered_offsets_up_to == n this means that all -+ * the frame offsets up to and including the frame -+ * offset determining the end of element n are in -+ * order. This guarantees that the bytes of element -+ * n don't overlap with any previous element. -+ * -+ * For trusted data this is set to G_MAXSIZE and we -+ * don't check that the frame offsets are in order. -+ * -+ * Note: This doesn't imply the offsets are good in -+ * any way apart from their ordering. In particular -+ * offsets may be out of bounds for this value or -+ * may imply that the data overlaps the frame -+ * offsets themselves. -+ * -+ * This field is only relevant for arrays of non -+ * fixed width types. -+ * - * .tree: Only valid when the instance is in tree form. - * - * Note that accesses from other threads could result in -@@ -365,6 +384,7 @@ g_variant_to_serialised (GVariant *value) - (gpointer) value->contents.serialised.data, - value->size, - value->depth, -+ value->contents.serialised.ordered_offsets_up_to, - }; - return serialised; - } -@@ -396,6 +416,7 @@ g_variant_serialise (GVariant *value, - serialised.size = value->size; - serialised.data = data; - serialised.depth = value->depth; -+ serialised.ordered_offsets_up_to = 0; - - children = (gpointer *) value->contents.tree.children; - n_children = value->contents.tree.n_children; -@@ -439,6 +460,15 @@ g_variant_fill_gvs (GVariantSerialised *serialised, - g_assert (serialised->size == value->size); - serialised->depth = value->depth; - -+ if (value->state & STATE_SERIALISED) -+ { -+ serialised->ordered_offsets_up_to = value->contents.serialised.ordered_offsets_up_to; -+ } -+ else -+ { -+ serialised->ordered_offsets_up_to = 0; -+ } -+ - if (serialised->data) - /* g_variant_store() is a public API, so it - * it will reacquire the lock if it needs to. -@@ -481,6 +511,7 @@ g_variant_ensure_serialised (GVariant *value) - bytes = g_bytes_new_take (data, value->size); - value->contents.serialised.data = g_bytes_get_data (bytes, NULL); - value->contents.serialised.bytes = bytes; -+ value->contents.serialised.ordered_offsets_up_to = G_MAXSIZE; - value->state |= STATE_SERIALISED; - } - } -@@ -561,6 +592,7 @@ g_variant_new_from_bytes (const GVariantType *type, - serialised.type_info = value->type_info; - serialised.data = (guchar *) g_bytes_get_data (bytes, &serialised.size); - serialised.depth = 0; -+ serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0; - - if (!g_variant_serialised_check (serialised)) - { -@@ -611,6 +643,8 @@ g_variant_new_from_bytes (const GVariantType *type, - value->contents.serialised.data = g_bytes_get_data (bytes, &value->size); - } - -+ value->contents.serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0; -+ - g_clear_pointer (&owned_bytes, g_bytes_unref); - - return value; -@@ -1130,6 +1164,7 @@ g_variant_get_child_value (GVariant *value, - child->contents.serialised.bytes = - g_bytes_ref (value->contents.serialised.bytes); - child->contents.serialised.data = s_child.data; -+ child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to; - - return child; - } -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index ab6a56eb6..8e9364e85 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -1,6 +1,7 @@ - /* - * Copyright © 2007, 2008 Ryan Lortie - * Copyright © 2010 Codethink Limited -+ * Copyright © 2020 William Manley - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -264,6 +265,7 @@ gvs_fixed_sized_maybe_get_child (GVariantSerialised value, - value.type_info = g_variant_type_info_element (value.type_info); - g_variant_type_info_ref (value.type_info); - value.depth++; -+ value.ordered_offsets_up_to = 0; - - return value; - } -@@ -295,7 +297,7 @@ gvs_fixed_sized_maybe_serialise (GVariantSerialised value, - { - if (n_children) - { -- GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1 }; -+ GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0 }; - - gvs_filler (&child, children[0]); - } -@@ -317,6 +319,7 @@ gvs_fixed_sized_maybe_is_normal (GVariantSerialised value) - /* proper element size: "Just". recurse to the child. */ - value.type_info = g_variant_type_info_element (value.type_info); - value.depth++; -+ value.ordered_offsets_up_to = 0; - - return g_variant_serialised_is_normal (value); - } -@@ -358,6 +361,7 @@ gvs_variable_sized_maybe_get_child (GVariantSerialised value, - value.data = NULL; - - value.depth++; -+ value.ordered_offsets_up_to = 0; - - return value; - } -@@ -388,7 +392,7 @@ gvs_variable_sized_maybe_serialise (GVariantSerialised value, - { - if (n_children) - { -- GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1 }; -+ GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0 }; - - /* write the data for the child. */ - gvs_filler (&child, children[0]); -@@ -408,6 +412,7 @@ gvs_variable_sized_maybe_is_normal (GVariantSerialised value) - value.type_info = g_variant_type_info_element (value.type_info); - value.size--; - value.depth++; -+ value.ordered_offsets_up_to = 0; - - return g_variant_serialised_is_normal (value); - } -@@ -691,6 +696,32 @@ gvs_variable_sized_array_n_children (GVariantSerialised value) - return gvs_variable_sized_array_get_frame_offsets (value).length; - } - -+/* Find the index of the first out-of-order element in @data, assuming that -+ * @data is an array of elements of given @type, starting at index @start and -+ * containing a further @len-@start elements. */ -+#define DEFINE_FIND_UNORDERED(type) \ -+ static gsize \ -+ find_unordered_##type (const guint8 *data, gsize start, gsize len) \ -+ { \ -+ gsize off; \ -+ type current, previous; \ -+ \ -+ memcpy (&previous, data + start * sizeof (current), sizeof (current)); \ -+ for (off = (start + 1) * sizeof (current); off < len * sizeof (current); off += sizeof (current)) \ -+ { \ -+ memcpy (¤t, data + off, sizeof (current)); \ -+ if (current < previous) \ -+ break; \ -+ previous = current; \ -+ } \ -+ return off / sizeof (current) - 1; \ -+ } -+ -+DEFINE_FIND_UNORDERED (guint8); -+DEFINE_FIND_UNORDERED (guint16); -+DEFINE_FIND_UNORDERED (guint32); -+DEFINE_FIND_UNORDERED (guint64); -+ - static GVariantSerialised - gvs_variable_sized_array_get_child (GVariantSerialised value, - gsize index_) -@@ -706,6 +737,49 @@ gvs_variable_sized_array_get_child (GVariantSerialised value, - g_variant_type_info_ref (child.type_info); - child.depth = value.depth + 1; - -+ /* If the requested @index_ is beyond the set of indices whose framing offsets -+ * have been checked, check the remaining offsets to see whether they’re -+ * normal (in order, no overlapping array elements). */ -+ if (index_ > value.ordered_offsets_up_to) -+ { -+ switch (offsets.offset_size) -+ { -+ case 1: -+ { -+ value.ordered_offsets_up_to = find_unordered_guint8 ( -+ offsets.array, value.ordered_offsets_up_to, index_ + 1); -+ break; -+ } -+ case 2: -+ { -+ value.ordered_offsets_up_to = find_unordered_guint16 ( -+ offsets.array, value.ordered_offsets_up_to, index_ + 1); -+ break; -+ } -+ case 4: -+ { -+ value.ordered_offsets_up_to = find_unordered_guint32 ( -+ offsets.array, value.ordered_offsets_up_to, index_ + 1); -+ break; -+ } -+ case 8: -+ { -+ value.ordered_offsets_up_to = find_unordered_guint64 ( -+ offsets.array, value.ordered_offsets_up_to, index_ + 1); -+ break; -+ } -+ default: -+ /* gvs_get_offset_size() only returns maximum 8 */ -+ g_assert_not_reached (); -+ } -+ } -+ -+ if (index_ > value.ordered_offsets_up_to) -+ { -+ /* Offsets are invalid somewhere, so return an empty child. */ -+ return child; -+ } -+ - if (index_ > 0) - { - guint alignment; -@@ -840,6 +914,9 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value) - - g_assert (offset == offsets.data_size); - -+ /* All offsets have now been checked. */ -+ value.ordered_offsets_up_to = G_MAXSIZE; -+ - return TRUE; - } - -@@ -1072,7 +1149,7 @@ gvs_tuple_is_normal (GVariantSerialised value) - for (i = 0; i < length; i++) - { - const GVariantMemberInfo *member_info; -- GVariantSerialised child; -+ GVariantSerialised child = { 0, }; - gsize fixed_size; - guint alignment; - gsize end; -@@ -1132,6 +1209,9 @@ gvs_tuple_is_normal (GVariantSerialised value) - offset = end; - } - -+ /* All element bounds have been checked above. */ -+ value.ordered_offsets_up_to = G_MAXSIZE; -+ - { - gsize fixed_size; - guint alignment; -diff --git a/glib/gvariant-serialiser.h b/glib/gvariant-serialiser.h -index 81343e9ca..bc636000c 100644 ---- a/glib/gvariant-serialiser.h -+++ b/glib/gvariant-serialiser.h -@@ -29,6 +29,15 @@ typedef struct - guchar *data; - gsize size; - gsize depth; /* same semantics as GVariant.depth */ -+ -+ /* If ordered_offsets_up_to == n this means that all the frame offsets up to and -+ * including the frame offset determining the end of element n are in order. -+ * This guarantees that the bytes of element n don't overlap with any previous -+ * element. -+ * -+ * This is both read and set by g_variant_serialised_get_child for arrays of -+ * non-fixed-width types */ -+ gsize ordered_offsets_up_to; - } GVariantSerialised; - - /* deserialisation */ -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index ebd617639..7e5664e65 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -1,5 +1,6 @@ - /* - * Copyright © 2010 Codethink Limited -+ * Copyright © 2020 William Manley - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -1279,6 +1280,7 @@ random_instance_filler (GVariantSerialised *serialised, - serialised->size = instance->size; - - serialised->depth = 0; -+ serialised->ordered_offsets_up_to = 0; - - g_assert_true (serialised->type_info == instance->type_info); - g_assert_cmpuint (serialised->size, ==, instance->size); -@@ -5023,6 +5025,47 @@ test_normal_checking_array_offsets (void) - g_variant_unref (variant); - } - -+/* This is a regression test that we can't have non-normal values that take up -+ * significantly more space than the normal equivalent, by specifying the -+ * offset table entries so that array elements overlap. -+ * -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_832242 */ -+static void -+test_normal_checking_array_offsets2 (void) -+{ -+ const guint8 data[] = { -+ 'h', 'i', '\0', -+ 0x03, 0x00, 0x03, -+ 0x06, 0x00, 0x06, -+ 0x09, 0x00, 0x09, -+ 0x0c, 0x00, 0x0c, -+ 0x0f, 0x00, 0x0f, -+ 0x12, 0x00, 0x12, -+ 0x15, 0x00, 0x15, -+ }; -+ gsize size = sizeof (data); -+ const GVariantType *aaaaaaas = G_VARIANT_TYPE ("aaaaaaas"); -+ GVariant *variant = NULL; -+ GVariant *normal_variant = NULL; -+ GVariant *expected = NULL; -+ -+ variant = g_variant_new_from_data (aaaaaaas, data, size, FALSE, NULL, NULL); -+ g_assert_nonnull (variant); -+ -+ normal_variant = g_variant_get_normal_form (variant); -+ g_assert_nonnull (normal_variant); -+ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 2); -+ -+ expected = g_variant_new_parsed ( -+ "[[[[[[['hi', '', ''], [], []], [], []], [], []], [], []], [], []], [], []]"); -+ g_assert_cmpvariant (expected, variant); -+ g_assert_cmpvariant (expected, normal_variant); -+ -+ g_variant_unref (expected); -+ g_variant_unref (normal_variant); -+ g_variant_unref (variant); -+} -+ - /* Test that a tuple with invalidly large values in its offset table is - * normalised successfully without looping infinitely. */ - static void -@@ -5190,6 +5233,8 @@ main (int argc, char **argv) - test_normal_checking_tuples); - g_test_add_func ("/gvariant/normal-checking/array-offsets", - test_normal_checking_array_offsets); -+ g_test_add_func ("/gvariant/normal-checking/array-offsets2", -+ test_normal_checking_array_offsets2); - g_test_add_func ("/gvariant/normal-checking/tuple-offsets", - test_normal_checking_tuple_offsets); - g_test_add_func ("/gvariant/normal-checking/empty-object-path", --- -2.40.0 - -From 21fba6a534b35cc4fc245c6a8822b53c84b7fb48 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 7 Jan 2022 15:03:52 +0000 -Subject: [PATCH 05/19] gvariant-serialiser: Factor out code to get bounds of a - tuple member - -This introduces no functional changes. - -Signed-off-by: Philip Withnall - -Helps: #2121 ---- - glib/gvariant-serialiser.c | 73 ++++++++++++++++++++++++-------------- - 1 file changed, 46 insertions(+), 27 deletions(-) - -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index 8e9364e85..cf4d2a2a5 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -942,6 +942,51 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value) - * for the tuple. See the notes in gvarianttypeinfo.h. - */ - -+static void -+gvs_tuple_get_member_bounds (GVariantSerialised value, -+ gsize index_, -+ gsize offset_size, -+ gsize *out_member_start, -+ gsize *out_member_end) -+{ -+ const GVariantMemberInfo *member_info; -+ gsize member_start, member_end; -+ -+ member_info = g_variant_type_info_member_info (value.type_info, index_); -+ -+ if (member_info->i + 1) -+ member_start = gvs_read_unaligned_le (value.data + value.size - -+ offset_size * (member_info->i + 1), -+ offset_size); -+ else -+ member_start = 0; -+ -+ member_start += member_info->a; -+ member_start &= member_info->b; -+ member_start |= member_info->c; -+ -+ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST) -+ member_end = value.size - offset_size * (member_info->i + 1); -+ -+ else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) -+ { -+ gsize fixed_size; -+ -+ g_variant_type_info_query (member_info->type_info, NULL, &fixed_size); -+ member_end = member_start + fixed_size; -+ } -+ -+ else /* G_VARIANT_MEMBER_ENDING_OFFSET */ -+ member_end = gvs_read_unaligned_le (value.data + value.size - -+ offset_size * (member_info->i + 2), -+ offset_size); -+ -+ if (out_member_start != NULL) -+ *out_member_start = member_start; -+ if (out_member_end != NULL) -+ *out_member_end = member_end; -+} -+ - static gsize - gvs_tuple_n_children (GVariantSerialised value) - { -@@ -997,33 +1042,7 @@ gvs_tuple_get_child (GVariantSerialised value, - } - } - -- if (member_info->i + 1) -- start = gvs_read_unaligned_le (value.data + value.size - -- offset_size * (member_info->i + 1), -- offset_size); -- else -- start = 0; -- -- start += member_info->a; -- start &= member_info->b; -- start |= member_info->c; -- -- if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST) -- end = value.size - offset_size * (member_info->i + 1); -- -- else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) -- { -- gsize fixed_size; -- -- g_variant_type_info_query (child.type_info, NULL, &fixed_size); -- end = start + fixed_size; -- child.size = fixed_size; -- } -- -- else /* G_VARIANT_MEMBER_ENDING_OFFSET */ -- end = gvs_read_unaligned_le (value.data + value.size - -- offset_size * (member_info->i + 2), -- offset_size); -+ gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end); - - /* The child should not extend into the offset table. */ - if (index_ != g_variant_type_info_n_members (value.type_info) - 1) --- -2.40.0 - -From 44ae51d04615867fe3bcb2842b93c059e764f8f7 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 7 Jan 2022 16:37:29 +0000 -Subject: [PATCH 06/19] gvariant-serialiser: Rework child size calculation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reduces a few duplicate calls to `g_variant_type_info_query()` and -explains why they’re needed. - -Signed-off-by: Philip Withnall - -Helps: #2121 ---- - glib/gvariant-serialiser.c | 31 +++++++++---------------------- - 1 file changed, 9 insertions(+), 22 deletions(-) - -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index cf4d2a2a5..7ba7aed1a 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -1007,14 +1007,18 @@ gvs_tuple_get_child (GVariantSerialised value, - child.depth = value.depth + 1; - offset_size = gvs_get_offset_size (value.size); - -+ /* Ensure the size is set for fixed-sized children, or -+ * g_variant_serialised_check() will fail, even if we return -+ * (child.data == NULL) to indicate an error. */ -+ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) -+ g_variant_type_info_query (child.type_info, NULL, &child.size); -+ - /* tuples are the only (potentially) fixed-sized containers, so the - * only ones that have to deal with the possibility of having %NULL - * data with a non-zero %size if errors occurred elsewhere. - */ - if G_UNLIKELY (value.data == NULL && value.size != 0) - { -- g_variant_type_info_query (child.type_info, NULL, &child.size); -- - /* this can only happen in fixed-sized tuples, - * so the child must also be fixed sized. - */ -@@ -1032,29 +1036,12 @@ gvs_tuple_get_child (GVariantSerialised value, - else - { - if (offset_size * (member_info->i + 1) > value.size) -- { -- /* if the child is fixed size, return its size. -- * if child is not fixed-sized, return size = 0. -- */ -- g_variant_type_info_query (child.type_info, NULL, &child.size); -- -- return child; -- } -+ return child; - } - -- gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end); -- - /* The child should not extend into the offset table. */ -- if (index_ != g_variant_type_info_n_members (value.type_info) - 1) -- { -- GVariantSerialised last_child; -- last_child = gvs_tuple_get_child (value, -- g_variant_type_info_n_members (value.type_info) - 1); -- last_end = last_child.data + last_child.size - value.data; -- g_variant_type_info_unref (last_child.type_info); -- } -- else -- last_end = end; -+ gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end); -+ gvs_tuple_get_member_bounds (value, g_variant_type_info_n_members (value.type_info) - 1, offset_size, NULL, &last_end); - - if (start < end && end <= value.size && end <= last_end) - { --- -2.40.0 - -From a4ddf8ea87a43c2ceffb5d806061d9c6297b9096 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 7 Jan 2022 16:42:14 +0000 -Subject: [PATCH 07/19] =?UTF-8?q?gvariant:=20Don=E2=80=99t=20allow=20child?= - =?UTF-8?q?=20elements=20of=20a=20tuple=20to=20overlap=20each=20other?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is similar to the earlier commit which prevents child elements of a -variable-sized array from overlapping each other, but this time for -tuples. It is based heavily on ideas by William Manley. - -Tuples are slightly different from variable-sized arrays in that they -contain a mixture of fixed and variable sized elements. All but one of -the variable sized elements have an entry in the frame offsets table. -This means that if we were to just check the ordering of the frame -offsets table, the variable sized elements could still overlap -interleaving fixed sized elements, which would be bad. - -Therefore we have to check the elements rather than the frame offsets. - -The logic of checking the elements up to the index currently being -requested, and caching the result in `ordered_offsets_up_to`, means that -the algorithmic cost implications are the same for this commit as for -variable-sized arrays: an O(N) cost for these checks is amortised out -over N accesses to O(1) per access. - -Signed-off-by: Philip Withnall - -Fixes: #2121 ---- - glib/gvariant-core.c | 6 +- - glib/gvariant-serialiser.c | 40 ++++++++ - glib/gvariant-serialiser.h | 7 +- - glib/gvariant.c | 1 + - glib/tests/gvariant.c | 181 +++++++++++++++++++++++++++++++++++++ - 5 files changed, 232 insertions(+), 3 deletions(-) - -diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c -index 4bd7d0537..9b268d977 100644 ---- a/glib/gvariant-core.c -+++ b/glib/gvariant-core.c -@@ -1,6 +1,7 @@ - /* - * Copyright © 2007, 2008 Ryan Lortie - * Copyright © 2010 Codethink Limited -+ * Copyright © 2022 Endless OS Foundation, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -179,7 +180,7 @@ struct _GVariant - * offsets themselves. - * - * This field is only relevant for arrays of non -- * fixed width types. -+ * fixed width types and for tuples. - * - * .tree: Only valid when the instance is in tree form. - * -@@ -1139,6 +1140,9 @@ g_variant_get_child_value (GVariant *value, - */ - s_child = g_variant_serialised_get_child (serialised, index_); - -+ /* Update the cached ordered_offsets_up_to, since @serialised will be thrown away when this function exits */ -+ value->contents.serialised.ordered_offsets_up_to = MAX (value->contents.serialised.ordered_offsets_up_to, serialised.ordered_offsets_up_to); -+ - /* Check whether this would cause nesting too deep. If so, return a fake - * child. The only situation we expect this to happen in is with a variant, - * as all other deeply-nested types have a static type, and hence should -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index 7ba7aed1a..470e21919 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -942,6 +942,10 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value) - * for the tuple. See the notes in gvarianttypeinfo.h. - */ - -+/* Note: This doesn’t guarantee that @out_member_end >= @out_member_start; that -+ * condition may not hold true for invalid serialised variants. The caller is -+ * responsible for checking the returned values and handling invalid ones -+ * appropriately. */ - static void - gvs_tuple_get_member_bounds (GVariantSerialised value, - gsize index_, -@@ -1028,6 +1032,42 @@ gvs_tuple_get_child (GVariantSerialised value, - return child; - } - -+ /* If the requested @index_ is beyond the set of indices whose framing offsets -+ * have been checked, check the remaining offsets to see whether they’re -+ * normal (in order, no overlapping tuple elements). -+ * -+ * Unlike the checks in gvs_variable_sized_array_get_child(), we have to check -+ * all the tuple *elements* here, not just all the framing offsets, since -+ * tuples contain a mix of elements which use framing offsets and ones which -+ * don’t. None of them are allowed to overlap. */ -+ if (index_ > value.ordered_offsets_up_to) -+ { -+ gsize i, prev_i_end = 0; -+ -+ if (value.ordered_offsets_up_to > 0) -+ gvs_tuple_get_member_bounds (value, value.ordered_offsets_up_to - 1, offset_size, NULL, &prev_i_end); -+ -+ for (i = value.ordered_offsets_up_to; i <= index_; i++) -+ { -+ gsize i_start, i_end; -+ -+ gvs_tuple_get_member_bounds (value, i, offset_size, &i_start, &i_end); -+ -+ if (i_start > i_end || i_start < prev_i_end || i_end > value.size) -+ break; -+ -+ prev_i_end = i_end; -+ } -+ -+ value.ordered_offsets_up_to = i - 1; -+ } -+ -+ if (index_ > value.ordered_offsets_up_to) -+ { -+ /* Offsets are invalid somewhere, so return an empty child. */ -+ return child; -+ } -+ - if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET) - { - if (offset_size * (member_info->i + 2) > value.size) -diff --git a/glib/gvariant-serialiser.h b/glib/gvariant-serialiser.h -index bc636000c..765bd43b9 100644 ---- a/glib/gvariant-serialiser.h -+++ b/glib/gvariant-serialiser.h -@@ -35,8 +35,11 @@ typedef struct - * This guarantees that the bytes of element n don't overlap with any previous - * element. - * -- * This is both read and set by g_variant_serialised_get_child for arrays of -- * non-fixed-width types */ -+ * This is both read and set by g_variant_serialised_get_child() for arrays of -+ * non-fixed-width types, and for tuples. -+ * -+ * Even when dealing with tuples, @ordered_offsets_up_to is an element index, -+ * rather than an index into the frame offsets. */ - gsize ordered_offsets_up_to; - } GVariantSerialised; - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index 8ebbaa662..5f6eb63ee 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -5953,6 +5953,7 @@ g_variant_byteswap (GVariant *value) - serialised.size = g_variant_get_size (trusted); - serialised.data = g_malloc (serialised.size); - serialised.depth = g_variant_get_depth (trusted); -+ serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */ - g_variant_store (trusted, serialised.data); - g_variant_unref (trusted); - -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index 7e5664e65..9ed56d66d 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -1,6 +1,7 @@ - /* - * Copyright © 2010 Codethink Limited - * Copyright © 2020 William Manley -+ * Copyright © 2022 Endless OS Foundation, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -1447,6 +1448,7 @@ test_maybe (void) - serialised.data = flavoured_malloc (needed_size, flavour); - serialised.size = needed_size; - serialised.depth = 0; -+ serialised.ordered_offsets_up_to = 0; - - g_variant_serialiser_serialise (serialised, - random_instance_filler, -@@ -1570,6 +1572,7 @@ test_array (void) - serialised.data = flavoured_malloc (needed_size, flavour); - serialised.size = needed_size; - serialised.depth = 0; -+ serialised.ordered_offsets_up_to = 0; - - g_variant_serialiser_serialise (serialised, random_instance_filler, - (gpointer *) instances, n_children); -@@ -1734,6 +1737,7 @@ test_tuple (void) - serialised.data = flavoured_malloc (needed_size, flavour); - serialised.size = needed_size; - serialised.depth = 0; -+ serialised.ordered_offsets_up_to = 0; - - g_variant_serialiser_serialise (serialised, random_instance_filler, - (gpointer *) instances, n_children); -@@ -1830,6 +1834,7 @@ test_variant (void) - serialised.data = flavoured_malloc (needed_size, flavour); - serialised.size = needed_size; - serialised.depth = 0; -+ serialised.ordered_offsets_up_to = 0; - - g_variant_serialiser_serialise (serialised, random_instance_filler, - (gpointer *) &instance, 1); -@@ -5090,6 +5095,176 @@ test_normal_checking_tuple_offsets (void) - g_variant_unref (variant); - } - -+/* This is a regression test that we can't have non-normal values that take up -+ * significantly more space than the normal equivalent, by specifying the -+ * offset table entries so that tuple elements overlap. -+ * -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_838503 and -+ * https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_838513 */ -+static void -+test_normal_checking_tuple_offsets2 (void) -+{ -+ const GVariantType *data_type = G_VARIANT_TYPE ("(yyaiyyaiyy)"); -+ const guint8 data[] = { -+ 0x12, 0x34, 0x56, 0x78, 0x01, -+ /* -+ ^───────────────────┘ -+ -+ ^^^^^^^^^^ 1st yy -+ ^^^^^^^^^^ 2nd yy -+ ^^^^^^^^^^ 3rd yy -+ ^^^^ Framing offsets -+ */ -+ -+ /* If this variant was encoded normally, it would be something like this: -+ * 0x12, 0x34, pad, pad, [array bytes], 0x56, 0x78, pad, pad, [array bytes], 0x9A, 0xBC, 0xXX -+ * ^─────────────────────────────────────────────────────┘ -+ * -+ * ^^^^^^^^^^ 1st yy -+ * ^^^^^^^^^^ 2nd yy -+ * ^^^^^^^^^^ 3rd yy -+ * ^^^^ Framing offsets -+ */ -+ }; -+ gsize size = sizeof (data); -+ GVariant *variant = NULL; -+ GVariant *normal_variant = NULL; -+ GVariant *expected = NULL; -+ -+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); -+ g_assert_nonnull (variant); -+ -+ normal_variant = g_variant_get_normal_form (variant); -+ g_assert_nonnull (normal_variant); -+ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3); -+ -+ expected = g_variant_new_parsed ( -+ "@(yyaiyyaiyy) (0x12, 0x34, [], 0x00, 0x00, [], 0x00, 0x00)"); -+ g_assert_cmpvariant (expected, variant); -+ g_assert_cmpvariant (expected, normal_variant); -+ -+ g_variant_unref (expected); -+ g_variant_unref (normal_variant); -+ g_variant_unref (variant); -+} -+ -+/* This is a regression test that overlapping entries in the offset table are -+ * decoded consistently, even though they’re non-normal. -+ * -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_910935 */ -+static void -+test_normal_checking_tuple_offsets3 (void) -+{ -+ /* The expected decoding of this non-normal byte stream is complex. See -+ * section 2.7.3 (Handling Non-Normal Serialised Data) of the GVariant -+ * specification. -+ * -+ * The rule “Child Values Overlapping Framing Offsets” from the specification -+ * says that the first `ay` must be decoded as `[0x01]` even though it -+ * overlaps the first byte of the offset table. However, since commit -+ * 7eedcd76f7d5b8c98fa60013e1fe6e960bf19df3, GLib explicitly doesn’t allow -+ * this as it’s exploitable. So the first `ay` must be given a default value. -+ * -+ * The second and third `ay`s must be given default values because of rule -+ * “End Boundary Precedes Start Boundary”. -+ * -+ * The `i` must be given a default value because of rule “Start or End -+ * Boundary of a Child Falls Outside the Container”. -+ */ -+ const GVariantType *data_type = G_VARIANT_TYPE ("(ayayiay)"); -+ const guint8 data[] = { -+ 0x01, 0x00, 0x02, -+ /* -+ ^──┘ -+ -+ ^^^^^^^^^^ 1st ay, bytes 0-2 (but given a default value anyway, see above) -+ 2nd ay, bytes 2-0 -+ i, bytes 0-4 -+ 3rd ay, bytes 4-1 -+ ^^^^^^^^^^ Framing offsets -+ */ -+ }; -+ gsize size = sizeof (data); -+ GVariant *variant = NULL; -+ GVariant *normal_variant = NULL; -+ GVariant *expected = NULL; -+ -+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); -+ g_assert_nonnull (variant); -+ -+ g_assert_false (g_variant_is_normal_form (variant)); -+ -+ normal_variant = g_variant_get_normal_form (variant); -+ g_assert_nonnull (normal_variant); -+ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3); -+ -+ expected = g_variant_new_parsed ("@(ayayiay) ([], [], 0, [])"); -+ g_assert_cmpvariant (expected, variant); -+ g_assert_cmpvariant (expected, normal_variant); -+ -+ g_variant_unref (expected); -+ g_variant_unref (normal_variant); -+ g_variant_unref (variant); -+} -+ -+/* This is a regression test that overlapping entries in the offset table are -+ * decoded consistently, even though they’re non-normal. -+ * -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_910935 */ -+static void -+test_normal_checking_tuple_offsets4 (void) -+{ -+ /* The expected decoding of this non-normal byte stream is complex. See -+ * section 2.7.3 (Handling Non-Normal Serialised Data) of the GVariant -+ * specification. -+ * -+ * The rule “Child Values Overlapping Framing Offsets” from the specification -+ * says that the first `ay` must be decoded as `[0x01]` even though it -+ * overlaps the first byte of the offset table. However, since commit -+ * 7eedcd76f7d5b8c98fa60013e1fe6e960bf19df3, GLib explicitly doesn’t allow -+ * this as it’s exploitable. So the first `ay` must be given a default value. -+ * -+ * The second `ay` must be given a default value because of rule “End Boundary -+ * Precedes Start Boundary”. -+ * -+ * The third `ay` must be given a default value because its framing offsets -+ * overlap that of the first `ay`. -+ */ -+ const GVariantType *data_type = G_VARIANT_TYPE ("(ayayay)"); -+ const guint8 data[] = { -+ 0x01, 0x00, 0x02, -+ /* -+ ^──┘ -+ -+ ^^^^^^^^^^ 1st ay, bytes 0-2 (but given a default value anyway, see above) -+ 2nd ay, bytes 2-0 -+ 3rd ay, bytes 0-1 -+ ^^^^^^^^^^ Framing offsets -+ */ -+ }; -+ gsize size = sizeof (data); -+ GVariant *variant = NULL; -+ GVariant *normal_variant = NULL; -+ GVariant *expected = NULL; -+ -+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); -+ g_assert_nonnull (variant); -+ -+ g_assert_false (g_variant_is_normal_form (variant)); -+ -+ normal_variant = g_variant_get_normal_form (variant); -+ g_assert_nonnull (normal_variant); -+ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3); -+ -+ expected = g_variant_new_parsed ("@(ayayay) ([], [], [])"); -+ g_assert_cmpvariant (expected, variant); -+ g_assert_cmpvariant (expected, normal_variant); -+ -+ g_variant_unref (expected); -+ g_variant_unref (normal_variant); -+ g_variant_unref (variant); -+} -+ - /* Test that an empty object path is normalised successfully to the base object - * path, ‘/’. */ - static void -@@ -5237,6 +5412,12 @@ main (int argc, char **argv) - test_normal_checking_array_offsets2); - g_test_add_func ("/gvariant/normal-checking/tuple-offsets", - test_normal_checking_tuple_offsets); -+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets2", -+ test_normal_checking_tuple_offsets2); -+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets3", -+ test_normal_checking_tuple_offsets3); -+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets4", -+ test_normal_checking_tuple_offsets4); - g_test_add_func ("/gvariant/normal-checking/empty-object-path", - test_normal_checking_empty_object_path); - --- -2.40.0 - -From 98d5b84c2cdff1431084909b47d1a7f6d0dd60b5 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 7 Jan 2022 16:42:14 +0000 -Subject: [PATCH 08/19] =?UTF-8?q?gvariant:=20Don=E2=80=99t=20allow=20child?= - =?UTF-8?q?=20elements=20of=20a=20tuple=20to=20overlap=20each=20other?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is similar to the earlier commit which prevents child elements of a -variable-sized array from overlapping each other, but this time for -tuples. It is based heavily on ideas by William Manley. - -Tuples are slightly different from variable-sized arrays in that they -contain a mixture of fixed and variable sized elements. All but one of -the variable sized elements have an entry in the frame offsets table. -This means that if we were to just check the ordering of the frame -offsets table, the variable sized elements could still overlap -interleaving fixed sized elements, which would be bad. - -Therefore we have to check the elements rather than the frame offsets. - -The logic of checking the elements up to the index currently being -requested, and caching the result in `ordered_offsets_up_to`, means that -the algorithmic cost implications are the same for this commit as for -variable-sized arrays: an O(N) cost for these checks is amortised out -over N accesses to O(1) per access. - -Signed-off-by: Philip Withnall - -Fixes: #2121 ---- - glib/gvariant-core.c | 2 ++ - glib/tests/gvariant.c | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c -index 9b268d977..c6c50a6ff 100644 ---- a/glib/gvariant-core.c -+++ b/glib/gvariant-core.c -@@ -3,6 +3,8 @@ - * Copyright © 2010 Codethink Limited - * Copyright © 2022 Endless OS Foundation, LLC - * -+ * SPDX-License-Identifier: LGPL-2.1-or-later -+ * - * 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 -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index 9ed56d66d..a565ea69a 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -3,6 +3,8 @@ - * Copyright © 2020 William Manley - * Copyright © 2022 Endless OS Foundation, LLC - * -+ * SPDX-License-Identifier: LGPL-2.1-or-later -+ * - * 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 --- -2.40.0 - -From b53b26c5596a57d06bcc3947b9c8316526d9e70b Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Tue, 25 Oct 2022 15:14:14 +0100 -Subject: [PATCH 09/19] gvariant: Track checked and ordered offsets - independently - -The past few commits introduced the concept of known-good offsets in the -offset table (which is used for variable-width arrays and tuples). -Good offsets are ones which are non-overlapping with all the previous -offsets in the table. - -If a bad offset is encountered when indexing into the array or tuple, -the cached known-good offset index will not be increased. In this way, -all child variants at and beyond the first bad offset can be returned as -default values rather than dereferencing potentially invalid data. - -In this case, there was no information about the fact that the indexes -between the highest known-good index and the requested one had been -checked already. That could lead to a pathological case where an offset -table with an invalid first offset is repeatedly checked in full when -trying to access higher-indexed children. - -Avoid that by storing the index of the highest checked offset in the -table, as well as the index of the highest good/ordered offset. - -Signed-off-by: Philip Withnall - -Helps: #2121 ---- - glib/gvariant-core.c | 28 ++++++++++++++++++++++++ - glib/gvariant-serialiser.c | 44 +++++++++++++++++++++++++++----------- - glib/gvariant-serialiser.h | 9 ++++++++ - glib/gvariant.c | 1 + - glib/tests/gvariant.c | 5 +++++ - 5 files changed, 75 insertions(+), 12 deletions(-) - -diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c -index c6c50a6ff..1efcf200f 100644 ---- a/glib/gvariant-core.c -+++ b/glib/gvariant-core.c -@@ -69,6 +69,7 @@ struct _GVariant - GBytes *bytes; - gconstpointer data; - gsize ordered_offsets_up_to; -+ gsize checked_offsets_up_to; - } serialised; - - struct -@@ -184,6 +185,24 @@ struct _GVariant - * This field is only relevant for arrays of non - * fixed width types and for tuples. - * -+ * .checked_offsets_up_to: Similarly to .ordered_offsets_up_to, this stores -+ * the index of the highest element, n, whose frame -+ * offsets (and all the preceding frame offsets) -+ * have been checked for validity. -+ * -+ * It is always the case that -+ * .checked_offsets_up_to ≥ .ordered_offsets_up_to. -+ * -+ * If .checked_offsets_up_to == .ordered_offsets_up_to, -+ * then a bad offset has not been found so far. -+ * -+ * If .checked_offsets_up_to > .ordered_offsets_up_to, -+ * then a bad offset has been found at -+ * (.ordered_offsets_up_to + 1). -+ * -+ * This field is only relevant for arrays of non -+ * fixed width types and for tuples. -+ * - * .tree: Only valid when the instance is in tree form. - * - * Note that accesses from other threads could result in -@@ -388,6 +407,7 @@ g_variant_to_serialised (GVariant *value) - value->size, - value->depth, - value->contents.serialised.ordered_offsets_up_to, -+ value->contents.serialised.checked_offsets_up_to, - }; - return serialised; - } -@@ -420,6 +440,7 @@ g_variant_serialise (GVariant *value, - serialised.data = data; - serialised.depth = value->depth; - serialised.ordered_offsets_up_to = 0; -+ serialised.checked_offsets_up_to = 0; - - children = (gpointer *) value->contents.tree.children; - n_children = value->contents.tree.n_children; -@@ -466,10 +487,12 @@ g_variant_fill_gvs (GVariantSerialised *serialised, - if (value->state & STATE_SERIALISED) - { - serialised->ordered_offsets_up_to = value->contents.serialised.ordered_offsets_up_to; -+ serialised->checked_offsets_up_to = value->contents.serialised.checked_offsets_up_to; - } - else - { - serialised->ordered_offsets_up_to = 0; -+ serialised->checked_offsets_up_to = 0; - } - - if (serialised->data) -@@ -515,6 +538,7 @@ g_variant_ensure_serialised (GVariant *value) - value->contents.serialised.data = g_bytes_get_data (bytes, NULL); - value->contents.serialised.bytes = bytes; - value->contents.serialised.ordered_offsets_up_to = G_MAXSIZE; -+ value->contents.serialised.checked_offsets_up_to = G_MAXSIZE; - value->state |= STATE_SERIALISED; - } - } -@@ -596,6 +620,7 @@ g_variant_new_from_bytes (const GVariantType *type, - serialised.data = (guchar *) g_bytes_get_data (bytes, &serialised.size); - serialised.depth = 0; - serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0; -+ serialised.checked_offsets_up_to = trusted ? G_MAXSIZE : 0; - - if (!g_variant_serialised_check (serialised)) - { -@@ -647,6 +672,7 @@ g_variant_new_from_bytes (const GVariantType *type, - } - - value->contents.serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0; -+ value->contents.serialised.checked_offsets_up_to = trusted ? G_MAXSIZE : 0; - - g_clear_pointer (&owned_bytes, g_bytes_unref); - -@@ -1144,6 +1170,7 @@ g_variant_get_child_value (GVariant *value, - - /* Update the cached ordered_offsets_up_to, since @serialised will be thrown away when this function exits */ - value->contents.serialised.ordered_offsets_up_to = MAX (value->contents.serialised.ordered_offsets_up_to, serialised.ordered_offsets_up_to); -+ value->contents.serialised.checked_offsets_up_to = MAX (value->contents.serialised.checked_offsets_up_to, serialised.checked_offsets_up_to); - - /* Check whether this would cause nesting too deep. If so, return a fake - * child. The only situation we expect this to happen in is with a variant, -@@ -1171,6 +1198,7 @@ g_variant_get_child_value (GVariant *value, - g_bytes_ref (value->contents.serialised.bytes); - child->contents.serialised.data = s_child.data; - child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to; -+ child->contents.serialised.checked_offsets_up_to = s_child.checked_offsets_up_to; - - return child; - } -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index 470e21919..8e01ab53e 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -120,6 +120,8 @@ - * - * @depth has no restrictions; the depth of a top-level serialised #GVariant is - * zero, and it increases for each level of nested child. -+ * -+ * @checked_offsets_up_to is always ≥ @ordered_offsets_up_to - */ - - /* < private > -@@ -147,6 +149,9 @@ g_variant_serialised_check (GVariantSerialised serialised) - !(serialised.size == 0 || serialised.data != NULL)) - return FALSE; - -+ if (serialised.ordered_offsets_up_to > serialised.checked_offsets_up_to) -+ return FALSE; -+ - /* Depending on the native alignment requirements of the machine, the - * compiler will insert either 3 or 7 padding bytes after the char. - * This will result in the sizeof() the struct being 12 or 16. -@@ -266,6 +271,7 @@ gvs_fixed_sized_maybe_get_child (GVariantSerialised value, - g_variant_type_info_ref (value.type_info); - value.depth++; - value.ordered_offsets_up_to = 0; -+ value.checked_offsets_up_to = 0; - - return value; - } -@@ -297,7 +303,7 @@ gvs_fixed_sized_maybe_serialise (GVariantSerialised value, - { - if (n_children) - { -- GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0 }; -+ GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0, 0 }; - - gvs_filler (&child, children[0]); - } -@@ -320,6 +326,7 @@ gvs_fixed_sized_maybe_is_normal (GVariantSerialised value) - value.type_info = g_variant_type_info_element (value.type_info); - value.depth++; - value.ordered_offsets_up_to = 0; -+ value.checked_offsets_up_to = 0; - - return g_variant_serialised_is_normal (value); - } -@@ -362,6 +369,7 @@ gvs_variable_sized_maybe_get_child (GVariantSerialised value, - - value.depth++; - value.ordered_offsets_up_to = 0; -+ value.checked_offsets_up_to = 0; - - return value; - } -@@ -392,7 +400,7 @@ gvs_variable_sized_maybe_serialise (GVariantSerialised value, - { - if (n_children) - { -- GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0 }; -+ GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0, 0 }; - - /* write the data for the child. */ - gvs_filler (&child, children[0]); -@@ -413,6 +421,7 @@ gvs_variable_sized_maybe_is_normal (GVariantSerialised value) - value.size--; - value.depth++; - value.ordered_offsets_up_to = 0; -+ value.checked_offsets_up_to = 0; - - return g_variant_serialised_is_normal (value); - } -@@ -739,39 +748,46 @@ gvs_variable_sized_array_get_child (GVariantSerialised value, - - /* If the requested @index_ is beyond the set of indices whose framing offsets - * have been checked, check the remaining offsets to see whether they’re -- * normal (in order, no overlapping array elements). */ -- if (index_ > value.ordered_offsets_up_to) -+ * normal (in order, no overlapping array elements). -+ * -+ * Don’t bother checking if the highest known-good offset is lower than the -+ * highest checked offset, as that means there’s an invalid element at that -+ * index, so there’s no need to check further. */ -+ if (index_ > value.checked_offsets_up_to && -+ value.ordered_offsets_up_to == value.checked_offsets_up_to) - { - switch (offsets.offset_size) - { - case 1: - { - value.ordered_offsets_up_to = find_unordered_guint8 ( -- offsets.array, value.ordered_offsets_up_to, index_ + 1); -+ offsets.array, value.checked_offsets_up_to, index_ + 1); - break; - } - case 2: - { - value.ordered_offsets_up_to = find_unordered_guint16 ( -- offsets.array, value.ordered_offsets_up_to, index_ + 1); -+ offsets.array, value.checked_offsets_up_to, index_ + 1); - break; - } - case 4: - { - value.ordered_offsets_up_to = find_unordered_guint32 ( -- offsets.array, value.ordered_offsets_up_to, index_ + 1); -+ offsets.array, value.checked_offsets_up_to, index_ + 1); - break; - } - case 8: - { - value.ordered_offsets_up_to = find_unordered_guint64 ( -- offsets.array, value.ordered_offsets_up_to, index_ + 1); -+ offsets.array, value.checked_offsets_up_to, index_ + 1); - break; - } - default: - /* gvs_get_offset_size() only returns maximum 8 */ - g_assert_not_reached (); - } -+ -+ value.checked_offsets_up_to = index_; - } - - if (index_ > value.ordered_offsets_up_to) -@@ -916,6 +932,7 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value) - - /* All offsets have now been checked. */ - value.ordered_offsets_up_to = G_MAXSIZE; -+ value.checked_offsets_up_to = G_MAXSIZE; - - return TRUE; - } -@@ -1040,14 +1057,15 @@ gvs_tuple_get_child (GVariantSerialised value, - * all the tuple *elements* here, not just all the framing offsets, since - * tuples contain a mix of elements which use framing offsets and ones which - * don’t. None of them are allowed to overlap. */ -- if (index_ > value.ordered_offsets_up_to) -+ if (index_ > value.checked_offsets_up_to && -+ value.ordered_offsets_up_to == value.checked_offsets_up_to) - { - gsize i, prev_i_end = 0; - -- if (value.ordered_offsets_up_to > 0) -- gvs_tuple_get_member_bounds (value, value.ordered_offsets_up_to - 1, offset_size, NULL, &prev_i_end); -+ if (value.checked_offsets_up_to > 0) -+ gvs_tuple_get_member_bounds (value, value.checked_offsets_up_to - 1, offset_size, NULL, &prev_i_end); - -- for (i = value.ordered_offsets_up_to; i <= index_; i++) -+ for (i = value.checked_offsets_up_to; i <= index_; i++) - { - gsize i_start, i_end; - -@@ -1060,6 +1078,7 @@ gvs_tuple_get_child (GVariantSerialised value, - } - - value.ordered_offsets_up_to = i - 1; -+ value.checked_offsets_up_to = index_; - } - - if (index_ > value.ordered_offsets_up_to) -@@ -1257,6 +1276,7 @@ gvs_tuple_is_normal (GVariantSerialised value) - - /* All element bounds have been checked above. */ - value.ordered_offsets_up_to = G_MAXSIZE; -+ value.checked_offsets_up_to = G_MAXSIZE; - - { - gsize fixed_size; -diff --git a/glib/gvariant-serialiser.h b/glib/gvariant-serialiser.h -index 765bd43b9..113df2ccc 100644 ---- a/glib/gvariant-serialiser.h -+++ b/glib/gvariant-serialiser.h -@@ -41,6 +41,15 @@ typedef struct - * Even when dealing with tuples, @ordered_offsets_up_to is an element index, - * rather than an index into the frame offsets. */ - gsize ordered_offsets_up_to; -+ -+ /* Similar to @ordered_offsets_up_to. This gives the index of the child element -+ * whose frame offset is the highest in the offset table which has been -+ * checked so far. -+ * -+ * This is always ≥ @ordered_offsets_up_to. It is always an element index. -+ * -+ * See documentation in gvariant-core.c for `struct GVariant` for details. */ -+ gsize checked_offsets_up_to; - } GVariantSerialised; - - /* deserialisation */ -diff --git a/glib/gvariant.c b/glib/gvariant.c -index 5f6eb63ee..3e1adffaa 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -5954,6 +5954,7 @@ g_variant_byteswap (GVariant *value) - serialised.data = g_malloc (serialised.size); - serialised.depth = g_variant_get_depth (trusted); - serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */ -+ serialised.checked_offsets_up_to = G_MAXSIZE; - g_variant_store (trusted, serialised.data); - g_variant_unref (trusted); - -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index a565ea69a..a13655eef 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -1284,6 +1284,7 @@ random_instance_filler (GVariantSerialised *serialised, - - serialised->depth = 0; - serialised->ordered_offsets_up_to = 0; -+ serialised->checked_offsets_up_to = 0; - - g_assert_true (serialised->type_info == instance->type_info); - g_assert_cmpuint (serialised->size, ==, instance->size); -@@ -1451,6 +1452,7 @@ test_maybe (void) - serialised.size = needed_size; - serialised.depth = 0; - serialised.ordered_offsets_up_to = 0; -+ serialised.checked_offsets_up_to = 0; - - g_variant_serialiser_serialise (serialised, - random_instance_filler, -@@ -1575,6 +1577,7 @@ test_array (void) - serialised.size = needed_size; - serialised.depth = 0; - serialised.ordered_offsets_up_to = 0; -+ serialised.checked_offsets_up_to = 0; - - g_variant_serialiser_serialise (serialised, random_instance_filler, - (gpointer *) instances, n_children); -@@ -1740,6 +1743,7 @@ test_tuple (void) - serialised.size = needed_size; - serialised.depth = 0; - serialised.ordered_offsets_up_to = 0; -+ serialised.checked_offsets_up_to = 0; - - g_variant_serialiser_serialise (serialised, random_instance_filler, - (gpointer *) instances, n_children); -@@ -1837,6 +1841,7 @@ test_variant (void) - serialised.size = needed_size; - serialised.depth = 0; - serialised.ordered_offsets_up_to = 0; -+ serialised.checked_offsets_up_to = 0; - - g_variant_serialiser_serialise (serialised, random_instance_filler, - (gpointer *) &instance, 1); --- -2.40.0 - -From 319f859c4ad021f636df67d61fa674afdd10d3c2 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 12 Jun 2020 18:01:13 +0100 -Subject: [PATCH 10/19] tests: Add another test for overlapping offsets in - GVariant - -Signed-off-by: Philip Withnall - -Helps: #2121 ---- - glib/tests/gvariant.c | 34 ++++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index a13655eef..965aa98af 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -5013,6 +5013,38 @@ test_recursion_limits_array_in_variant (void) - g_variant_unref (wrapper_variant); - } - -+/* Test that a nested array with invalid values in its offset table (which point -+ * from the inner to the outer array) is normalised successfully without -+ * looping infinitely. */ -+static void -+test_normal_checking_array_offsets_overlapped (void) -+{ -+ const guint8 data[] = { -+ 0x01, 0x00, -+ }; -+ gsize size = sizeof (data); -+ GVariant *variant = NULL; -+ GVariant *normal_variant = NULL; -+ GVariant *expected_variant = NULL; -+ -+ variant = g_variant_new_from_data (G_VARIANT_TYPE ("aay"), data, size, -+ FALSE, NULL, NULL); -+ g_assert_nonnull (variant); -+ -+ normal_variant = g_variant_get_normal_form (variant); -+ g_assert_nonnull (normal_variant); -+ -+ expected_variant = g_variant_new_parsed ("[@ay [], []]"); -+ g_assert_cmpvariant (normal_variant, expected_variant); -+ -+ g_assert_cmpmem (g_variant_get_data (normal_variant), g_variant_get_size (normal_variant), -+ g_variant_get_data (expected_variant), g_variant_get_size (expected_variant)); -+ -+ g_variant_unref (expected_variant); -+ g_variant_unref (normal_variant); -+ g_variant_unref (variant); -+} -+ - /* Test that an array with invalidly large values in its offset table is - * normalised successfully without looping infinitely. */ - static void -@@ -5413,6 +5445,8 @@ main (int argc, char **argv) - - g_test_add_func ("/gvariant/normal-checking/tuples", - test_normal_checking_tuples); -+ g_test_add_func ("/gvariant/normal-checking/array-offsets/overlapped", -+ test_normal_checking_array_offsets_overlapped); - g_test_add_func ("/gvariant/normal-checking/array-offsets", - test_normal_checking_array_offsets); - g_test_add_func ("/gvariant/normal-checking/array-offsets2", --- -2.40.0 - -From 24ac75fab0b869fbf7e2cb970974ba59bc1a8a10 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Mon, 24 Oct 2022 16:43:23 +0100 -Subject: [PATCH 11/19] tests: Disable some random instance tests of GVariants -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Building a `GVariant` using entirely random data may result in a -non-normally-formed `GVariant`. It’s always possible to read these -`GVariant`s, but the API might return default values for some or all of -their components. - -In particular, this can easily happen when randomly generating the -offset tables for non-fixed-width container types. - -If it does happen, bytewise comparison of the parsed `GVariant` with the -original bytes will not always match. So skip those checks. - -Signed-off-by: Philip Withnall - -Helps: #2121 ---- - glib/tests/gvariant.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index 965aa98af..f3b975652 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -1231,6 +1231,7 @@ random_instance_assert (RandomInstance *instance, - GRand *rand; - gsize i; - -+ g_assert_true (size == 0 || buffer != NULL); - g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0); - g_assert_cmpint (size, ==, instance->size); - -@@ -1457,10 +1458,13 @@ test_maybe (void) - g_variant_serialiser_serialise (serialised, - random_instance_filler, - (gpointer *) &instance, 1); -+ - child = g_variant_serialised_get_child (serialised, 0); - g_assert_true (child.type_info == instance->type_info); -- random_instance_assert (instance, child.data, child.size); -+ if (child.data != NULL) /* could be NULL if element is non-normal */ -+ random_instance_assert (instance, child.data, child.size); - g_variant_type_info_unref (child.type_info); -+ - flavoured_free (serialised.data, flavour); - } - } -@@ -1593,7 +1597,8 @@ test_array (void) - - child = g_variant_serialised_get_child (serialised, i); - g_assert_true (child.type_info == instances[i]->type_info); -- random_instance_assert (instances[i], child.data, child.size); -+ if (child.data != NULL) /* could be NULL if element is non-normal */ -+ random_instance_assert (instances[i], child.data, child.size); - g_variant_type_info_unref (child.type_info); - } - -@@ -1759,7 +1764,8 @@ test_tuple (void) - - child = g_variant_serialised_get_child (serialised, i); - g_assert_true (child.type_info == instances[i]->type_info); -- random_instance_assert (instances[i], child.data, child.size); -+ if (child.data != NULL) /* could be NULL if element is non-normal */ -+ random_instance_assert (instances[i], child.data, child.size); - g_variant_type_info_unref (child.type_info); - } - --- -2.40.0 - -From 88bbf60b61e4aada5b8ebd7deb91fff1f25e60c2 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Mon, 24 Oct 2022 18:14:57 +0100 -Subject: [PATCH 12/19] gvariant: Clarify the docs for - g_variant_get_normal_form() - -Document how non-normal parts of the `GVariant` are handled. - -Signed-off-by: Philip Withnall ---- - glib/gvariant.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index 3e1adffaa..2a6aaa1f4 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -5879,7 +5879,9 @@ g_variant_deep_copy (GVariant *value) - * marked as trusted and a new reference to it is returned. - * - * If @value is found not to be in normal form then a new trusted -- * #GVariant is created with the same value as @value. -+ * #GVariant is created with the same value as @value. The non-normal parts of -+ * @value will be replaced with default values which are guaranteed to be in -+ * normal form. - * - * It makes sense to call this function if you've received #GVariant - * data from untrusted sources and you want to ensure your serialised --- -2.40.0 - -From 2f3b16d3439e4843718428c21aaedd1ecba868d7 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Mon, 24 Oct 2022 18:43:55 +0100 -Subject: [PATCH 13/19] gvariant: Port g_variant_deep_copy() to count its - iterations directly - -This is equivalent to what `GVariantIter` does, but it means that -`g_variant_deep_copy()` is making its own `g_variant_get_child_value()` -calls. - -This will be useful in an upcoming commit, where those child values will -be inspected a little more deeply. - -Signed-off-by: Philip Withnall - -Helps: #2121 ---- - glib/gvariant.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index 2a6aaa1f4..40d3639bc 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -5806,14 +5806,13 @@ g_variant_deep_copy (GVariant *value) - case G_VARIANT_CLASS_VARIANT: - { - GVariantBuilder builder; -- GVariantIter iter; -- GVariant *child; -+ gsize i, n_children; - - g_variant_builder_init (&builder, g_variant_get_type (value)); -- g_variant_iter_init (&iter, value); - -- while ((child = g_variant_iter_next_value (&iter))) -+ for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++) - { -+ GVariant *child = g_variant_get_child_value (value, i); - g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); - g_variant_unref (child); - } --- -2.40.0 - -From 81567d2bd81f303061b93be34da96ef2e2b11693 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Tue, 25 Oct 2022 13:03:22 +0100 -Subject: [PATCH 14/19] gvariant: Add internal - g_variant_maybe_get_child_value() - -This will be used in a following commit. - -Signed-off-by: Philip Withnall - -Helps: #2540 ---- - glib/gvariant-core.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ - glib/gvariant-core.h | 3 ++ - 2 files changed, 71 insertions(+) - -diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c -index 1efcf200f..dbcf60f69 100644 ---- a/glib/gvariant-core.c -+++ b/glib/gvariant-core.c -@@ -1204,6 +1204,74 @@ g_variant_get_child_value (GVariant *value, - } - } - -+/** -+ * g_variant_maybe_get_child_value: -+ * @value: a container #GVariant -+ * @index_: the index of the child to fetch -+ * -+ * Reads a child item out of a container #GVariant instance, if it is in normal -+ * form. If it is not in normal form, return %NULL. -+ * -+ * This function behaves the same as g_variant_get_child_value(), except that it -+ * returns %NULL if the child is not in normal form. g_variant_get_child_value() -+ * would instead return a new default value of the correct type. -+ * -+ * This is intended to be used internally to avoid unnecessary #GVariant -+ * allocations. -+ * -+ * The returned value is never floating. You should free it with -+ * g_variant_unref() when you're done with it. -+ * -+ * This function is O(1). -+ * -+ * Returns: (transfer full): the child at the specified index -+ * -+ * Since: 2.74 -+ */ -+GVariant * -+g_variant_maybe_get_child_value (GVariant *value, -+ gsize index_) -+{ -+ g_return_val_if_fail (index_ < g_variant_n_children (value), NULL); -+ g_return_val_if_fail (value->depth < G_MAXSIZE, NULL); -+ -+ if (~g_atomic_int_get (&value->state) & STATE_SERIALISED) -+ { -+ g_variant_lock (value); -+ -+ if (~value->state & STATE_SERIALISED) -+ { -+ GVariant *child; -+ -+ child = g_variant_ref (value->contents.tree.children[index_]); -+ g_variant_unlock (value); -+ -+ return child; -+ } -+ -+ g_variant_unlock (value); -+ } -+ -+ { -+ GVariantSerialised serialised = g_variant_to_serialised (value); -+ GVariantSerialised s_child; -+ -+ /* get the serializer to extract the serialized data for the child -+ * from the serialized data for the container -+ */ -+ s_child = g_variant_serialised_get_child (serialised, index_); -+ -+ if (!(value->state & STATE_TRUSTED) && s_child.data == NULL) -+ { -+ g_variant_type_info_unref (s_child.type_info); -+ return NULL; -+ } -+ -+ g_variant_type_info_unref (s_child.type_info); -+ return g_variant_get_child_value (value, index_); -+ } -+} -+ - /** - * g_variant_store: - * @value: the #GVariant to store -diff --git a/glib/gvariant-core.h b/glib/gvariant-core.h -index fc04711ac..947a98ca0 100644 ---- a/glib/gvariant-core.h -+++ b/glib/gvariant-core.h -@@ -36,4 +36,7 @@ GVariantTypeInfo * g_variant_get_type_info (GVarian - - gsize g_variant_get_depth (GVariant *value); - -+GVariant * g_variant_maybe_get_child_value (GVariant *value, -+ gsize index_); -+ - #endif /* __G_VARIANT_CORE_H__ */ --- -2.40.0 - -From 2db1a61cabfc4919277f004c411c753bcfa71235 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Tue, 25 Oct 2022 13:03:45 +0100 -Subject: [PATCH 15/19] gvariant: Cut allocs of default values for children of - non-normal arrays -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This improves a slow case in `g_variant_get_normal_form()` where -allocating many identical default values for the children of a -variable-sized array which has a malformed offset table would take a lot -of time. - -The fix is to make all child values after the first invalid one be -references to the default value emitted for the first invalid one, -rather than identical new `GVariant`s. - -In particular, this fixes a case where an attacker could create an array -of length L of very large tuples of size T each, corrupt the offset table -so they don’t have to specify the array content, and then induce -`g_variant_get_normal_form()` into allocating L×T default values from an -input which is significantly smaller than L×T in length. - -A pre-existing workaround for this issue is for code to call -`g_variant_is_normal_form()` before calling -`g_variant_get_normal_form()`, and to skip the latter call if the former -returns false. This commit improves the behaviour in the case that -`g_variant_get_normal_form()` is called anyway. - -This fix changes the time to run the `fuzz_variant_binary` test on the -testcase from oss-fuzz#19777 from >60s (before being terminated) with -2.3GB of memory usage and 580k page faults; to 32s, 8.3MB of memory -usage and 1500 page faults (as measured by `time -v`). - -Signed-off-by: Philip Withnall - -Fixes: #2540 -oss-fuzz#19777 ---- - glib/gvariant.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 65 insertions(+), 1 deletion(-) - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index 40d3639bc..63c134839 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -5800,7 +5800,6 @@ g_variant_deep_copy (GVariant *value) - switch (g_variant_classify (value)) - { - case G_VARIANT_CLASS_MAYBE: -- case G_VARIANT_CLASS_ARRAY: - case G_VARIANT_CLASS_TUPLE: - case G_VARIANT_CLASS_DICT_ENTRY: - case G_VARIANT_CLASS_VARIANT: -@@ -5820,6 +5819,71 @@ g_variant_deep_copy (GVariant *value) - return g_variant_builder_end (&builder); - } - -+ case G_VARIANT_CLASS_ARRAY: -+ { -+ GVariantBuilder builder; -+ gsize i, n_children; -+ GVariant *first_invalid_child_deep_copy = NULL; -+ -+ /* Arrays are in theory treated the same as maybes, tuples, dict entries -+ * and variants, and could be another case in the above block of code. -+ * -+ * However, they have the property that when dealing with non-normal -+ * data (which is the only time g_variant_deep_copy() is currently -+ * called) in a variable-sized array, the code above can easily end up -+ * creating many default child values in order to return an array which -+ * is of the right length and type, but without containing non-normal -+ * data. This can happen if the offset table for the array is malformed. -+ * -+ * In this case, the code above would end up allocating the same default -+ * value for each one of the child indexes beyond the first malformed -+ * entry in the offset table. This can end up being a lot of identical -+ * allocations of default values, particularly if the non-normal array -+ * is crafted maliciously. -+ * -+ * Avoid that problem by returning a new reference to the same default -+ * value for every child after the first invalid one. This results in -+ * returning an equivalent array, in normal form and trusted — but with -+ * significantly fewer memory allocations. -+ * -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2540 */ -+ -+ g_variant_builder_init (&builder, g_variant_get_type (value)); -+ -+ for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++) -+ { -+ /* Try maybe_get_child_value() first; if it returns NULL, this child -+ * is non-normal. get_child_value() would have constructed and -+ * returned a default value in that case. */ -+ GVariant *child = g_variant_maybe_get_child_value (value, i); -+ -+ if (child != NULL) -+ { -+ /* Non-normal children may not always be contiguous, as they may -+ * be non-normal for reasons other than invalid offset table -+ * entries. As they are all the same type, they will all have -+ * the same default value though, so keep that around. */ -+ g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); -+ } -+ else if (child == NULL && first_invalid_child_deep_copy != NULL) -+ { -+ g_variant_builder_add_value (&builder, first_invalid_child_deep_copy); -+ } -+ else if (child == NULL) -+ { -+ child = g_variant_get_child_value (value, i); -+ first_invalid_child_deep_copy = g_variant_ref_sink (g_variant_deep_copy (child)); -+ g_variant_builder_add_value (&builder, first_invalid_child_deep_copy); -+ } -+ -+ g_clear_pointer (&child, g_variant_unref); -+ } -+ -+ g_clear_pointer (&first_invalid_child_deep_copy, g_variant_unref); -+ -+ return g_variant_builder_end (&builder); -+ } -+ - case G_VARIANT_CLASS_BOOLEAN: - return g_variant_new_boolean (g_variant_get_boolean (value)); - --- -2.40.0 - -From b4cfb50f42950b0f2f382865f23e9ff02ba05aa4 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Tue, 25 Oct 2022 18:03:56 +0100 -Subject: [PATCH 16/19] gvariant: Fix a leak of a GVariantTypeInfo on an error - handling path - -Signed-off-by: Philip Withnall ---- - glib/gvariant-core.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c -index dbcf60f69..2d2508244 100644 ---- a/glib/gvariant-core.c -+++ b/glib/gvariant-core.c -@@ -1183,6 +1183,7 @@ g_variant_get_child_value (GVariant *value, - G_VARIANT_MAX_RECURSION_DEPTH - value->depth) - { - g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_VARIANT)); -+ g_variant_type_info_unref (s_child.type_info); - return g_variant_new_tuple (NULL, 0); - } - --- -2.40.0 - -From 6dd5afa8a0daf574210ea21f1536f69960c0d007 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 27 Oct 2022 12:00:04 +0100 -Subject: [PATCH 17/19] gvariant-serialiser: Check offset table entry size is - minimal - -The entries in an offset table (which is used for variable sized arrays -and tuples containing variable sized members) are sized so that they can -address every byte in the overall variant. - -The specification requires that for a variant to be in normal form, its -offset table entries must be the minimum width such that they can -address every byte in the variant. - -That minimality requirement was not checked in -`g_variant_is_normal_form()`, leading to two different byte arrays being -interpreted as the normal form of a given variant tree. That kind of -confusion could potentially be exploited, and is certainly a bug. - -Fix it by adding the necessary checks on offset table entry width, and -unit tests. - -Spotted by William Manley. - -Signed-off-by: Philip Withnall - -Fixes: #2794 ---- - glib/gvariant-serialiser.c | 19 +++- - glib/tests/gvariant.c | 176 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 194 insertions(+), 1 deletion(-) - -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index 8e01ab53e..a6141f7d0 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -694,6 +694,10 @@ gvs_variable_sized_array_get_frame_offsets (GVariantSerialised value) - out.data_size = last_end; - out.array = value.data + last_end; - out.length = offsets_array_size / out.offset_size; -+ -+ if (out.length > 0 && gvs_calculate_total_size (last_end, out.length) != value.size) -+ return out; /* offset size not minimal */ -+ - out.is_normal = TRUE; - - return out; -@@ -1201,6 +1205,7 @@ gvs_tuple_is_normal (GVariantSerialised value) - gsize length; - gsize offset; - gsize i; -+ gsize offset_table_size; - - /* as per the comment in gvs_tuple_get_child() */ - if G_UNLIKELY (value.data == NULL && value.size != 0) -@@ -1305,7 +1310,19 @@ gvs_tuple_is_normal (GVariantSerialised value) - } - } - -- return offset_ptr == offset; -+ /* @offset_ptr has been counting backwards from the end of the variant, to -+ * find the beginning of the offset table. @offset has been counting forwards -+ * from the beginning of the variant to find the end of the data. They should -+ * have met in the middle. */ -+ if (offset_ptr != offset) -+ return FALSE; -+ -+ offset_table_size = value.size - offset_ptr; -+ if (value.size > 0 && -+ gvs_calculate_total_size (offset, offset_table_size / offset_size) != value.size) -+ return FALSE; /* offset size not minimal */ -+ -+ return TRUE; - } - - /* Variants {{{2 -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index f3b975652..028543833 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -5116,6 +5116,86 @@ test_normal_checking_array_offsets2 (void) - g_variant_unref (variant); - } - -+/* Test that an otherwise-valid serialised GVariant is considered non-normal if -+ * its offset table entries are too wide. -+ * -+ * See §2.3.6 (Framing Offsets) of the GVariant specification. */ -+static void -+test_normal_checking_array_offsets_minimal_sized (void) -+{ -+ GVariantBuilder builder; -+ gsize i; -+ GVariant *aay_constructed = NULL; -+ const guint8 *data = NULL; -+ guint8 *data_owned = NULL; -+ GVariant *aay_deserialised = NULL; -+ GVariant *aay_normalised = NULL; -+ -+ /* Construct an array of type aay, consisting of 128 elements which are each -+ * an empty array, i.e. `[[] * 128]`. This is chosen because the inner -+ * elements are variable sized (making the outer array variable sized, so it -+ * must have an offset table), but they are also zero-sized when serialised. -+ * So the serialised representation of @aay_constructed consists entirely of -+ * its offset table, which is entirely zeroes. -+ * -+ * The array is chosen to be 128 elements long because that means offset -+ * table entries which are 1 byte long. If the elements in the array were -+ * non-zero-sized (to the extent that the overall array is ≥256 bytes long), -+ * the offset table entries would end up being 2 bytes long. */ -+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay")); -+ -+ for (i = 0; i < 128; i++) -+ g_variant_builder_add_value (&builder, g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0)); -+ -+ aay_constructed = g_variant_builder_end (&builder); -+ -+ /* Verify that the constructed array is in normal form, and its serialised -+ * form is `b'\0' * 128`. */ -+ g_assert_true (g_variant_is_normal_form (aay_constructed)); -+ g_assert_cmpuint (g_variant_n_children (aay_constructed), ==, 128); -+ g_assert_cmpuint (g_variant_get_size (aay_constructed), ==, 128); -+ -+ data = g_variant_get_data (aay_constructed); -+ for (i = 0; i < g_variant_get_size (aay_constructed); i++) -+ g_assert_cmpuint (data[i], ==, 0); -+ -+ /* Construct a serialised `aay` GVariant which is `b'\0' * 256`. This has to -+ * be a non-normal form of `[[] * 128]`, with 2-byte-long offset table -+ * entries, because each offset table entry has to be able to reference all of -+ * the byte boundaries in the container. All the entries in the offset table -+ * are zero, so all the elements of the array are zero-sized. */ -+ data = data_owned = g_malloc0 (256); -+ aay_deserialised = g_variant_new_from_data (G_VARIANT_TYPE ("aay"), -+ data, -+ 256, -+ FALSE, -+ g_free, -+ g_steal_pointer (&data_owned)); -+ -+ g_assert_false (g_variant_is_normal_form (aay_deserialised)); -+ g_assert_cmpuint (g_variant_n_children (aay_deserialised), ==, 128); -+ g_assert_cmpuint (g_variant_get_size (aay_deserialised), ==, 256); -+ -+ data = g_variant_get_data (aay_deserialised); -+ for (i = 0; i < g_variant_get_size (aay_deserialised); i++) -+ g_assert_cmpuint (data[i], ==, 0); -+ -+ /* Get its normal form. That should change the serialised size. */ -+ aay_normalised = g_variant_get_normal_form (aay_deserialised); -+ -+ g_assert_true (g_variant_is_normal_form (aay_normalised)); -+ g_assert_cmpuint (g_variant_n_children (aay_normalised), ==, 128); -+ g_assert_cmpuint (g_variant_get_size (aay_normalised), ==, 128); -+ -+ data = g_variant_get_data (aay_normalised); -+ for (i = 0; i < g_variant_get_size (aay_normalised); i++) -+ g_assert_cmpuint (data[i], ==, 0); -+ -+ g_variant_unref (aay_normalised); -+ g_variant_unref (aay_deserialised); -+ g_variant_unref (aay_constructed); -+} -+ - /* Test that a tuple with invalidly large values in its offset table is - * normalised successfully without looping infinitely. */ - static void -@@ -5310,6 +5390,98 @@ test_normal_checking_tuple_offsets4 (void) - g_variant_unref (variant); - } - -+/* Test that an otherwise-valid serialised GVariant is considered non-normal if -+ * its offset table entries are too wide. -+ * -+ * See §2.3.6 (Framing Offsets) of the GVariant specification. */ -+static void -+test_normal_checking_tuple_offsets_minimal_sized (void) -+{ -+ GString *type_string = NULL; -+ GVariantBuilder builder; -+ gsize i; -+ GVariant *ray_constructed = NULL; -+ const guint8 *data = NULL; -+ guint8 *data_owned = NULL; -+ GVariant *ray_deserialised = NULL; -+ GVariant *ray_normalised = NULL; -+ -+ /* Construct a tuple of type (ay…ay), consisting of 129 members which are each -+ * an empty array, i.e. `([] * 129)`. This is chosen because the inner -+ * members are variable sized, so the outer tuple must have an offset table, -+ * but they are also zero-sized when serialised. So the serialised -+ * representation of @ray_constructed consists entirely of its offset table, -+ * which is entirely zeroes. -+ * -+ * The tuple is chosen to be 129 members long because that means it has 128 -+ * offset table entries which are 1 byte long each. If the members in the -+ * tuple were non-zero-sized (to the extent that the overall tuple is ≥256 -+ * bytes long), the offset table entries would end up being 2 bytes long. -+ * -+ * 129 members are used unlike 128 array elements in -+ * test_normal_checking_array_offsets_minimal_sized(), because the last member -+ * in a tuple never needs an offset table entry. */ -+ type_string = g_string_new (""); -+ g_string_append_c (type_string, '('); -+ for (i = 0; i < 129; i++) -+ g_string_append (type_string, "ay"); -+ g_string_append_c (type_string, ')'); -+ -+ g_variant_builder_init (&builder, G_VARIANT_TYPE (type_string->str)); -+ -+ for (i = 0; i < 129; i++) -+ g_variant_builder_add_value (&builder, g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0)); -+ -+ ray_constructed = g_variant_builder_end (&builder); -+ -+ /* Verify that the constructed tuple is in normal form, and its serialised -+ * form is `b'\0' * 128`. */ -+ g_assert_true (g_variant_is_normal_form (ray_constructed)); -+ g_assert_cmpuint (g_variant_n_children (ray_constructed), ==, 129); -+ g_assert_cmpuint (g_variant_get_size (ray_constructed), ==, 128); -+ -+ data = g_variant_get_data (ray_constructed); -+ for (i = 0; i < g_variant_get_size (ray_constructed); i++) -+ g_assert_cmpuint (data[i], ==, 0); -+ -+ /* Construct a serialised `(ay…ay)` GVariant which is `b'\0' * 256`. This has -+ * to be a non-normal form of `([] * 129)`, with 2-byte-long offset table -+ * entries, because each offset table entry has to be able to reference all of -+ * the byte boundaries in the container. All the entries in the offset table -+ * are zero, so all the members of the tuple are zero-sized. */ -+ data = data_owned = g_malloc0 (256); -+ ray_deserialised = g_variant_new_from_data (G_VARIANT_TYPE (type_string->str), -+ data, -+ 256, -+ FALSE, -+ g_free, -+ g_steal_pointer (&data_owned)); -+ -+ g_assert_false (g_variant_is_normal_form (ray_deserialised)); -+ g_assert_cmpuint (g_variant_n_children (ray_deserialised), ==, 129); -+ g_assert_cmpuint (g_variant_get_size (ray_deserialised), ==, 256); -+ -+ data = g_variant_get_data (ray_deserialised); -+ for (i = 0; i < g_variant_get_size (ray_deserialised); i++) -+ g_assert_cmpuint (data[i], ==, 0); -+ -+ /* Get its normal form. That should change the serialised size. */ -+ ray_normalised = g_variant_get_normal_form (ray_deserialised); -+ -+ g_assert_true (g_variant_is_normal_form (ray_normalised)); -+ g_assert_cmpuint (g_variant_n_children (ray_normalised), ==, 129); -+ g_assert_cmpuint (g_variant_get_size (ray_normalised), ==, 128); -+ -+ data = g_variant_get_data (ray_normalised); -+ for (i = 0; i < g_variant_get_size (ray_normalised); i++) -+ g_assert_cmpuint (data[i], ==, 0); -+ -+ g_variant_unref (ray_normalised); -+ g_variant_unref (ray_deserialised); -+ g_variant_unref (ray_constructed); -+ g_string_free (type_string, TRUE); -+} -+ - /* Test that an empty object path is normalised successfully to the base object - * path, ‘/’. */ - static void -@@ -5457,6 +5629,8 @@ main (int argc, char **argv) - test_normal_checking_array_offsets); - g_test_add_func ("/gvariant/normal-checking/array-offsets2", - test_normal_checking_array_offsets2); -+ g_test_add_func ("/gvariant/normal-checking/array-offsets/minimal-sized", -+ test_normal_checking_array_offsets_minimal_sized); - g_test_add_func ("/gvariant/normal-checking/tuple-offsets", - test_normal_checking_tuple_offsets); - g_test_add_func ("/gvariant/normal-checking/tuple-offsets2", -@@ -5465,6 +5639,8 @@ main (int argc, char **argv) - test_normal_checking_tuple_offsets3); - g_test_add_func ("/gvariant/normal-checking/tuple-offsets4", - test_normal_checking_tuple_offsets4); -+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized", -+ test_normal_checking_tuple_offsets_minimal_sized); - g_test_add_func ("/gvariant/normal-checking/empty-object-path", - test_normal_checking_empty_object_path); - --- -2.40.0 - -From 5ebfcae9b5e409cc2ad0c1e73175af2bdab455ac Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 27 Oct 2022 16:13:54 +0100 -Subject: [PATCH 18/19] gvariant: Fix g_variant_byteswap() returning non-normal - data sometimes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If `g_variant_byteswap()` was called on a non-normal variant of a type -which doesn’t need byteswapping, it would return a non-normal output. - -That contradicts the documentation, which says that the return value is -always in normal form. - -Fix the code so it matches the documentation. - -Includes a unit test. - -Signed-off-by: Philip Withnall - -Helps: #2797 ---- - glib/gvariant.c | 8 +++++--- - glib/tests/gvariant.c | 24 ++++++++++++++++++++++++ - 2 files changed, 29 insertions(+), 3 deletions(-) - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index 63c134839..9388c529d 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -6026,14 +6026,16 @@ g_variant_byteswap (GVariant *value) - g_variant_serialised_byteswap (serialised); - - bytes = g_bytes_new_take (serialised.data, serialised.size); -- new = g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE); -+ new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE)); - g_bytes_unref (bytes); - } - else - /* contains no multi-byte data */ -- new = value; -+ new = g_variant_get_normal_form (value); - -- return g_variant_ref_sink (new); -+ g_assert (g_variant_is_trusted (new)); -+ -+ return g_steal_pointer (&new); - } - - /** -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index 028543833..871a6dab0 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -3826,6 +3826,29 @@ test_gv_byteswap (void) - g_free (string); - } - -+static void -+test_gv_byteswap_non_normal_non_aligned (void) -+{ -+ const guint8 data[] = { 0x02 }; -+ GVariant *v = NULL; -+ GVariant *v_byteswapped = NULL; -+ -+ g_test_summary ("Test that calling g_variant_byteswap() on a variant which " -+ "is in non-normal form and doesn’t need byteswapping returns " -+ "the same variant in normal form."); -+ -+ v = g_variant_new_from_data (G_VARIANT_TYPE_BOOLEAN, data, sizeof (data), FALSE, NULL, NULL); -+ g_assert_false (g_variant_is_normal_form (v)); -+ -+ v_byteswapped = g_variant_byteswap (v); -+ g_assert_true (g_variant_is_normal_form (v_byteswapped)); -+ -+ g_assert_cmpvariant (v, v_byteswapped); -+ -+ g_variant_unref (v); -+ g_variant_unref (v_byteswapped); -+} -+ - static void - test_parser (void) - { -@@ -5594,6 +5617,7 @@ main (int argc, char **argv) - g_test_add_func ("/gvariant/builder-memory", test_builder_memory); - g_test_add_func ("/gvariant/hashing", test_hashing); - g_test_add_func ("/gvariant/byteswap", test_gv_byteswap); -+ g_test_add_func ("/gvariant/byteswap/non-normal-non-aligned", test_gv_byteswap_non_normal_non_aligned); - g_test_add_func ("/gvariant/parser", test_parses); - g_test_add_func ("/gvariant/parser/integer-bounds", test_parser_integer_bounds); - g_test_add_func ("/gvariant/parser/recursion", test_parser_recursion); --- -2.40.0 - -From c6d0ae6c04a4257e9e06edd186d19e8ac4f37024 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 27 Oct 2022 22:53:13 +0100 -Subject: [PATCH 19/19] gvariant: Allow g_variant_byteswap() to operate on - tree-form variants -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This avoids needing to always serialise a variant before byteswapping it. -With variants in non-normal forms, serialisation can result in a large -increase in size of the variant, and a lot of allocations for leaf -`GVariant`s. This can lead to a denial of service attack. - -Avoid that by changing byteswapping so that it happens on the tree form -of the variant if the input is in non-normal form. If the input is in -normal form (either serialised or in tree form), continue using the -existing code as byteswapping an already-serialised normal variant is -about 3× faster than byteswapping on the equivalent tree form. - -The existing unit tests cover byteswapping well, but need some -adaptation so that they operate on tree form variants too. - -I considered dropping the serialised byteswapping code and doing all -byteswapping on tree-form variants, as that would make maintenance -simpler (avoiding having two parallel implementations of byteswapping). -However, most inputs to `g_variant_byteswap()` are likely to be -serialised variants (coming from a byte array of input from some foreign -source) and most of them are going to be in normal form (as corruption -and malicious action are rare). So getting rid of the serialised -byteswapping code would impose quite a performance penalty on the common -case. - -Signed-off-by: Philip Withnall - -Fixes: #2797 ---- - glib/gvariant.c | 87 ++++++++++++++++++++++++++++++++----------- - glib/tests/gvariant.c | 57 ++++++++++++++++++++++++---- - 2 files changed, 115 insertions(+), 29 deletions(-) - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index 9388c529d..1f0eccb73 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -5795,7 +5795,8 @@ g_variant_iter_loop (GVariantIter *iter, - - /* Serialised data {{{1 */ - static GVariant * --g_variant_deep_copy (GVariant *value) -+g_variant_deep_copy (GVariant *value, -+ gboolean byteswap) - { - switch (g_variant_classify (value)) - { -@@ -5812,7 +5813,7 @@ g_variant_deep_copy (GVariant *value) - for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++) - { - GVariant *child = g_variant_get_child_value (value, i); -- g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); -+ g_variant_builder_add_value (&builder, g_variant_deep_copy (child, byteswap)); - g_variant_unref (child); - } - -@@ -5863,7 +5864,7 @@ g_variant_deep_copy (GVariant *value) - * be non-normal for reasons other than invalid offset table - * entries. As they are all the same type, they will all have - * the same default value though, so keep that around. */ -- g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); -+ g_variant_builder_add_value (&builder, g_variant_deep_copy (child, byteswap)); - } - else if (child == NULL && first_invalid_child_deep_copy != NULL) - { -@@ -5872,7 +5873,7 @@ g_variant_deep_copy (GVariant *value) - else if (child == NULL) - { - child = g_variant_get_child_value (value, i); -- first_invalid_child_deep_copy = g_variant_ref_sink (g_variant_deep_copy (child)); -+ first_invalid_child_deep_copy = g_variant_ref_sink (g_variant_deep_copy (child, byteswap)); - g_variant_builder_add_value (&builder, first_invalid_child_deep_copy); - } - -@@ -5891,28 +5892,63 @@ g_variant_deep_copy (GVariant *value) - return g_variant_new_byte (g_variant_get_byte (value)); - - case G_VARIANT_CLASS_INT16: -- return g_variant_new_int16 (g_variant_get_int16 (value)); -+ if (byteswap) -+ return g_variant_new_int16 (GUINT16_SWAP_LE_BE (g_variant_get_int16 (value))); -+ else -+ return g_variant_new_int16 (g_variant_get_int16 (value)); - - case G_VARIANT_CLASS_UINT16: -- return g_variant_new_uint16 (g_variant_get_uint16 (value)); -+ if (byteswap) -+ return g_variant_new_uint16 (GUINT16_SWAP_LE_BE (g_variant_get_uint16 (value))); -+ else -+ return g_variant_new_uint16 (g_variant_get_uint16 (value)); - - case G_VARIANT_CLASS_INT32: -- return g_variant_new_int32 (g_variant_get_int32 (value)); -+ if (byteswap) -+ return g_variant_new_int32 (GUINT32_SWAP_LE_BE (g_variant_get_int32 (value))); -+ else -+ return g_variant_new_int32 (g_variant_get_int32 (value)); - - case G_VARIANT_CLASS_UINT32: -- return g_variant_new_uint32 (g_variant_get_uint32 (value)); -+ if (byteswap) -+ return g_variant_new_uint32 (GUINT32_SWAP_LE_BE (g_variant_get_uint32 (value))); -+ else -+ return g_variant_new_uint32 (g_variant_get_uint32 (value)); - - case G_VARIANT_CLASS_INT64: -- return g_variant_new_int64 (g_variant_get_int64 (value)); -+ if (byteswap) -+ return g_variant_new_int64 (GUINT64_SWAP_LE_BE (g_variant_get_int64 (value))); -+ else -+ return g_variant_new_int64 (g_variant_get_int64 (value)); - - case G_VARIANT_CLASS_UINT64: -- return g_variant_new_uint64 (g_variant_get_uint64 (value)); -+ if (byteswap) -+ return g_variant_new_uint64 (GUINT64_SWAP_LE_BE (g_variant_get_uint64 (value))); -+ else -+ return g_variant_new_uint64 (g_variant_get_uint64 (value)); - - case G_VARIANT_CLASS_HANDLE: -- return g_variant_new_handle (g_variant_get_handle (value)); -+ if (byteswap) -+ return g_variant_new_handle (GUINT32_SWAP_LE_BE (g_variant_get_handle (value))); -+ else -+ return g_variant_new_handle (g_variant_get_handle (value)); - - case G_VARIANT_CLASS_DOUBLE: -- return g_variant_new_double (g_variant_get_double (value)); -+ if (byteswap) -+ { -+ /* We have to convert the double to a uint64 here using a union, -+ * because a cast will round it numerically. */ -+ union -+ { -+ guint64 u64; -+ gdouble dbl; -+ } u1, u2; -+ u1.dbl = g_variant_get_double (value); -+ u2.u64 = GUINT64_SWAP_LE_BE (u1.u64); -+ return g_variant_new_double (u2.dbl); -+ } -+ else -+ return g_variant_new_double (g_variant_get_double (value)); - - case G_VARIANT_CLASS_STRING: - return g_variant_new_string (g_variant_get_string (value, NULL)); -@@ -5969,7 +6005,7 @@ g_variant_get_normal_form (GVariant *value) - if (g_variant_is_normal_form (value)) - return g_variant_ref (value); - -- trusted = g_variant_deep_copy (value); -+ trusted = g_variant_deep_copy (value, FALSE); - g_assert (g_variant_is_trusted (trusted)); - - return g_variant_ref_sink (trusted); -@@ -5989,6 +6025,11 @@ g_variant_get_normal_form (GVariant *value) - * contain multi-byte numeric data. That include strings, booleans, - * bytes and containers containing only these things (recursively). - * -+ * While this function can safely handle untrusted, non-normal data, it is -+ * recommended to check whether the input is in normal form beforehand, using -+ * g_variant_is_normal_form(), and to reject non-normal inputs if your -+ * application can be strict about what inputs it rejects. -+ * - * The returned value is always in normal form and is marked as trusted. - * - * Returns: (transfer full): the byteswapped form of @value -@@ -6006,22 +6047,21 @@ g_variant_byteswap (GVariant *value) - - g_variant_type_info_query (type_info, &alignment, NULL); - -- if (alignment) -- /* (potentially) contains multi-byte numeric data */ -+ if (alignment && g_variant_is_normal_form (value)) - { -+ /* (potentially) contains multi-byte numeric data, but is also already in -+ * normal form so we can use a faster byteswapping codepath on the -+ * serialised data */ - GVariantSerialised serialised = { 0, }; -- GVariant *trusted; - GBytes *bytes; - -- trusted = g_variant_get_normal_form (value); -- serialised.type_info = g_variant_get_type_info (trusted); -- serialised.size = g_variant_get_size (trusted); -+ serialised.type_info = g_variant_get_type_info (value); -+ serialised.size = g_variant_get_size (value); - serialised.data = g_malloc (serialised.size); -- serialised.depth = g_variant_get_depth (trusted); -+ serialised.depth = g_variant_get_depth (value); - serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */ - serialised.checked_offsets_up_to = G_MAXSIZE; -- g_variant_store (trusted, serialised.data); -- g_variant_unref (trusted); -+ g_variant_store (value, serialised.data); - - g_variant_serialised_byteswap (serialised); - -@@ -6029,6 +6069,9 @@ g_variant_byteswap (GVariant *value) - new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE)); - g_bytes_unref (bytes); - } -+ else if (alignment) -+ /* (potentially) contains multi-byte numeric data */ -+ new = g_variant_ref_sink (g_variant_deep_copy (value, TRUE)); - else - /* contains no multi-byte data */ - new = g_variant_get_normal_form (value); -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index 871a6dab0..143057de7 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -2288,24 +2288,67 @@ serialise_tree (TreeInstance *tree, - static void - test_byteswap (void) - { -- GVariantSerialised one = { 0, }, two = { 0, }; -+ GVariantSerialised one = { 0, }, two = { 0, }, three = { 0, }; - TreeInstance *tree; -- -+ GVariant *one_variant = NULL; -+ GVariant *two_variant = NULL; -+ GVariant *two_byteswapped = NULL; -+ GVariant *three_variant = NULL; -+ GVariant *three_byteswapped = NULL; -+ guint8 *three_data_copy = NULL; -+ gsize three_size_copy = 0; -+ -+ /* Write a tree out twice, once normally and once byteswapped. */ - tree = tree_instance_new (NULL, 3); - serialise_tree (tree, &one); - -+ one_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (one.type_info)), -+ one.data, one.size, FALSE, NULL, NULL); -+ - i_am_writing_byteswapped = TRUE; - serialise_tree (tree, &two); -+ serialise_tree (tree, &three); - i_am_writing_byteswapped = FALSE; - -- g_variant_serialised_byteswap (two); -- -- g_assert_cmpmem (one.data, one.size, two.data, two.size); -- g_assert_cmpuint (one.depth, ==, two.depth); -- -+ /* Swap the first byteswapped one back using the function we want to test. */ -+ two_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (two.type_info)), -+ two.data, two.size, FALSE, NULL, NULL); -+ two_byteswapped = g_variant_byteswap (two_variant); -+ -+ /* Make the second byteswapped one non-normal (hopefully), and then byteswap -+ * it back using the function we want to test in its non-normal mode. -+ * This might not work because it’s not necessarily possible to make an -+ * arbitrary random variant non-normal. Adding a single zero byte to the end -+ * often makes something non-normal but still readable. */ -+ three_size_copy = three.size + 1; -+ three_data_copy = g_malloc (three_size_copy); -+ memcpy (three_data_copy, three.data, three.size); -+ three_data_copy[three.size] = '\0'; -+ -+ three_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (three.type_info)), -+ three_data_copy, three_size_copy, FALSE, NULL, NULL); -+ three_byteswapped = g_variant_byteswap (three_variant); -+ -+ /* Check they’re the same. We can always compare @one_variant and -+ * @two_byteswapped. We can only compare @two_byteswapped and -+ * @three_byteswapped if @two_variant and @three_variant are equal: in that -+ * case, the corruption to @three_variant was enough to make it non-normal but -+ * not enough to change its value. */ -+ g_assert_cmpvariant (one_variant, two_byteswapped); -+ -+ if (g_variant_equal (two_variant, three_variant)) -+ g_assert_cmpvariant (two_byteswapped, three_byteswapped); -+ -+ g_variant_unref (three_byteswapped); -+ g_variant_unref (three_variant); -+ g_variant_unref (two_byteswapped); -+ g_variant_unref (two_variant); -+ g_variant_unref (one_variant); - tree_instance_free (tree); - g_free (one.data); - g_free (two.data); -+ g_free (three.data); -+ g_free (three_data_copy); - } - - static void --- -2.40.0 diff --git a/base/rx-glib2/3136.patch b/base/rx-glib2/3136.patch deleted file mode 100644 index 57e1b95..0000000 --- a/base/rx-glib2/3136.patch +++ /dev/null @@ -1,65 +0,0 @@ -From ba2137b0d9ea3744155be81a5ba770c6535b46f3 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Thu, 15 Dec 2022 12:51:37 +0000 -Subject: [PATCH] gvariant-serialiser: Convert endianness of offsets -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The array of offsets is little-endian, even on big-endian architectures -like s390x. - -Fixes: ade71fb5 "gvariant: Don’t allow child elements to overlap with each other" -Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2839 -Signed-off-by: Simon McVittie ---- - glib/gvariant-serialiser.c | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index fadefab659..f443c2eb85 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -714,17 +714,19 @@ gvs_variable_sized_array_n_children (GVariantSerialised value) - /* Find the index of the first out-of-order element in @data, assuming that - * @data is an array of elements of given @type, starting at index @start and - * containing a further @len-@start elements. */ --#define DEFINE_FIND_UNORDERED(type) \ -+#define DEFINE_FIND_UNORDERED(type, le_to_native) \ - static gsize \ - find_unordered_##type (const guint8 *data, gsize start, gsize len) \ - { \ - gsize off; \ -- type current, previous; \ -+ type current_le, previous_le, current, previous; \ - \ -- memcpy (&previous, data + start * sizeof (current), sizeof (current)); \ -+ memcpy (&previous_le, data + start * sizeof (current), sizeof (current)); \ -+ previous = le_to_native (previous_le); \ - for (off = (start + 1) * sizeof (current); off < len * sizeof (current); off += sizeof (current)) \ - { \ -- memcpy (¤t, data + off, sizeof (current)); \ -+ memcpy (¤t_le, data + off, sizeof (current)); \ -+ current = le_to_native (current_le); \ - if (current < previous) \ - break; \ - previous = current; \ -@@ -732,10 +734,11 @@ gvs_variable_sized_array_n_children (GVariantSerialised value) - return off / sizeof (current) - 1; \ - } - --DEFINE_FIND_UNORDERED (guint8); --DEFINE_FIND_UNORDERED (guint16); --DEFINE_FIND_UNORDERED (guint32); --DEFINE_FIND_UNORDERED (guint64); -+#define NO_CONVERSION(x) (x) -+DEFINE_FIND_UNORDERED (guint8, NO_CONVERSION); -+DEFINE_FIND_UNORDERED (guint16, GUINT16_FROM_LE); -+DEFINE_FIND_UNORDERED (guint32, GUINT32_FROM_LE); -+DEFINE_FIND_UNORDERED (guint64, GUINT64_FROM_LE); - - static GVariantSerialised - gvs_variable_sized_array_get_child (GVariantSerialised value, --- -GitLab - diff --git a/base/rx-glib2/3163.patch b/base/rx-glib2/3163.patch deleted file mode 100644 index 13fe47c..0000000 --- a/base/rx-glib2/3163.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 78da5faccb3e065116b75b3ff87ff55381da6c76 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 15 Dec 2022 13:00:39 +0000 -Subject: [PATCH 1/2] =?UTF-8?q?gvariant:=20Check=20offset=20table=20doesn?= - =?UTF-8?q?=E2=80=99t=20fall=20outside=20variant=20bounds?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When dereferencing the first entry in the offset table for a tuple, -check that it doesn’t fall outside the bounds of the variant first. - -This prevents an out-of-bounds read from some non-normal tuples. - -This bug was introduced in commit 73d0aa81c2575a5c9ae77d. - -Includes a unit test, although the test will likely only catch the -original bug if run with asan enabled. - -Signed-off-by: Philip Withnall - -Fixes: #2840 -oss-fuzz#54302 ---- - glib/gvariant-serialiser.c | 12 ++++++-- - glib/tests/gvariant.c | 63 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 72 insertions(+), 3 deletions(-) - -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index f443c2eb85..4e4a73ad17 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -984,7 +984,8 @@ gvs_tuple_get_member_bounds (GVariantSerialised value, - - member_info = g_variant_type_info_member_info (value.type_info, index_); - -- if (member_info->i + 1) -+ if (member_info->i + 1 && -+ offset_size * (member_info->i + 1) <= value.size) - member_start = gvs_read_unaligned_le (value.data + value.size - - offset_size * (member_info->i + 1), - offset_size); -@@ -995,7 +996,8 @@ gvs_tuple_get_member_bounds (GVariantSerialised value, - member_start &= member_info->b; - member_start |= member_info->c; - -- if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST) -+ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST && -+ offset_size * (member_info->i + 1) <= value.size) - member_end = value.size - offset_size * (member_info->i + 1); - - else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) -@@ -1006,11 +1008,15 @@ gvs_tuple_get_member_bounds (GVariantSerialised value, - member_end = member_start + fixed_size; - } - -- else /* G_VARIANT_MEMBER_ENDING_OFFSET */ -+ else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET && -+ offset_size * (member_info->i + 2) <= value.size) - member_end = gvs_read_unaligned_le (value.data + value.size - - offset_size * (member_info->i + 2), - offset_size); - -+ else /* invalid */ -+ member_end = G_MAXSIZE; -+ - if (out_member_start != NULL) - *out_member_start = member_start; - if (out_member_end != NULL) -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index b360888e4d..98c51a1d75 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -5576,6 +5576,67 @@ test_normal_checking_tuple_offsets4 (void) - g_variant_unref (variant); - } - -+/* This is a regression test that dereferencing the first element in the offset -+ * table doesn’t dereference memory before the start of the GVariant. The first -+ * element in the offset table gives the offset of the final member in the -+ * tuple (the offset table is stored in reverse), and the position of this final -+ * member is needed to check that none of the tuple members overlap with the -+ * offset table -+ * -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2840 */ -+static void -+test_normal_checking_tuple_offsets5 (void) -+{ -+ /* A tuple of type (sss) in normal form would have an offset table with two -+ * entries: -+ * - The first entry (lowest index in the table) gives the offset of the -+ * third `s` in the tuple, as the offset table is reversed compared to the -+ * tuple members. -+ * - The second entry (highest index in the table) gives the offset of the -+ * second `s` in the tuple. -+ * - The offset of the first `s` in the tuple is always 0. -+ * -+ * See §2.5.4 (Structures) of the GVariant specification for details, noting -+ * that the table is only layed out this way because all three members of the -+ * tuple have non-fixed sizes. -+ * -+ * It’s not clear whether the 0xaa data of this variant is part of the strings -+ * in the tuple, or part of the offset table. It doesn’t really matter. This -+ * is a regression test to check that the code to validate the offset table -+ * doesn’t unconditionally try to access the first entry in the offset table -+ * by subtracting the table size from the end of the GVariant data. -+ * -+ * In this non-normal case, that would result in an address off the start of -+ * the GVariant data, and an out-of-bounds read, because the GVariant is one -+ * byte long, but the offset table is calculated as two bytes long (with 1B -+ * sized entries) from the tuple’s type. -+ */ -+ const GVariantType *data_type = G_VARIANT_TYPE ("(sss)"); -+ const guint8 data[] = { 0xaa }; -+ gsize size = sizeof (data); -+ GVariant *variant = NULL; -+ GVariant *normal_variant = NULL; -+ GVariant *expected = NULL; -+ -+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2840"); -+ -+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); -+ g_assert_nonnull (variant); -+ -+ g_assert_false (g_variant_is_normal_form (variant)); -+ -+ normal_variant = g_variant_get_normal_form (variant); -+ g_assert_nonnull (normal_variant); -+ -+ expected = g_variant_new_parsed ("('', '', '')"); -+ g_assert_cmpvariant (expected, variant); -+ g_assert_cmpvariant (expected, normal_variant); -+ -+ g_variant_unref (expected); -+ g_variant_unref (normal_variant); -+ g_variant_unref (variant); -+} -+ - /* Test that an otherwise-valid serialised GVariant is considered non-normal if - * its offset table entries are too wide. - * -@@ -5827,6 +5888,8 @@ main (int argc, char **argv) - test_normal_checking_tuple_offsets3); - g_test_add_func ("/gvariant/normal-checking/tuple-offsets4", - test_normal_checking_tuple_offsets4); -+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets5", -+ test_normal_checking_tuple_offsets5); - g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized", - test_normal_checking_tuple_offsets_minimal_sized); - g_test_add_func ("/gvariant/normal-checking/empty-object-path", --- -GitLab - - -From 21a204147b16539b3eda3143b32844c49e29f4d4 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 15 Dec 2022 16:49:28 +0000 -Subject: [PATCH 2/2] gvariant: Propagate trust when getting a child of a - serialised variant - -If a variant is trusted, that means all its children are trusted, so -ensure that their checked offsets are set as such. - -This allows a lot of the offset table checks to be avoided when getting -children from trusted serialised tuples, which speeds things up. - -No unit test is included because this is just a performance fix. If -there are other slownesses, or regressions, in serialised `GVariant` -performance, the fuzzing setup will catch them like it did this one. - -This change does reduce the time to run the oss-fuzz reproducer from 80s -to about 0.7s on my machine. - -Signed-off-by: Philip Withnall - -Fixes: #2841 -oss-fuzz#54314 ---- - glib/gvariant-core.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c -index f441c4757e..4778022829 100644 ---- a/glib/gvariant-core.c -+++ b/glib/gvariant-core.c -@@ -1198,8 +1198,8 @@ g_variant_get_child_value (GVariant *value, - child->contents.serialised.bytes = - g_bytes_ref (value->contents.serialised.bytes); - child->contents.serialised.data = s_child.data; -- child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to; -- child->contents.serialised.checked_offsets_up_to = s_child.checked_offsets_up_to; -+ child->contents.serialised.ordered_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.ordered_offsets_up_to; -+ child->contents.serialised.checked_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.checked_offsets_up_to; - - return child; - } --- -GitLab - diff --git a/base/rx-glib2/3272.patch b/base/rx-glib2/3272.patch deleted file mode 100644 index c97e428..0000000 --- a/base/rx-glib2/3272.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 059f4f3999f1de506417611318c6f27db57fb689 Mon Sep 17 00:00:00 2001 -From: Marius Vollmer -Date: Mon, 13 Feb 2023 14:12:52 +0200 -Subject: [PATCH] gdbus: Never buffer reads during server authentication - -Otherwise, the content of the buffer is thrown away when switching -from reading via a GDataInputStream to unbuffered reads when waiting -for the "BEGIN" line. - -(The code already tried to protect against over-reading like this by -using unbuffered reads for the last few lines of the auth protocol, -but it might already be too late at that point. The buffer of the -GDataInputStream might already contain the "BEGIN" line for example.) - -This matters when connecting a sd-bus client directly to a GDBus -client. A sd-bus client optimistically sends the whole auth -conversation in one go without waiting for intermediate replies. This -is done to improve performance for the many short-lived connections -that are typically made. ---- - gio/gdbusauth.c | 50 ++++++++++++++++++++++++++++++------------------- - 1 file changed, 31 insertions(+), 19 deletions(-) - -diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c -index c430f0cf0..17c7d47b7 100644 ---- a/gio/gdbusauth.c -+++ b/gio/gdbusauth.c -@@ -933,7 +933,6 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - { - gboolean ret; - ServerState state; -- GDataInputStream *dis; - GDataOutputStream *dos; - GError *local_error; - gchar *line; -@@ -949,7 +948,6 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - _g_dbus_auth_add_mechs (auth, observer); - - ret = FALSE; -- dis = NULL; - dos = NULL; - mech = NULL; - negotiated_capabilities = 0; -@@ -965,13 +963,18 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - goto out; - } - -- dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream))); -+ /* We use an extremely slow (but reliable) line reader for input -+ * instead of something buffered - this basically does a recvfrom() -+ * system call per character -+ * -+ * (the problem with using GDataInputStream's read_line is that -+ * because of buffering it might start reading into the first D-Bus -+ * message that appears after "BEGIN\r\n"....) -+ */ -+ - dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream))); -- g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE); - g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE); - -- g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); -- - /* read the NUL-byte, possibly with credentials attached */ - #ifdef G_OS_UNIX - #ifndef G_CREDENTIALS_PREFER_MESSAGE_PASSING -@@ -1010,11 +1013,22 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - } - else - { -+ gchar c; -+ gssize num_read; -+ - local_error = NULL; -- (void)g_data_input_stream_read_byte (dis, cancellable, &local_error); -- if (local_error != NULL) -+ num_read = g_input_stream_read (g_io_stream_get_input_stream (auth->priv->stream), -+ &c, 1, -+ cancellable, &local_error); -+ if (num_read != 1 || local_error != NULL) - { -- g_propagate_error (error, local_error); -+ if (local_error == NULL) -+ g_set_error_literal (error, -+ G_IO_ERROR, -+ G_IO_ERROR_FAILED, -+ _ ("Unexpected lack of content trying to read a byte")); -+ else -+ g_propagate_error (error, local_error); - goto out; - } - } -@@ -1050,7 +1064,10 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - { - case SERVER_STATE_WAITING_FOR_AUTH: - debug_print ("SERVER: WaitingForAuth"); -- line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); -+ line = _my_g_input_stream_read_line_safe (g_io_stream_get_input_stream (auth->priv->stream), -+ &line_length, -+ cancellable, -+ error); - debug_print ("SERVER: WaitingForAuth, read '%s'", line); - if (line == NULL) - goto out; -@@ -1260,7 +1277,10 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - - case SERVER_STATE_WAITING_FOR_DATA: - debug_print ("SERVER: WaitingForData"); -- line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); -+ line = _my_g_input_stream_read_line_safe (g_io_stream_get_input_stream (auth->priv->stream), -+ &line_length, -+ cancellable, -+ error); - debug_print ("SERVER: WaitingForData, read '%s'", line); - if (line == NULL) - goto out; -@@ -1299,13 +1319,6 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - - case SERVER_STATE_WAITING_FOR_BEGIN: - debug_print ("SERVER: WaitingForBegin"); -- /* Use extremely slow (but reliable) line reader - this basically -- * does a recvfrom() system call per character -- * -- * (the problem with using GDataInputStream's read_line is that because of -- * buffering it might start reading into the first D-Bus message that -- * appears after "BEGIN\r\n"....) -- */ - line = _my_g_input_stream_read_line_safe (g_io_stream_get_input_stream (auth->priv->stream), - &line_length, - cancellable, -@@ -1364,7 +1377,6 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - - out: - g_clear_object (&mech); -- g_clear_object (&dis); - g_clear_object (&dos); - g_clear_object (&own_credentials); - --- -2.41.0 - diff --git a/base/rx-glib2/3353.patch b/base/rx-glib2/3353.patch deleted file mode 100644 index eb9020a..0000000 --- a/base/rx-glib2/3353.patch +++ /dev/null @@ -1,1078 +0,0 @@ -From 68f0cd7f3d351da1f011a65e080d8e3f26a31525 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Tue, 28 Mar 2023 14:38:08 +0200 -Subject: [PATCH 1/7] gmain: unify win/unix implementations for child watcher - -Let's move the difference between the win/unix implementations closer to -where the difference is. Thereby, we easier see the two implementations -side by side. Splitting it at a higher layer makes the code harder to -read. - -This is just a preparation for what comes next. ---- - glib/gmain.c | 192 ++++++++++++++++++++++++--------------------------- - 1 file changed, 92 insertions(+), 100 deletions(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index f0cf700c0..228737efa 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -446,6 +446,11 @@ static gboolean g_child_watch_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data); - static void g_child_watch_finalize (GSource *source); -+ -+#ifndef G_OS_WIN32 -+static void unref_unix_signal_handler_unlocked (int signum); -+#endif -+ - #ifdef G_OS_UNIX - static void g_unix_signal_handler (int signum); - static gboolean g_unix_signal_watch_prepare (GSource *source, -@@ -5214,17 +5219,49 @@ g_timeout_add_seconds (guint interval, - - /* Child watch functions */ - --#ifdef G_OS_WIN32 -+#ifdef HAVE_PIDFD -+static int -+siginfo_t_to_wait_status (const siginfo_t *info) -+{ -+ /* Each of these returns is essentially the inverse of WIFEXITED(), -+ * WIFSIGNALED(), etc. */ -+ switch (info->si_code) -+ { -+ case CLD_EXITED: -+ return W_EXITCODE (info->si_status, 0); -+ case CLD_KILLED: -+ return W_EXITCODE (0, info->si_status); -+ case CLD_DUMPED: -+ return W_EXITCODE (0, info->si_status | WCOREFLAG); -+ case CLD_CONTINUED: -+ return __W_CONTINUED; -+ case CLD_STOPPED: -+ case CLD_TRAPPED: -+ default: -+ return W_STOPCODE (info->si_status); -+ } -+} -+#endif /* HAVE_PIDFD */ - - static gboolean - g_child_watch_prepare (GSource *source, - gint *timeout) - { -+#ifdef G_OS_WIN32 - *timeout = -1; - return FALSE; -+#else /* G_OS_WIN32 */ -+ { -+ GChildWatchSource *child_watch_source; -+ -+ child_watch_source = (GChildWatchSource *) source; -+ -+ return g_atomic_int_get (&child_watch_source->child_exited); -+ } -+#endif /* G_OS_WIN32 */ - } - --static gboolean -+static gboolean - g_child_watch_check (GSource *source) - { - GChildWatchSource *child_watch_source; -@@ -5232,6 +5269,7 @@ g_child_watch_check (GSource *source) - - child_watch_source = (GChildWatchSource *) source; - -+#ifdef G_OS_WIN32 - child_exited = child_watch_source->poll.revents & G_IO_IN; - - if (child_exited) -@@ -5246,15 +5284,45 @@ g_child_watch_check (GSource *source) - */ - if (!GetExitCodeProcess (child_watch_source->pid, &child_status)) - { -- gchar *emsg = g_win32_error_message (GetLastError ()); -- g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg); -- g_free (emsg); -+ gchar *emsg = g_win32_error_message (GetLastError ()); -+ g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg); -+ g_free (emsg); - -- child_watch_source->child_status = -1; -- } -+ child_watch_source->child_status = -1; -+ } - else -- child_watch_source->child_status = child_status; -+ child_watch_source->child_status = child_status; - } -+#else /* G_OS_WIN32 */ -+#ifdef HAVE_PIDFD -+ if (child_watch_source->using_pidfd) -+ { -+ child_exited = child_watch_source->poll.revents & G_IO_IN; -+ -+ if (child_exited) -+ { -+ siginfo_t child_info = { 0, }; -+ -+ /* Get the exit status */ -+ if (waitid (P_PIDFD, child_watch_source->poll.fd, &child_info, WEXITED | WNOHANG) >= 0 && -+ child_info.si_pid != 0) -+ { -+ /* waitid() helpfully provides the wait status in a decomposed -+ * form which is quite useful. Unfortunately we have to report it -+ * to the #GChildWatchFunc as a waitpid()-style platform-specific -+ * wait status, so that the user code in #GChildWatchFunc can then -+ * call WIFEXITED() (etc.) on it. That means re-composing the -+ * status information. */ -+ child_watch_source->child_status = siginfo_t_to_wait_status (&child_info); -+ child_watch_source->child_exited = TRUE; -+ } -+ } -+ -+ return child_exited; -+ } -+#endif /* HAVE_PIDFD */ -+ child_exited = g_atomic_int_get (&child_watch_source->child_exited); -+#endif /* G_OS_WIN32 */ - - return child_exited; - } -@@ -5262,9 +5330,24 @@ g_child_watch_check (GSource *source) - static void - g_child_watch_finalize (GSource *source) - { -+#ifndef G_OS_WIN32 -+ GChildWatchSource *child_watch_source = (GChildWatchSource *) source; -+ -+ if (child_watch_source->using_pidfd) -+ { -+ if (child_watch_source->poll.fd >= 0) -+ close (child_watch_source->poll.fd); -+ return; -+ } -+ -+ G_LOCK (unix_signal_lock); -+ unix_child_watches = g_slist_remove (unix_child_watches, source); -+ unref_unix_signal_handler_unlocked (SIGCHLD); -+ G_UNLOCK (unix_signal_lock); -+#endif /* G_OS_WIN32 */ - } - --#else /* G_OS_WIN32 */ -+#ifndef G_OS_WIN32 - - static void - wake_source (GSource *source) -@@ -5397,79 +5480,6 @@ dispatch_unix_signals (void) - G_UNLOCK(unix_signal_lock); - } - --static gboolean --g_child_watch_prepare (GSource *source, -- gint *timeout) --{ -- GChildWatchSource *child_watch_source; -- -- child_watch_source = (GChildWatchSource *) source; -- -- return g_atomic_int_get (&child_watch_source->child_exited); --} -- --#ifdef HAVE_PIDFD --static int --siginfo_t_to_wait_status (const siginfo_t *info) --{ -- /* Each of these returns is essentially the inverse of WIFEXITED(), -- * WIFSIGNALED(), etc. */ -- switch (info->si_code) -- { -- case CLD_EXITED: -- return W_EXITCODE (info->si_status, 0); -- case CLD_KILLED: -- return W_EXITCODE (0, info->si_status); -- case CLD_DUMPED: -- return W_EXITCODE (0, info->si_status | WCOREFLAG); -- case CLD_CONTINUED: -- return __W_CONTINUED; -- case CLD_STOPPED: -- case CLD_TRAPPED: -- default: -- return W_STOPCODE (info->si_status); -- } --} --#endif /* HAVE_PIDFD */ -- --static gboolean --g_child_watch_check (GSource *source) --{ -- GChildWatchSource *child_watch_source; -- -- child_watch_source = (GChildWatchSource *) source; -- --#ifdef HAVE_PIDFD -- if (child_watch_source->using_pidfd) -- { -- gboolean child_exited = child_watch_source->poll.revents & G_IO_IN; -- -- if (child_exited) -- { -- siginfo_t child_info = { 0, }; -- -- /* Get the exit status */ -- if (waitid (P_PIDFD, child_watch_source->poll.fd, &child_info, WEXITED | WNOHANG) >= 0 && -- child_info.si_pid != 0) -- { -- /* waitid() helpfully provides the wait status in a decomposed -- * form which is quite useful. Unfortunately we have to report it -- * to the #GChildWatchFunc as a waitpid()-style platform-specific -- * wait status, so that the user code in #GChildWatchFunc can then -- * call WIFEXITED() (etc.) on it. That means re-composing the -- * status information. */ -- child_watch_source->child_status = siginfo_t_to_wait_status (&child_info); -- child_watch_source->child_exited = TRUE; -- } -- } -- -- return child_exited; -- } --#endif /* HAVE_PIDFD */ -- -- return g_atomic_int_get (&child_watch_source->child_exited); --} -- - static gboolean - g_unix_signal_watch_prepare (GSource *source, - gint *timeout) -@@ -5648,24 +5658,6 @@ g_unix_signal_watch_finalize (GSource *source) - G_UNLOCK (unix_signal_lock); - } - --static void --g_child_watch_finalize (GSource *source) --{ -- GChildWatchSource *child_watch_source = (GChildWatchSource *) source; -- -- if (child_watch_source->using_pidfd) -- { -- if (child_watch_source->poll.fd >= 0) -- close (child_watch_source->poll.fd); -- return; -- } -- -- G_LOCK (unix_signal_lock); -- unix_child_watches = g_slist_remove (unix_child_watches, source); -- unref_unix_signal_handler_unlocked (SIGCHLD); -- G_UNLOCK (unix_signal_lock); --} -- - #endif /* G_OS_WIN32 */ - - static gboolean --- -2.41.0 - - -From 984e04a77b29c60f66fd60b1f9690e6ff7880574 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Tue, 28 Mar 2023 15:44:30 +0200 -Subject: [PATCH 2/7] gmain: simplify handling child watchers in - dispatch_unix_signals_unlocked() - -- if a child watch source has "using_pidfd", it is never linked in the - unix_child_watches list. Drop that check. -- replace the deep nested if, with an early "continue" in the loop, - if we detect there is nothing to do. It makes the code easier to - read. ---- - glib/gmain.c | 39 +++++++++++++++++++-------------------- - 1 file changed, 19 insertions(+), 20 deletions(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index 228737efa..8a030a409 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -5430,31 +5430,30 @@ dispatch_unix_signals_unlocked (void) - for (node = unix_child_watches; node; node = node->next) - { - GChildWatchSource *source = node->data; -+ pid_t pid; - -- if (!source->using_pidfd && -- !g_atomic_int_get (&source->child_exited)) -+ if (g_atomic_int_get (&source->child_exited)) -+ continue; -+ -+ do - { -- pid_t pid; -- do -- { -- g_assert (source->pid > 0); -+ g_assert (source->pid > 0); - -- pid = waitpid (source->pid, &source->child_status, WNOHANG); -- if (pid > 0) -- { -- g_atomic_int_set (&source->child_exited, TRUE); -- wake_source ((GSource *) source); -- } -- else if (pid == -1 && errno == ECHILD) -- { -- g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes."); -- source->child_status = 0; -- g_atomic_int_set (&source->child_exited, TRUE); -- wake_source ((GSource *) source); -- } -+ pid = waitpid (source->pid, &source->child_status, WNOHANG); -+ if (pid > 0) -+ { -+ g_atomic_int_set (&source->child_exited, TRUE); -+ wake_source ((GSource *) source); -+ } -+ else if (pid == -1 && errno == ECHILD) -+ { -+ g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes."); -+ source->child_status = 0; -+ g_atomic_int_set (&source->child_exited, TRUE); -+ wake_source ((GSource *) source); - } -- while (pid == -1 && errno == EINTR); - } -+ while (pid == -1 && errno == EINTR); - } - } - --- -2.41.0 - - -From aaac91a86288e103f7f413b9d075acc803178da9 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 17 May 2023 08:04:02 +0200 -Subject: [PATCH 3/7] gmain: remove unnecessary initialization of - source_timeout in g_main_context_prepare_unlocked() - -Note that the variable source_timeout is already initialized upon -definition, at the beginning of the block. - -It's easy to see, that no code changes the variable between the variable -definition, and the place where it was initialized. It was thus -unnecessary. - -It's not about dropping the unnecessary code (the compiler could do that -just fine too). It's that there is the other branch of the "if/else", where -the variable is also not initialized. But the other branch also requires -that the variable is in fact initialized to -1, because prepare() -callbacks are free not to explicitly set the output value. So both -branches require the variable to be initialized to -1, but only one of -them did. This poses unnecessary questions about whether anything is -wrong. Avoid that by dropping the redundant code. ---- - glib/gmain.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index 8a030a409..28fbcc015 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -3695,10 +3695,7 @@ g_main_context_prepare (GMainContext *context, - context->in_check_or_prepare--; - } - else -- { -- source_timeout = -1; -- result = FALSE; -- } -+ result = FALSE; - - if (result == FALSE && source->priv->ready_time != -1) - { --- -2.41.0 - - -From b71ae65f14843cc09819e5b482667e5c941a27af Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 17 May 2023 08:15:16 +0200 -Subject: [PATCH 4/7] gmain: remove unnecessary initialization of *timeout in - prepare() callbacks - -Note that the prepare callback only has one caller, which pre-initializes -the timeout argument to -1. That may be an implementation detail and not -publicly promised, but it wouldn't make sense to do it any other way in -the caller. - -Also, note that g_unix_signal_watch_prepare() and the UNIX branch of -g_child_watch_prepare() already relied on that. ---- - gio/gsocket.c | 2 -- - glib/giounix.c | 2 -- - glib/giowin32.c | 2 -- - glib/gmain.c | 1 - - glib/tests/mainloop.c | 2 ++ - 5 files changed, 2 insertions(+), 7 deletions(-) - -diff --git a/gio/gsocket.c b/gio/gsocket.c -index f39a568b3..c624eb1ae 100644 ---- a/gio/gsocket.c -+++ b/gio/gsocket.c -@@ -3955,8 +3955,6 @@ socket_source_prepare (GSource *source, - { - GSocketSource *socket_source = (GSocketSource *)source; - -- *timeout = -1; -- - #ifdef G_OS_WIN32 - if ((socket_source->pollfd.revents & G_IO_NVAL) != 0) - return TRUE; -diff --git a/glib/giounix.c b/glib/giounix.c -index b86d79db7..94b33253f 100644 ---- a/glib/giounix.c -+++ b/glib/giounix.c -@@ -129,8 +129,6 @@ g_io_unix_prepare (GSource *source, - GIOUnixWatch *watch = (GIOUnixWatch *)source; - GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel); - -- *timeout = -1; -- - /* Only return TRUE here if _all_ bits in watch->condition will be set - */ - return ((watch->condition & buffer_condition) == watch->condition); -diff --git a/glib/giowin32.c b/glib/giowin32.c -index b0b6c3d85..e4b171b0d 100644 ---- a/glib/giowin32.c -+++ b/glib/giowin32.c -@@ -707,8 +707,6 @@ g_io_win32_prepare (GSource *source, - GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel; - int event_mask; - -- *timeout = -1; -- - if (channel->debug) - g_print ("g_io_win32_prepare: source=%p channel=%p", source, channel); - -diff --git a/glib/gmain.c b/glib/gmain.c -index 28fbcc015..aec04314c 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -5245,7 +5245,6 @@ g_child_watch_prepare (GSource *source, - gint *timeout) - { - #ifdef G_OS_WIN32 -- *timeout = -1; - return FALSE; - #else /* G_OS_WIN32 */ - { -diff --git a/glib/tests/mainloop.c b/glib/tests/mainloop.c -index d43b2cf08..a7c5b33d1 100644 ---- a/glib/tests/mainloop.c -+++ b/glib/tests/mainloop.c -@@ -34,6 +34,8 @@ cb (gpointer data) - static gboolean - prepare (GSource *source, gint *time) - { -+ g_assert_nonnull (time); -+ g_assert_cmpint (*time, ==, -1); - return FALSE; - } - static gboolean --- -2.41.0 - - -From ccbebd3bd2d9163da3e2ad7f213ded04cd92136d Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Tue, 28 Mar 2023 14:30:58 +0200 -Subject: [PATCH 5/7] gmain: fix race with waitpid() and child watcher sources - -GChildWatchSource uses waitpid(), among pidfd and GetExitCodeProcess(). -It thus only works for child processes which the user must ensure to -exist and not being reaped yet. Also, the user must not kill() the PID -after the child process is reaped and must not race kill() against -waitpid(). Also, the user must not call waitpid()/kill() after the child -process is reaped. - -Previously, GChildWatchSource would call waitpid() already when adding -the source (g_child_watch_source_new()) and from the worker thread -(dispatch_unix_signals_unlocked()). That is racy: - -- if a child watcher is attached and did not yet fire, you cannot call - kill() on the PID without racing against the PID being reaped on the - worker thread. That would then lead to ESRCH or even worse, killing - the wrong process. - -- if you g_source_destroy() the source that didn't fire yet, the user - doesn't know whether the PID was reaped in the background. Any - subsequent kill()/waitpid() may fail with ESRCH/ECHILD or even address - the wrong process. - -The race is most visible on Unix without pidfd support, because then the -process gets reaped on the worker thread or during g_child_watch_source_new(). -But it's also with Windows and pidfd, because we would have waited for -the process in g_child_watch_check(), where other callbacks could fire -between reaping the process status and emitting the source's callback. - -Fix all that by calling waitpid() right before dispatching the callback. ---- - glib/gmain.c | 209 +++++++++++++++++++++++++++------------------- - glib/tests/unix.c | 93 +++++++++++++++++++++ - 2 files changed, 218 insertions(+), 84 deletions(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index aec04314c..d1ab421fb 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -350,12 +350,11 @@ struct _GChildWatchSource - { - GSource source; - GPid pid; -- gint child_status; - /* @poll is always used on Windows, and used on Unix iff @using_pidfd is set: */ - GPollFD poll; - #ifndef G_OS_WIN32 -- gboolean child_exited; /* (atomic); not used iff @using_pidfd is set */ -- gboolean using_pidfd; -+ gboolean child_maybe_exited; /* (atomic) */ -+ gboolean using_pidfd; - #endif /* G_OS_WIN32 */ - }; - -@@ -5238,7 +5237,7 @@ siginfo_t_to_wait_status (const siginfo_t *info) - return W_STOPCODE (info->si_status); - } - } --#endif /* HAVE_PIDFD */ -+#endif /* HAVE_PIDFD */ - - static gboolean - g_child_watch_prepare (GSource *source, -@@ -5246,19 +5245,19 @@ g_child_watch_prepare (GSource *source, - { - #ifdef G_OS_WIN32 - return FALSE; --#else /* G_OS_WIN32 */ -+#else /* G_OS_WIN32 */ - { - GChildWatchSource *child_watch_source; - - child_watch_source = (GChildWatchSource *) source; - -- return g_atomic_int_get (&child_watch_source->child_exited); -+ return !child_watch_source->using_pidfd && g_atomic_int_get (&child_watch_source->child_maybe_exited); - } - #endif /* G_OS_WIN32 */ - } - - static gboolean --g_child_watch_check (GSource *source) -+g_child_watch_check (GSource *source) - { - GChildWatchSource *child_watch_source; - gboolean child_exited; -@@ -5267,57 +5266,15 @@ g_child_watch_check (GSource *source) - - #ifdef G_OS_WIN32 - child_exited = child_watch_source->poll.revents & G_IO_IN; -- -- if (child_exited) -- { -- DWORD child_status; -- -- /* -- * Note: We do _not_ check for the special value of STILL_ACTIVE -- * since we know that the process has exited and doing so runs into -- * problems if the child process "happens to return STILL_ACTIVE(259)" -- * as Microsoft's Platform SDK puts it. -- */ -- if (!GetExitCodeProcess (child_watch_source->pid, &child_status)) -- { -- gchar *emsg = g_win32_error_message (GetLastError ()); -- g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg); -- g_free (emsg); -- -- child_watch_source->child_status = -1; -- } -- else -- child_watch_source->child_status = child_status; -- } - #else /* G_OS_WIN32 */ - #ifdef HAVE_PIDFD - if (child_watch_source->using_pidfd) - { - child_exited = child_watch_source->poll.revents & G_IO_IN; -- -- if (child_exited) -- { -- siginfo_t child_info = { 0, }; -- -- /* Get the exit status */ -- if (waitid (P_PIDFD, child_watch_source->poll.fd, &child_info, WEXITED | WNOHANG) >= 0 && -- child_info.si_pid != 0) -- { -- /* waitid() helpfully provides the wait status in a decomposed -- * form which is quite useful. Unfortunately we have to report it -- * to the #GChildWatchFunc as a waitpid()-style platform-specific -- * wait status, so that the user code in #GChildWatchFunc can then -- * call WIFEXITED() (etc.) on it. That means re-composing the -- * status information. */ -- child_watch_source->child_status = siginfo_t_to_wait_status (&child_info); -- child_watch_source->child_exited = TRUE; -- } -- } -- - return child_exited; - } --#endif /* HAVE_PIDFD */ -- child_exited = g_atomic_int_get (&child_watch_source->child_exited); -+#endif /* HAVE_PIDFD */ -+ child_exited = g_atomic_int_get (&child_watch_source->child_maybe_exited); - #endif /* G_OS_WIN32 */ - - return child_exited; -@@ -5426,30 +5383,9 @@ dispatch_unix_signals_unlocked (void) - for (node = unix_child_watches; node; node = node->next) - { - GChildWatchSource *source = node->data; -- pid_t pid; -- -- if (g_atomic_int_get (&source->child_exited)) -- continue; - -- do -- { -- g_assert (source->pid > 0); -- -- pid = waitpid (source->pid, &source->child_status, WNOHANG); -- if (pid > 0) -- { -- g_atomic_int_set (&source->child_exited, TRUE); -- wake_source ((GSource *) source); -- } -- else if (pid == -1 && errno == ECHILD) -- { -- g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes."); -- source->child_status = 0; -- g_atomic_int_set (&source->child_exited, TRUE); -- wake_source ((GSource *) source); -- } -- } -- while (pid == -1 && errno == EINTR); -+ if (g_atomic_int_compare_and_exchange (&source->child_maybe_exited, FALSE, TRUE)) -+ wake_source ((GSource *) source); - } - } - -@@ -5662,9 +5598,106 @@ g_child_watch_dispatch (GSource *source, - { - GChildWatchSource *child_watch_source; - GChildWatchFunc child_watch_callback = (GChildWatchFunc) callback; -+ int wait_status; - - child_watch_source = (GChildWatchSource *) source; - -+ /* We only (try to) reap the child process right before dispatching the callback. -+ * That way, the caller can rely that the process is there until the callback -+ * is invoked; or, if the caller calls g_source_destroy() without the callback -+ * being dispatched, the process is still not reaped. */ -+ -+#ifdef G_OS_WIN32 -+ { -+ DWORD child_status; -+ -+ /* -+ * Note: We do _not_ check for the special value of STILL_ACTIVE -+ * since we know that the process has exited and doing so runs into -+ * problems if the child process "happens to return STILL_ACTIVE(259)" -+ * as Microsoft's Platform SDK puts it. -+ */ -+ if (!GetExitCodeProcess (child_watch_source->pid, &child_status)) -+ { -+ gchar *emsg = g_win32_error_message (GetLastError ()); -+ g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg); -+ g_free (emsg); -+ -+ /* Unknown error. We got signaled that the process might be exited, -+ * but now we failed to reap it? Assume the process is gone and proceed. */ -+ wait_status = -1; -+ } -+ else -+ wait_status = child_status; -+ } -+#else /* G_OS_WIN32 */ -+ { -+ gboolean child_exited = FALSE; -+ -+ wait_status = -1; -+ -+#ifdef HAVE_PIDFD -+ if (child_watch_source->using_pidfd) -+ { -+ siginfo_t child_info = { -+ 0, -+ }; -+ -+ /* Get the exit status */ -+ if (waitid (P_PIDFD, child_watch_source->poll.fd, &child_info, WEXITED | WNOHANG) >= 0 && -+ child_info.si_pid != 0) -+ { -+ /* waitid() helpfully provides the wait status in a decomposed -+ * form which is quite useful. Unfortunately we have to report it -+ * to the #GChildWatchFunc as a waitpid()-style platform-specific -+ * wait status, so that the user code in #GChildWatchFunc can then -+ * call WIFEXITED() (etc.) on it. That means re-composing the -+ * status information. */ -+ wait_status = siginfo_t_to_wait_status (&child_info); -+ } -+ else -+ { -+ /* Unknown error. We got signaled that the process might be exited, -+ * but now we failed to reap it? Assume the process is gone and proceed. */ -+ g_warning (G_STRLOC ": pidfd signaled ready but failed"); -+ } -+ child_exited = TRUE; -+ } -+#endif /* HAVE_PIDFD*/ -+ -+ if (!child_exited) -+ { -+ pid_t pid; -+ int wstatus; -+ -+ waitpid_again: -+ -+ /* We must reset the flag before waitpid(). Otherwise, there would be a -+ * race. */ -+ g_atomic_int_set (&child_watch_source->child_maybe_exited, FALSE); -+ -+ pid = waitpid (child_watch_source->pid, &wstatus, WNOHANG); -+ -+ if (pid == 0) -+ { -+ /* Not exited yet. Wait longer. */ -+ return TRUE; -+ } -+ -+ if (pid > 0) -+ wait_status = wstatus; -+ else if (errno == ECHILD) -+ g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes."); -+ else if (errno == EINTR) -+ goto waitpid_again; -+ else -+ { -+ /* Unexpected error. Whatever happened, we are done waiting for this child. */ -+ } -+ } -+ } -+#endif /* G_OS_WIN32 */ -+ - if (!callback) - { - g_warning ("Child watch source dispatched without callback. " -@@ -5672,7 +5705,7 @@ g_child_watch_dispatch (GSource *source, - return FALSE; - } - -- (child_watch_callback) (child_watch_source->pid, child_watch_source->child_status, user_data); -+ (child_watch_callback) (child_watch_source->pid, wait_status, user_data); - - /* We never keep a child watch source around as the child is gone */ - return FALSE; -@@ -5731,6 +5764,14 @@ g_unix_signal_handler (int signum) - * mechanism, including `waitpid(pid, ...)` or a second child-watch - * source for the same @pid - * * the application must not ignore `SIGCHLD` -+ * * Before 2.78, the application could not send a signal (`kill()`) to the -+ * watched @pid in a race free manner. Since 2.78, you can do that while the -+ * associated #GMainContext is acquired. -+ * * Before 2.78, even after destroying the #GSource, you could not -+ * be sure that @pid wasn't already reaped. Hence, it was also not -+ * safe to `kill()` or `waitpid()` on the process ID after the child watch -+ * source was gone. Destroying the source before it fired made it -+ * impossible to reliably reap the process. - * - * If any of those conditions are not met, this and related APIs will - * not work correctly. This can often be diagnosed via a GLib warning -@@ -5791,19 +5832,19 @@ g_child_watch_source_new (GPid pid) - - return source; - } -- else -- { -- g_debug ("pidfd_open(%" G_PID_FORMAT ") failed with error: %s", -- pid, g_strerror (errsv)); -- /* Fall through; likely the kernel isn’t new enough to support pidfd_open() */ -- } --#endif /* HAVE_PIDFD */ -+ -+ g_debug ("pidfd_open(%" G_PID_FORMAT ") failed with error: %s", -+ pid, g_strerror (errsv)); -+ /* Fall through; likely the kernel isn’t new enough to support pidfd_open() */ -+#endif /* HAVE_PIDFD */ -+ -+ /* We can do that without atomic, as the source is not yet added in -+ * unix_child_watches (which we do next under a lock). */ -+ child_watch_source->child_maybe_exited = TRUE; - - G_LOCK (unix_signal_lock); - ref_unix_signal_handler_unlocked (SIGCHLD); - unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source); -- if (waitpid (pid, &child_watch_source->child_status, WNOHANG) > 0) -- child_watch_source->child_exited = TRUE; - G_UNLOCK (unix_signal_lock); - #endif /* !G_OS_WIN32 */ - -diff --git a/glib/tests/unix.c b/glib/tests/unix.c -index 7639d066a..6f40ff893 100644 ---- a/glib/tests/unix.c -+++ b/glib/tests/unix.c -@@ -330,6 +330,99 @@ test_get_passwd_entry_nonexistent (void) - g_clear_error (&local_error); - } - -+static void -+_child_wait_watch_cb (GPid pid, -+ gint wait_status, -+ gpointer user_data) -+{ -+ gboolean *p_got_callback = user_data; -+ -+ g_assert_nonnull (p_got_callback); -+ g_assert_false (*p_got_callback); -+ *p_got_callback = TRUE; -+} -+ -+static void -+test_child_wait (void) -+{ -+ gboolean r; -+ GPid pid; -+ guint id; -+ pid_t pid2; -+ int wstatus; -+ gboolean got_callback = FALSE; -+ gboolean iterate_maincontext = g_test_rand_bit (); -+ char **argv; -+ int errsv; -+ -+ /* - We spawn a trivial child process that exits after a short time. -+ * - We schedule a g_child_watch_add() -+ * - we may iterate the GMainContext a bit. Randomly we either get the -+ * child-watcher callback or not. -+ * - if we didn't get the callback, we g_source_remove() the child watcher. -+ * -+ * Afterwards, if the callback didn't fire, we check that we are able to waitpid() -+ * on the process ourselves. Of course, if the child watcher notified, the waitpid() -+ * will fail with ECHILD. -+ */ -+ -+ argv = g_test_rand_bit () ? ((char *[]){ "/bin/sleep", "0.05", NULL }) : ((char *[]){ "/bin/true", NULL }); -+ -+ r = g_spawn_async (NULL, -+ argv, -+ NULL, -+ G_SPAWN_DO_NOT_REAP_CHILD, -+ NULL, -+ NULL, -+ &pid, -+ NULL); -+ if (!r) -+ { -+ /* Some odd system without /bin/sleep? Skip the test. */ -+ g_test_skip ("failure to spawn test process in test_child_wait()"); -+ return; -+ } -+ -+ g_assert_cmpint (pid, >=, 1); -+ -+ if (g_test_rand_bit ()) -+ g_usleep (g_test_rand_int_range (0, (G_USEC_PER_SEC / 10))); -+ -+ id = g_child_watch_add (pid, _child_wait_watch_cb, &got_callback); -+ -+ if (g_test_rand_bit ()) -+ g_usleep (g_test_rand_int_range (0, (G_USEC_PER_SEC / 10))); -+ -+ if (iterate_maincontext) -+ { -+ gint64 start_usec = g_get_monotonic_time (); -+ gint64 end_usec = start_usec + g_test_rand_int_range (0, (G_USEC_PER_SEC / 10)); -+ -+ while (!got_callback && g_get_monotonic_time () < end_usec) -+ g_main_context_iteration (NULL, FALSE); -+ } -+ -+ if (!got_callback) -+ g_source_remove (id); -+ -+ errno = 0; -+ pid2 = waitpid (pid, &wstatus, 0); -+ errsv = errno; -+ if (got_callback) -+ { -+ g_assert_true (iterate_maincontext); -+ g_assert_cmpint (errsv, ==, ECHILD); -+ g_assert_cmpint (pid2, <, 0); -+ } -+ else -+ { -+ g_assert_cmpint (errsv, ==, 0); -+ g_assert_cmpint (pid2, ==, pid); -+ g_assert_true (WIFEXITED (wstatus)); -+ g_assert_cmpint (WEXITSTATUS (wstatus), ==, 0); -+ } -+} -+ - int - main (int argc, - char *argv[]) --- -2.41.0 - - -From ad18d2dad0b7105a379e1b2feae653bf30418397 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Tue, 28 Mar 2023 19:53:02 +0200 -Subject: [PATCH 6/7] gmain: drop redundant using_pidfd field from - GChildWatchSource - -It's redundant, which leads to impossible code like: - - if (child_watch_source->using_pidfd) - { - if (child_watch_source->poll.fd >= 0) - close (child_watch_source->poll.fd); ---- - glib/gmain.c | 23 ++++++++++++----------- - 1 file changed, 12 insertions(+), 11 deletions(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index d1ab421fb..3813b032a 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -350,11 +350,11 @@ struct _GChildWatchSource - { - GSource source; - GPid pid; -- /* @poll is always used on Windows, and used on Unix iff @using_pidfd is set: */ -+ /* @poll is always used on Windows. -+ * On Unix, poll.fd will be negative if PIDFD is unavailable. */ - GPollFD poll; - #ifndef G_OS_WIN32 - gboolean child_maybe_exited; /* (atomic) */ -- gboolean using_pidfd; - #endif /* G_OS_WIN32 */ - }; - -@@ -5251,7 +5251,10 @@ g_child_watch_prepare (GSource *source, - - child_watch_source = (GChildWatchSource *) source; - -- return !child_watch_source->using_pidfd && g_atomic_int_get (&child_watch_source->child_maybe_exited); -+ if (child_watch_source->poll.fd >= 0) -+ return FALSE; -+ -+ return g_atomic_int_get (&child_watch_source->child_maybe_exited); - } - #endif /* G_OS_WIN32 */ - } -@@ -5268,7 +5271,7 @@ g_child_watch_check (GSource *source) - child_exited = child_watch_source->poll.revents & G_IO_IN; - #else /* G_OS_WIN32 */ - #ifdef HAVE_PIDFD -- if (child_watch_source->using_pidfd) -+ if (child_watch_source->poll.fd >= 0) - { - child_exited = child_watch_source->poll.revents & G_IO_IN; - return child_exited; -@@ -5286,10 +5289,9 @@ g_child_watch_finalize (GSource *source) - #ifndef G_OS_WIN32 - GChildWatchSource *child_watch_source = (GChildWatchSource *) source; - -- if (child_watch_source->using_pidfd) -+ if (child_watch_source->poll.fd >= 0) - { -- if (child_watch_source->poll.fd >= 0) -- close (child_watch_source->poll.fd); -+ close (child_watch_source->poll.fd); - return; - } - -@@ -5637,7 +5639,7 @@ g_child_watch_dispatch (GSource *source, - wait_status = -1; - - #ifdef HAVE_PIDFD -- if (child_watch_source->using_pidfd) -+ if (child_watch_source->poll.fd >= 0) - { - siginfo_t child_info = { - 0, -@@ -5822,17 +5824,15 @@ g_child_watch_source_new (GPid pid) - * better than SIGCHLD. - */ - child_watch_source->poll.fd = (int) syscall (SYS_pidfd_open, pid, 0); -- errsv = errno; - - if (child_watch_source->poll.fd >= 0) - { -- child_watch_source->using_pidfd = TRUE; - child_watch_source->poll.events = G_IO_IN; - g_source_add_poll (source, &child_watch_source->poll); -- - return source; - } - -+ errsv = errno; - g_debug ("pidfd_open(%" G_PID_FORMAT ") failed with error: %s", - pid, g_strerror (errsv)); - /* Fall through; likely the kernel isn’t new enough to support pidfd_open() */ -@@ -5841,6 +5841,7 @@ g_child_watch_source_new (GPid pid) - /* We can do that without atomic, as the source is not yet added in - * unix_child_watches (which we do next under a lock). */ - child_watch_source->child_maybe_exited = TRUE; -+ child_watch_source->poll.fd = -1; - - G_LOCK (unix_signal_lock); - ref_unix_signal_handler_unlocked (SIGCHLD); --- -2.41.0 - - -From bbdcc6e72ac97e577486aeb1baad0060ad8e1cd6 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 29 Mar 2023 07:51:26 +0200 -Subject: [PATCH 7/7] gmain: ensure boolean value in g_child_watch_check() is - strictly 0 or 1 - -No problem in practice, but it seems nice to ensure that a gboolean is -always either FALSE or TRUE. ---- - glib/gmain.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/glib/gmain.c b/glib/gmain.c -index 3813b032a..b6ffc6dd0 100644 ---- a/glib/gmain.c -+++ b/glib/gmain.c -@@ -5268,12 +5268,12 @@ g_child_watch_check (GSource *source) - child_watch_source = (GChildWatchSource *) source; - - #ifdef G_OS_WIN32 -- child_exited = child_watch_source->poll.revents & G_IO_IN; -+ child_exited = !!(child_watch_source->poll.revents & G_IO_IN); - #else /* G_OS_WIN32 */ - #ifdef HAVE_PIDFD - if (child_watch_source->poll.fd >= 0) - { -- child_exited = child_watch_source->poll.revents & G_IO_IN; -+ child_exited = !!(child_watch_source->poll.revents & G_IO_IN); - return child_exited; - } - #endif /* HAVE_PIDFD */ --- -2.41.0 - diff --git a/base/rx-glib2/3845.patch b/base/rx-glib2/3845.patch deleted file mode 100644 index 8cd6b01..0000000 --- a/base/rx-glib2/3845.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 37e323f1d16720d662611866cde567b1d2a01d48 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Mon, 22 Jan 2024 15:29:37 +0100 -Subject: [PATCH 1/2] gunixmounts: Use libmnt_monitor API for monitoring - -The `GUnixMountMonitor` object implements monitoring on its own currently. -Only the `/proc/mounts` file changes are monitored. It is not aware of the -`/run/mount/utab` file changes. This file contains the userspace mount -options (e.g. `x-gvfs-notrash`, `x-gvfs-hide`) among others. There is a -problem when `/sbin/mount.` (e.g. `mount.nfs`) helper programs are -used. In that case, the `/run/mount/utab` file is updated later than the -`/proc/mounts` file and thus the `GUnixMountMonitor` clients (e.g. -`gvfs-udisks2-volume-monitor`, `gvfsd-trash`) don't see the userspace -options until the next `mount-changed` signal. Let's use the `libmnt_monitor` -API for monitoring instead and emit the `mount-changed` signal also when the -`/run/mount/utab` file is changed. - -Related: https://issues.redhat.com/browse/RHEL-14607 -Related: https://github.com/util-linux/util-linux/pull/2607 ---- - gio/gunixmounts.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 71 insertions(+), 1 deletion(-) - -diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c -index 32b936259..e11b34a7d 100644 ---- a/gio/gunixmounts.c -+++ b/gio/gunixmounts.c -@@ -202,6 +202,11 @@ static GSource *proc_mounts_watch_source; - #define endmntent(f) fclose(f) - #endif - -+#ifdef HAVE_LIBMOUNT -+/* Protected by proc_mounts_source lock */ -+static struct libmnt_monitor *proc_mounts_monitor = NULL; -+#endif -+ - static gboolean - is_in (const char *value, const char *set[]) - { -@@ -1859,7 +1864,36 @@ proc_mounts_changed (GIOChannel *channel, - GIOCondition cond, - gpointer user_data) - { -+ gboolean has_changed = FALSE; -+ -+#ifdef HAVE_LIBMOUNT -+ if (cond & G_IO_IN) -+ { -+ G_LOCK (proc_mounts_source); -+ if (proc_mounts_monitor != NULL) -+ { -+ int ret; -+ -+ /* The mnt_monitor_next_change function needs to be used to avoid false-positives. */ -+ ret = mnt_monitor_next_change (proc_mounts_monitor, NULL, NULL); -+ if (ret == 0) -+ { -+ has_changed = TRUE; -+ ret = mnt_monitor_event_cleanup (proc_mounts_monitor); -+ } -+ -+ if (ret < 0) -+ g_debug ("mnt_monitor_next_change failed: %s", g_strerror (-ret)); -+ } -+ G_UNLOCK (proc_mounts_source); -+ } -+ -+#else - if (cond & G_IO_ERR) -+ has_changed = TRUE; -+#endif -+ -+ if (has_changed) - { - G_LOCK (proc_mounts_source); - mount_poller_time = (guint64) g_get_monotonic_time (); -@@ -1924,6 +1958,10 @@ mount_monitor_stop (void) - g_source_destroy (proc_mounts_watch_source); - proc_mounts_watch_source = NULL; - } -+ -+#ifdef HAVE_LIBMOUNT -+ g_clear_pointer (&proc_mounts_monitor, mnt_unref_monitor); -+#endif - G_UNLOCK (proc_mounts_source); - - if (mtab_monitor) -@@ -1965,9 +2003,37 @@ mount_monitor_start (void) - */ - if (g_str_has_prefix (mtab_path, "/proc/")) - { -- GIOChannel *proc_mounts_channel; -+ GIOChannel *proc_mounts_channel = NULL; - GError *error = NULL; -+#ifdef HAVE_LIBMOUNT -+ int ret; -+ -+ G_LOCK (proc_mounts_source); -+ -+ proc_mounts_monitor = mnt_new_monitor (); -+ ret = mnt_monitor_enable_kernel (proc_mounts_monitor, TRUE); -+ if (ret < 0) -+ g_warning ("mnt_monitor_enable_kernel failed: %s", g_strerror (-ret)); -+ -+ ret = mnt_monitor_enable_userspace (proc_mounts_monitor, TRUE, NULL); -+ if (ret < 0) -+ g_warning ("mnt_monitor_enable_userspace failed: %s", g_strerror (-ret)); -+ -+ ret = mnt_monitor_get_fd (proc_mounts_monitor); -+ if (ret >= 0) -+ { -+ proc_mounts_channel = g_io_channel_unix_new (ret); -+ } -+ else -+ { -+ g_set_error_literal (&error, G_IO_ERROR, g_io_error_from_errno (-ret), -+ g_strerror (-ret)); -+ } -+ -+ G_UNLOCK (proc_mounts_source); -+#else - proc_mounts_channel = g_io_channel_new_file (mtab_path, "r", &error); -+#endif - if (proc_mounts_channel == NULL) - { - g_warning ("Error creating IO channel for %s: %s (%s, %d)", mtab_path, -@@ -1978,7 +2044,11 @@ mount_monitor_start (void) - { - G_LOCK (proc_mounts_source); - -+#ifdef HAVE_LIBMOUNT -+ proc_mounts_watch_source = g_io_create_watch (proc_mounts_channel, G_IO_IN); -+#else - proc_mounts_watch_source = g_io_create_watch (proc_mounts_channel, G_IO_ERR); -+#endif - mount_poller_time = (guint64) g_get_monotonic_time (); - g_source_set_callback (proc_mounts_watch_source, - (GSourceFunc) proc_mounts_changed, --- -2.43.0 - - -From bb7d6b8fcef36af5452071c8758f89955888469a Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 31 Jan 2024 13:35:39 +0100 -Subject: [PATCH 2/2] gunixmounts: Use mnt_monitor_veil_kernel option - -The previous commit enabled the `/run/mount/utab` monitoring. The problem -is that the `mount-changed` signal can be emitted twice for one mount. One -for the `/proc/mounts` file change and another one for the `/run/media/utab` -file change. This is still not ideal because e.g. the `GMount` objects for -mounts with the `x-gvfs-hide` option are added and immediately removed. -Let's enable the `mnt_monitor_veil_kernel` option to avoid this. - -Related: https://github.com/util-linux/util-linux/pull/2725 ---- - gio/gunixmounts.c | 6 ++++++ - meson.build | 4 ++++ - 2 files changed, 10 insertions(+) - -diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c -index e11b34a7d..6abe87414 100644 ---- a/gio/gunixmounts.c -+++ b/gio/gunixmounts.c -@@ -2019,6 +2019,12 @@ mount_monitor_start (void) - if (ret < 0) - g_warning ("mnt_monitor_enable_userspace failed: %s", g_strerror (-ret)); - -+#ifdef HAVE_MNT_MONITOR_VEIL_KERNEL -+ ret = mnt_monitor_veil_kernel (proc_mounts_monitor, TRUE); -+ if (ret < 0) -+ g_warning ("mnt_monitor_veil_kernel failed: %s", g_strerror (-ret)); -+#endif -+ - ret = mnt_monitor_get_fd (proc_mounts_monitor); - if (ret >= 0) - { -diff --git a/meson.build b/meson.build -index a0502fe69..159703557 100644 ---- a/meson.build -+++ b/meson.build -@@ -2102,6 +2102,10 @@ libmount_dep = [] - if host_system == 'linux' - libmount_dep = dependency('mount', version : '>=2.23', required : get_option('libmount')) - glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found()) -+ -+ if libmount_dep.found() and cc.has_function('mnt_monitor_veil_kernel', dependencies: libmount_dep) -+ glib_conf.set('HAVE_MNT_MONITOR_VEIL_KERNEL', 1) -+ endif - endif - - # gnutls is used optionally by GHmac --- -2.43.0 - diff --git a/base/rx-glib2/4038.patch b/base/rx-glib2/4038.patch deleted file mode 100644 index bf1ba0f..0000000 --- a/base/rx-glib2/4038.patch +++ /dev/null @@ -1,3359 +0,0 @@ -From 82f62517eb327aa3ea255294a90911091f39d7ae Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Tue, 28 Nov 2023 12:58:20 +0000 -Subject: [PATCH 01/19] gdbusmessage: Cache the arg0 value -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Technically we can’t rely on it being kept alive by the `message->body` -pointer, unless we can guarantee that the `GVariant` is always -serialised. That’s not necessarily the case, so keep a separate ref on -the arg0 value at all times. - -This avoids a potential use-after-free. - -Spotted by Thomas Haller in -https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3720#note_1924707. - -[This is a prerequisite for having tests pass after fixing the -vulnerability described in glib#3268, because after fixing that -vulnerability, the use-after-free genuinely does happen during -regression testing. -smcv] - -Signed-off-by: Philip Withnall - -Helps: #3183, #3268 -(cherry picked from commit 10e9a917be7fb92b6b27837ef7a7f1d0be6095d5) ---- - gio/gdbusmessage.c | 35 ++++++++++++++++++++++------------- - 1 file changed, 22 insertions(+), 13 deletions(-) - -diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c -index bc9386ee7..40a77dd92 100644 ---- a/gio/gdbusmessage.c -+++ b/gio/gdbusmessage.c -@@ -471,6 +471,7 @@ struct _GDBusMessage - guint32 serial; - GHashTable *headers; - GVariant *body; -+ GVariant *arg0_cache; /* (nullable) (owned) */ - #ifdef G_OS_UNIX - GUnixFDList *fd_list; - #endif -@@ -493,6 +494,7 @@ g_dbus_message_finalize (GObject *object) - g_hash_table_unref (message->headers); - if (message->body != NULL) - g_variant_unref (message->body); -+ g_clear_pointer (&message->arg0_cache, g_variant_unref); - #ifdef G_OS_UNIX - if (message->fd_list != NULL) - g_object_unref (message->fd_list); -@@ -1128,6 +1130,7 @@ g_dbus_message_set_body (GDBusMessage *message, - if (body == NULL) - { - message->body = NULL; -+ message->arg0_cache = NULL; - g_dbus_message_set_signature (message, NULL); - } - else -@@ -1138,6 +1141,12 @@ g_dbus_message_set_body (GDBusMessage *message, - - message->body = g_variant_ref_sink (body); - -+ if (g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE) && -+ g_variant_n_children (message->body) > 0) -+ message->arg0_cache = g_variant_get_child_value (message->body, 0); -+ else -+ message->arg0_cache = NULL; -+ - type_string = g_variant_get_type_string (body); - type_string_len = strlen (type_string); - g_assert (type_string_len >= 2); -@@ -2230,6 +2239,14 @@ g_dbus_message_new_from_blob (guchar *blob, - 2, - error); - g_variant_type_free (variant_type); -+ -+ if (message->body != NULL && -+ g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE) && -+ g_variant_n_children (message->body) > 0) -+ message->arg0_cache = g_variant_get_child_value (message->body, 0); -+ else -+ message->arg0_cache = NULL; -+ - if (message->body == NULL) - goto out; - } -@@ -3265,22 +3282,13 @@ g_dbus_message_set_signature (GDBusMessage *message, - const gchar * - g_dbus_message_get_arg0 (GDBusMessage *message) - { -- const gchar *ret; -- - g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); - -- ret = NULL; -+ if (message->arg0_cache != NULL && -+ g_variant_is_of_type (message->arg0_cache, G_VARIANT_TYPE_STRING)) -+ return g_variant_get_string (message->arg0_cache, NULL); - -- if (message->body != NULL && g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE)) -- { -- GVariant *item; -- item = g_variant_get_child_value (message->body, 0); -- if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING)) -- ret = g_variant_get_string (item, NULL); -- g_variant_unref (item); -- } -- -- return ret; -+ return NULL; - } - - /* ---------------------------------------------------------------------------------------------------- */ -@@ -3723,6 +3731,7 @@ g_dbus_message_copy (GDBusMessage *message, - * to just ref (as opposed to deep-copying) the GVariant instances - */ - ret->body = message->body != NULL ? g_variant_ref (message->body) : NULL; -+ ret->arg0_cache = message->arg0_cache != NULL ? g_variant_ref (message->arg0_cache) : NULL; - g_hash_table_iter_init (&iter, message->headers); - while (g_hash_table_iter_next (&iter, &header_key, (gpointer) &header_value)) - g_hash_table_insert (ret->headers, header_key, g_variant_ref (header_value)); --- -2.45.0 - - -From 3649ce253433149dea16d158542e7285655eb182 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Wed, 1 May 2024 15:51:42 +0100 -Subject: [PATCH 02/19] gdbusconnection: Make a backport of g_set_str() - available - -A subsequent commit will need this. Copying all of g_set_str() into a -private header seems cleaner than replacing the call to it. - -Helps: GNOME/glib#3268 -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 1 + - glib/glib-private.h | 18 ++++++++++++++++++ - 2 files changed, 19 insertions(+) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index a37611275..2808b1e46 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -95,6 +95,7 @@ - #include - #include - -+#include "glib-private.h" - #include "gdbusauth.h" - #include "gdbusutils.h" - #include "gdbusaddress.h" -diff --git a/glib/glib-private.h b/glib/glib-private.h -index 8de380d12..acdfa4911 100644 ---- a/glib/glib-private.h -+++ b/glib/glib-private.h -@@ -161,4 +161,22 @@ GLibPrivateVTable *glib__private__ (void); - # define GLIB_DEFAULT_LOCALE "" - #endif - -+/* Backported from GLib 2.78.x, where it is public API in gstrfuncs.h */ -+static inline gboolean -+g_set_str (char **str_pointer, -+ const char *new_str) -+{ -+ char *copy; -+ -+ if (*str_pointer == new_str || -+ (*str_pointer && new_str && strcmp (*str_pointer, new_str) == 0)) -+ return FALSE; -+ -+ copy = g_strdup (new_str); -+ g_free (*str_pointer); -+ *str_pointer = copy; -+ -+ return TRUE; -+} -+ - #endif /* __GLIB_PRIVATE_H__ */ --- -2.45.0 - - -From cef2cd7a033d3df50a8b5b3db28df93feb1d14a9 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Fri, 8 Mar 2024 14:19:46 +0000 -Subject: [PATCH 03/19] tests: Add a data-driven test for signal subscriptions - -This somewhat duplicates test_connection_signals(), but is easier to -extend to cover different scenarios. - -Each scenario is tested three times: once with lower-level -GDBusConnection APIs, once with the higher-level GDBusProxy (which -cannot implement all of the subscription scenarios, so some message -counts are lower), and once with both (to check that delivery of the -same message to multiple destinations is handled appropriately). - -[Backported to glib-2-74, resolving conflicts in gio/tests/meson.build] -Signed-off-by: Simon McVittie ---- - gio/tests/gdbus-subscribe.c | 938 ++++++++++++++++++++++++++++++++++++ - gio/tests/meson.build | 1 + - 2 files changed, 939 insertions(+) - create mode 100644 gio/tests/gdbus-subscribe.c - -diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c -new file mode 100644 -index 000000000..3f53e1d7f ---- /dev/null -+++ b/gio/tests/gdbus-subscribe.c -@@ -0,0 +1,938 @@ -+/* -+ * Copyright 2024 Collabora Ltd. -+ * SPDX-License-Identifier: LGPL-2.1-or-later -+ */ -+ -+#include -+ -+#include "gdbus-tests.h" -+ -+#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" -+#define DBUS_PATH_DBUS "/org/freedesktop/DBus" -+#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS -+ -+/* A signal that each connection emits to indicate that it has finished -+ * emitting other signals */ -+#define FINISHED_PATH "/org/gtk/Test/Finished" -+#define FINISHED_INTERFACE "org.gtk.Test.Finished" -+#define FINISHED_SIGNAL "Finished" -+ -+/* A signal emitted during testing */ -+#define EXAMPLE_PATH "/org/gtk/GDBus/ExampleInterface" -+#define EXAMPLE_INTERFACE "org.gtk.GDBus.ExampleInterface" -+#define FOO_SIGNAL "Foo" -+ -+/* Log @s in a debug message. */ -+static inline const char * -+nonnull (const char *s, -+ const char *if_null) -+{ -+ return (s == NULL) ? if_null : s; -+} -+ -+typedef enum -+{ -+ TEST_CONN_NONE, -+ TEST_CONN_FIRST, -+ /* A connection that subscribes to signals */ -+ TEST_CONN_SUBSCRIBER = TEST_CONN_FIRST, -+ /* A mockup of a legitimate service */ -+ TEST_CONN_SERVICE, -+ /* A mockup of a second legitimate service */ -+ TEST_CONN_SERVICE2, -+ /* A connection that tries to trick @subscriber into processing its signals -+ * as if they came from @service */ -+ TEST_CONN_ATTACKER, -+ NUM_TEST_CONNS -+} TestConn; -+ -+static const char * const test_conn_descriptions[NUM_TEST_CONNS] = -+{ -+ "(unused)", -+ "subscriber", -+ "service", -+ "service 2", -+ "attacker" -+}; -+ -+typedef enum -+{ -+ SUBSCRIPTION_MODE_CONN, -+ SUBSCRIPTION_MODE_PROXY, -+ SUBSCRIPTION_MODE_PARALLEL -+} SubscriptionMode; -+ -+typedef struct -+{ -+ GDBusProxy *received_by_proxy; -+ TestConn sender; -+ char *path; -+ char *iface; -+ char *member; -+ GVariant *parameters; -+ char *arg0; -+ guint32 step; -+} ReceivedMessage; -+ -+static void -+received_message_free (ReceivedMessage *self) -+{ -+ -+ g_clear_object (&self->received_by_proxy); -+ g_free (self->path); -+ g_free (self->iface); -+ g_free (self->member); -+ g_clear_pointer (&self->parameters, g_variant_unref); -+ g_free (self->arg0); -+ g_free (self); -+} -+ -+typedef struct -+{ -+ TestConn sender; -+ TestConn unicast_to; -+ const char *path; -+ const char *iface; -+ const char *member; -+ const char *arg0; -+ guint received_by_conn; -+ guint received_by_proxy; -+} TestEmitSignal; -+ -+typedef struct -+{ -+ TestConn sender; -+ const char *path; -+ const char *iface; -+ const char *member; -+ const char *arg0; -+ GDBusSignalFlags flags; -+} TestSubscribe; -+ -+typedef enum -+{ -+ TEST_ACTION_NONE = 0, -+ TEST_ACTION_SUBSCRIBE, -+ TEST_ACTION_EMIT_SIGNAL, -+} TestAction; -+ -+typedef struct -+{ -+ TestAction action; -+ union { -+ TestEmitSignal signal; -+ TestSubscribe subscribe; -+ } u; -+} TestStep; -+ -+/* Arbitrary, extend as necessary to accommodate the longest test */ -+#define MAX_TEST_STEPS 10 -+ -+typedef struct -+{ -+ const char *description; -+ TestStep steps[MAX_TEST_STEPS]; -+} TestPlan; -+ -+static const TestPlan plan_simple = -+{ -+ .description = "A broadcast is only received after subscribing to it", -+ .steps = { -+ { -+ /* We don't receive a signal if we haven't subscribed yet */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ /* Now it works */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 1, -+ /* The proxy can't be used in this case, because it needs -+ * a bus name to subscribe to */ -+ .received_by_proxy = 0 -+ }, -+ }, -+ }, -+}; -+ -+static const TestPlan plan_broadcast_from_anyone = -+{ -+ .description = "A subscription with NULL sender accepts broadcast and unicast", -+ .steps = { -+ { -+ /* Subscriber wants to receive signals from anyone */ -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ /* First service sends a broadcast */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 1, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* Second service also sends a broadcast */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE2, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 1, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* First service sends a unicast signal */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .unicast_to = TEST_CONN_SUBSCRIBER, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 1, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* Second service also sends a unicast signal */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE2, -+ .unicast_to = TEST_CONN_SUBSCRIBER, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 1, -+ .received_by_proxy = 0 -+ }, -+ }, -+ }, -+}; -+ -+static const TestPlan plan_match_twice = -+{ -+ .description = "A message matching more than one subscription is received " -+ "once per subscription", -+ .steps = { -+ { -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .path = EXAMPLE_PATH, -+ }, -+ }, -+ { -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 4, -+ /* Only the first and last work with GDBusProxy */ -+ .received_by_proxy = 2 -+ }, -+ }, -+ }, -+}; -+ -+static const TestPlan plan_limit_by_unique_name = -+{ -+ .description = "A subscription via a unique name only accepts messages " -+ "sent by that same unique name", -+ .steps = { -+ { -+ /* Subscriber wants to receive signals from service */ -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ /* Attacker wants to trick subscriber into thinking that service -+ * sent a signal */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_ATTACKER, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* Attacker tries harder, by sending a signal unicast directly to -+ * the subscriber */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_ATTACKER, -+ .unicast_to = TEST_CONN_SUBSCRIBER, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* When the real service sends a signal, it should still get through */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 1, -+ .received_by_proxy = 1 -+ }, -+ }, -+ }, -+}; -+ -+typedef struct -+{ -+ const TestPlan *plan; -+ SubscriptionMode mode; -+ GError *error; -+ /* (element-type ReceivedMessage) */ -+ GPtrArray *received; -+ /* conns[TEST_CONN_NONE] is unused and remains NULL */ -+ GDBusConnection *conns[NUM_TEST_CONNS]; -+ /* Proxies on conns[TEST_CONN_SUBSCRIBER] */ -+ GPtrArray *proxies; -+ /* unique_names[TEST_CONN_NONE] is unused and remains NULL */ -+ const char *unique_names[NUM_TEST_CONNS]; -+ /* finished[TEST_CONN_NONE] is unused and remains FALSE */ -+ gboolean finished[NUM_TEST_CONNS]; -+ /* Remains 0 for any step that is not a subscription */ -+ guint subscriptions[MAX_TEST_STEPS]; -+ /* Number of times the signal from step n was received */ -+ guint received_by_conn[MAX_TEST_STEPS]; -+ /* Number of times the signal from step n was received */ -+ guint received_by_proxy[MAX_TEST_STEPS]; -+ guint finished_subscription; -+} Fixture; -+ -+/* Wait for asynchronous messages from @conn to have been processed -+ * by the message bus, as a sequence point so that we can make -+ * "happens before" and "happens after" assertions relative to this. -+ * The easiest way to achieve this is to call a message bus method that has -+ * no arguments and wait for it to return: because the message bus processes -+ * messages in-order, anything we sent before this must have been processed -+ * by the time this call arrives. */ -+static void -+connection_wait_for_bus (GDBusConnection *conn) -+{ -+ GError *error = NULL; -+ GVariant *call_result; -+ -+ call_result = g_dbus_connection_call_sync (conn, -+ DBUS_SERVICE_DBUS, -+ DBUS_PATH_DBUS, -+ DBUS_INTERFACE_DBUS, -+ "GetId", -+ NULL, /* arguments */ -+ NULL, /* result type */ -+ G_DBUS_CALL_FLAGS_NONE, -+ -1, -+ NULL, -+ &error); -+ g_assert_no_error (error); -+ g_assert_nonnull (call_result); -+ g_variant_unref (call_result); -+} -+ -+/* -+ * Called when the subscriber receives a message from any connection -+ * announcing that it has emitted all the signals that it plans to emit. -+ */ -+static void -+subscriber_finished_cb (GDBusConnection *conn, -+ const char *sender_name, -+ const char *path, -+ const char *iface, -+ const char *member, -+ GVariant *parameters, -+ void *user_data) -+{ -+ Fixture *f = user_data; -+ GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER]; -+ guint i; -+ -+ g_assert_true (conn == subscriber); -+ -+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++) -+ { -+ if (g_str_equal (sender_name, f->unique_names[i])) -+ { -+ g_assert_false (f->finished[i]); -+ f->finished[i] = TRUE; -+ -+ g_test_message ("Received Finished signal from %s %s", -+ test_conn_descriptions[i], sender_name); -+ return; -+ } -+ } -+ -+ g_error ("Received Finished signal from unknown sender %s", sender_name); -+} -+ -+/* -+ * Called when we receive a signal, either via the GDBusProxy (proxy != NULL) -+ * or via the GDBusConnection (proxy == NULL). -+ */ -+static void -+fixture_received_signal (Fixture *f, -+ GDBusProxy *proxy, -+ const char *sender_name, -+ const char *path, -+ const char *iface, -+ const char *member, -+ GVariant *parameters) -+{ -+ guint i; -+ ReceivedMessage *received; -+ -+ /* Ignore the Finished signal if it matches a wildcard subscription */ -+ if (g_str_equal (member, FINISHED_SIGNAL)) -+ return; -+ -+ received = g_new0 (ReceivedMessage, 1); -+ -+ if (proxy != NULL) -+ received->received_by_proxy = g_object_ref (proxy); -+ else -+ received->received_by_proxy = NULL; -+ -+ received->path = g_strdup (path); -+ received->iface = g_strdup (iface); -+ received->member = g_strdup (member); -+ received->parameters = g_variant_ref (parameters); -+ -+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++) -+ { -+ if (g_str_equal (sender_name, f->unique_names[i])) -+ { -+ received->sender = i; -+ g_assert_false (f->finished[i]); -+ break; -+ } -+ } -+ -+ g_assert_cmpint (received->sender, !=, TEST_CONN_NONE); -+ -+ g_test_message ("Signal received from %s %s via %s", -+ test_conn_descriptions[received->sender], -+ sender_name, -+ proxy != NULL ? "proxy" : "connection"); -+ g_test_message ("\tPath: %s", path); -+ g_test_message ("\tInterface: %s", iface); -+ g_test_message ("\tMember: %s", member); -+ -+ if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(su)"))) -+ { -+ g_variant_get (parameters, "(su)", &received->arg0, &received->step); -+ g_test_message ("\tString argument 0: %s", received->arg0); -+ g_test_message ("\tSent in step: %u", received->step); -+ } -+ else -+ { -+ g_assert_cmpstr (g_variant_get_type_string (parameters), ==, "(uu)"); -+ g_variant_get (parameters, "(uu)", NULL, &received->step); -+ g_test_message ("\tArgument 0: (not a string)"); -+ g_test_message ("\tSent in step: %u", received->step); -+ } -+ -+ g_ptr_array_add (f->received, g_steal_pointer (&received)); -+} -+ -+static void -+proxy_signal_cb (GDBusProxy *proxy, -+ const char *sender_name, -+ const char *member, -+ GVariant *parameters, -+ void *user_data) -+{ -+ Fixture *f = user_data; -+ -+ fixture_received_signal (f, proxy, sender_name, -+ g_dbus_proxy_get_object_path (proxy), -+ g_dbus_proxy_get_interface_name (proxy), -+ member, parameters); -+} -+ -+static void -+subscribed_signal_cb (GDBusConnection *conn, -+ const char *sender_name, -+ const char *path, -+ const char *iface, -+ const char *member, -+ GVariant *parameters, -+ void *user_data) -+{ -+ Fixture *f = user_data; -+ GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER]; -+ -+ g_assert_true (conn == subscriber); -+ -+ fixture_received_signal (f, NULL, sender_name, path, iface, member, parameters); -+} -+ -+static void -+fixture_subscribe (Fixture *f, -+ const TestSubscribe *subscribe, -+ guint step_number) -+{ -+ GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER]; -+ const char *sender; -+ -+ if (subscribe->sender != TEST_CONN_NONE) -+ { -+ sender = f->unique_names[subscribe->sender]; -+ g_test_message ("\tSender: %s %s", -+ test_conn_descriptions[subscribe->sender], -+ sender); -+ } -+ else -+ { -+ sender = NULL; -+ g_test_message ("\tSender: (any)"); -+ } -+ -+ g_test_message ("\tPath: %s", nonnull (subscribe->path, "(any)")); -+ g_test_message ("\tInterface: %s", -+ nonnull (subscribe->iface, "(any)")); -+ g_test_message ("\tMember: %s", -+ nonnull (subscribe->member, "(any)")); -+ g_test_message ("\tString argument 0: %s", -+ nonnull (subscribe->arg0, "(any)")); -+ g_test_message ("\tFlags: %x", subscribe->flags); -+ -+ if (f->mode != SUBSCRIPTION_MODE_PROXY) -+ { -+ /* CONN or PARALLEL */ -+ guint id; -+ -+ g_test_message ("\tSubscribing via connection"); -+ id = g_dbus_connection_signal_subscribe (subscriber, -+ sender, -+ subscribe->iface, -+ subscribe->member, -+ subscribe->path, -+ subscribe->arg0, -+ subscribe->flags, -+ subscribed_signal_cb, -+ f, NULL); -+ g_assert_cmpuint (id, !=, 0); -+ f->subscriptions[step_number] = id; -+ } -+ -+ if (f->mode != SUBSCRIPTION_MODE_CONN) -+ { -+ /* PROXY or PARALLEL */ -+ -+ if (sender == NULL) -+ { -+ g_test_message ("\tCannot subscribe via proxy: no bus name"); -+ } -+ else if (subscribe->path == NULL) -+ { -+ g_test_message ("\tCannot subscribe via proxy: no path"); -+ } -+ else if (subscribe->iface == NULL) -+ { -+ g_test_message ("\tCannot subscribe via proxy: no interface"); -+ } -+ else -+ { -+ GDBusProxy *proxy; -+ -+ g_test_message ("\tSubscribing via proxy"); -+ proxy = g_dbus_proxy_new_sync (subscriber, -+ (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES -+ | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START), -+ NULL, /* GDBusInterfaceInfo */ -+ sender, -+ subscribe->path, -+ subscribe->iface, -+ NULL, /* GCancellable */ -+ &f->error); -+ g_assert_no_error (f->error); -+ g_assert_nonnull (proxy); -+ g_signal_connect (proxy, "g-signal", G_CALLBACK (proxy_signal_cb), f); -+ g_ptr_array_add (f->proxies, g_steal_pointer (&proxy)); -+ } -+ } -+ -+ /* As in setup(), we need to wait for AddMatch to happen. */ -+ g_test_message ("Waiting for AddMatch to be processed"); -+ connection_wait_for_bus (subscriber); -+} -+ -+static void -+fixture_emit_signal (Fixture *f, -+ const TestEmitSignal *signal, -+ guint step_number) -+{ -+ GVariant *body; -+ const char *destination; -+ gboolean ok; -+ -+ g_test_message ("\tSender: %s", -+ test_conn_descriptions[signal->sender]); -+ -+ if (signal->unicast_to != TEST_CONN_NONE) -+ { -+ destination = f->unique_names[signal->unicast_to]; -+ g_test_message ("\tDestination: %s %s", -+ test_conn_descriptions[signal->unicast_to], -+ destination); -+ } -+ else -+ { -+ destination = NULL; -+ g_test_message ("\tDestination: (broadcast)"); -+ } -+ -+ g_assert_nonnull (signal->path); -+ g_test_message ("\tPath: %s", signal->path); -+ g_assert_nonnull (signal->iface); -+ g_test_message ("\tInterface: %s", signal->iface); -+ g_assert_nonnull (signal->member); -+ g_test_message ("\tMember: %s", signal->member); -+ -+ /* If arg0 is non-NULL, put it in the message's argument 0. -+ * Otherwise put something that will not match any arg0. -+ * Either way, put the sequence number in argument 1 so we can -+ * correlate sent messages with received messages later. */ -+ if (signal->arg0 != NULL) -+ { -+ g_test_message ("\tString argument 0: %s", signal->arg0); -+ /* floating */ -+ body = g_variant_new ("(su)", signal->arg0, (guint32) step_number); -+ } -+ else -+ { -+ g_test_message ("\tArgument 0: (not a string)"); -+ body = g_variant_new ("(uu)", (guint32) 0, (guint32) step_number); -+ } -+ -+ ok = g_dbus_connection_emit_signal (f->conns[signal->sender], -+ destination, -+ signal->path, -+ signal->iface, -+ signal->member, -+ /* steals floating reference */ -+ g_steal_pointer (&body), -+ &f->error); -+ g_assert_no_error (f->error); -+ g_assert_true (ok); -+ -+ /* Emitting the signal is asynchronous, so if we want subsequent steps -+ * to be guaranteed to happen after the signal from the message bus's -+ * perspective, we have to do a round-trip to the message bus to sync up. */ -+ g_test_message ("Waiting for signal to reach message bus"); -+ connection_wait_for_bus (f->conns[signal->sender]); -+} -+ -+static void -+fixture_run_plan (Fixture *f, -+ const TestPlan *plan, -+ SubscriptionMode mode) -+{ -+ guint i; -+ -+ G_STATIC_ASSERT (G_N_ELEMENTS (plan->steps) == G_N_ELEMENTS (f->subscriptions)); -+ G_STATIC_ASSERT (G_N_ELEMENTS (plan->steps) == G_N_ELEMENTS (f->received_by_conn)); -+ G_STATIC_ASSERT (G_N_ELEMENTS (plan->steps) == G_N_ELEMENTS (f->received_by_proxy)); -+ -+ f->mode = mode; -+ f->plan = plan; -+ -+ g_test_summary (plan->description); -+ -+ for (i = 0; i < G_N_ELEMENTS (plan->steps); i++) -+ { -+ const TestStep *step = &plan->steps[i]; -+ -+ switch (step->action) -+ { -+ case TEST_ACTION_SUBSCRIBE: -+ g_test_message ("Step %u: adding subscription", i); -+ fixture_subscribe (f, &step->u.subscribe, i); -+ break; -+ -+ case TEST_ACTION_EMIT_SIGNAL: -+ g_test_message ("Step %u: emitting signal", i); -+ fixture_emit_signal (f, &step->u.signal, i); -+ break; -+ -+ case TEST_ACTION_NONE: -+ /* Padding to fill the rest of the array, do nothing */ -+ break; -+ -+ default: -+ g_return_if_reached (); -+ } -+ } -+ -+ /* Now that we have done everything we wanted to do, emit Finished -+ * from each connection. */ -+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++) -+ { -+ gboolean ok; -+ -+ ok = g_dbus_connection_emit_signal (f->conns[i], -+ NULL, -+ FINISHED_PATH, -+ FINISHED_INTERFACE, -+ FINISHED_SIGNAL, -+ NULL, -+ &f->error); -+ g_assert_no_error (f->error); -+ g_assert_true (ok); -+ } -+ -+ /* Wait until we have seen the Finished signal from each sender */ -+ while (TRUE) -+ { -+ gboolean all_finished = TRUE; -+ -+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++) -+ all_finished = all_finished && f->finished[i]; -+ -+ if (all_finished) -+ break; -+ -+ g_main_context_iteration (NULL, TRUE); -+ } -+ -+ /* Assert that the correct things happened before each Finished signal */ -+ for (i = 0; i < f->received->len; i++) -+ { -+ const ReceivedMessage *received = g_ptr_array_index (f->received, i); -+ -+ g_assert_cmpuint (received->step, <, G_N_ELEMENTS (f->received_by_conn)); -+ g_assert_cmpuint (received->step, <, G_N_ELEMENTS (f->received_by_proxy)); -+ g_assert_cmpint (plan->steps[received->step].action, -+ ==, TEST_ACTION_EMIT_SIGNAL); -+ -+ if (received->received_by_proxy != NULL) -+ f->received_by_proxy[received->step] += 1; -+ else -+ f->received_by_conn[received->step] += 1; -+ } -+ -+ for (i = 0; i < G_N_ELEMENTS (plan->steps); i++) -+ { -+ const TestStep *step = &plan->steps[i]; -+ -+ if (step->action == TEST_ACTION_EMIT_SIGNAL) -+ { -+ const TestEmitSignal *signal = &plan->steps[i].u.signal; -+ -+ if (mode != SUBSCRIPTION_MODE_PROXY) -+ { -+ g_test_message ("Signal from step %u was received %u times by " -+ "GDBusConnection, expected %u", -+ i, f->received_by_conn[i], signal->received_by_conn); -+ g_assert_cmpuint (f->received_by_conn[i], ==, signal->received_by_conn); -+ } -+ else -+ { -+ g_assert_cmpuint (f->received_by_conn[i], ==, 0); -+ } -+ -+ if (mode != SUBSCRIPTION_MODE_CONN) -+ { -+ g_test_message ("Signal from step %u was received %u times by " -+ "GDBusProxy, expected %u", -+ i, f->received_by_proxy[i], signal->received_by_proxy); -+ g_assert_cmpuint (f->received_by_proxy[i], ==, signal->received_by_proxy); -+ } -+ else -+ { -+ g_assert_cmpuint (f->received_by_proxy[i], ==, 0); -+ } -+ } -+ } -+} -+ -+static void -+setup (Fixture *f, -+ G_GNUC_UNUSED const void *context) -+{ -+ GDBusConnection *subscriber; -+ guint i; -+ -+ session_bus_up (); -+ -+ f->proxies = g_ptr_array_new_full (MAX_TEST_STEPS, g_object_unref); -+ f->received = g_ptr_array_new_full (MAX_TEST_STEPS, -+ (GDestroyNotify) received_message_free); -+ -+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++) -+ { -+ f->conns[i] = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &f->error); -+ g_assert_no_error (f->error); -+ g_assert_nonnull (f->conns[i]); -+ -+ f->unique_names[i] = g_dbus_connection_get_unique_name (f->conns[i]); -+ g_assert_nonnull (f->unique_names[i]); -+ g_test_message ("%s is %s", -+ test_conn_descriptions[i], -+ f->unique_names[i]); -+ } -+ -+ subscriber = f->conns[TEST_CONN_SUBSCRIBER]; -+ -+ /* Used to wait for all connections to finish sending whatever they -+ * wanted to send */ -+ f->finished_subscription = g_dbus_connection_signal_subscribe (subscriber, -+ NULL, -+ FINISHED_INTERFACE, -+ FINISHED_SIGNAL, -+ FINISHED_PATH, -+ NULL, -+ G_DBUS_SIGNAL_FLAGS_NONE, -+ subscriber_finished_cb, -+ f, NULL); -+ /* AddMatch is sent asynchronously, so we don't know how -+ * soon it will be processed. Before emitting signals, we -+ * need to wait for the message bus to get as far as processing -+ * AddMatch. */ -+ g_test_message ("Waiting for AddMatch to be processed"); -+ connection_wait_for_bus (subscriber); -+} -+ -+static void -+test_conn_subscribe (Fixture *f, -+ const void *context) -+{ -+ fixture_run_plan (f, context, SUBSCRIPTION_MODE_CONN); -+} -+ -+static void -+test_proxy_subscribe (Fixture *f, -+ const void *context) -+{ -+ fixture_run_plan (f, context, SUBSCRIPTION_MODE_PROXY); -+} -+ -+static void -+test_parallel_subscribe (Fixture *f, -+ const void *context) -+{ -+ fixture_run_plan (f, context, SUBSCRIPTION_MODE_PARALLEL); -+} -+ -+static void -+teardown (Fixture *f, -+ G_GNUC_UNUSED const void *context) -+{ -+ GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER]; -+ guint i; -+ -+ g_ptr_array_unref (f->proxies); -+ -+ if (f->finished_subscription != 0) -+ g_dbus_connection_signal_unsubscribe (subscriber, f->finished_subscription); -+ -+ for (i = 0; i < G_N_ELEMENTS (f->subscriptions); i++) -+ { -+ if (f->subscriptions[i] != 0) -+ g_dbus_connection_signal_unsubscribe (subscriber, f->subscriptions[i]); -+ } -+ -+ g_ptr_array_unref (f->received); -+ -+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++) -+ g_clear_object (&f->conns[i]); -+ -+ g_clear_error (&f->error); -+ -+ session_bus_down (); -+} -+ -+int -+main (int argc, -+ char *argv[]) -+{ -+ g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); -+ -+ g_test_dbus_unset (); -+ -+#define ADD_SUBSCRIBE_TEST(name) \ -+ do { \ -+ g_test_add ("/gdbus/subscribe/conn/" #name, \ -+ Fixture, &plan_ ## name, \ -+ setup, test_conn_subscribe, teardown); \ -+ g_test_add ("/gdbus/subscribe/proxy/" #name, \ -+ Fixture, &plan_ ## name, \ -+ setup, test_proxy_subscribe, teardown); \ -+ g_test_add ("/gdbus/subscribe/parallel/" #name, \ -+ Fixture, &plan_ ## name, \ -+ setup, test_parallel_subscribe, teardown); \ -+ } while (0) -+ -+ ADD_SUBSCRIBE_TEST (simple); -+ ADD_SUBSCRIBE_TEST (broadcast_from_anyone); -+ ADD_SUBSCRIBE_TEST (match_twice); -+ ADD_SUBSCRIBE_TEST (limit_by_unique_name); -+ -+ return g_test_run(); -+} -diff --git a/gio/tests/meson.build b/gio/tests/meson.build -index e1f583c70..1cd55e4ad 100644 ---- a/gio/tests/meson.build -+++ b/gio/tests/meson.build -@@ -314,6 +314,7 @@ if host_machine.system() != 'windows' - }, - 'gdbus-proxy-unique-name' : {'extra_sources' : extra_sources}, - 'gdbus-proxy-well-known-name' : {'extra_sources' : extra_sources}, -+ 'gdbus-subscribe' : {'extra_sources' : extra_sources}, - 'gdbus-test-codegen' : { - 'extra_sources' : [extra_sources, gdbus_test_codegen_generated, gdbus_test_codegen_generated_interface_info], - 'c_args' : ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'], --- -2.45.0 - - -From 38ee87713f8cc99c67ef00a4960027676cc16b25 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Fri, 8 Mar 2024 19:28:15 +0000 -Subject: [PATCH 04/19] tests: Add support for subscribing to signals from a - well-known name - -Signed-off-by: Simon McVittie ---- - gio/tests/gdbus-subscribe.c | 133 ++++++++++++++++++++++++++++++++++-- - 1 file changed, 126 insertions(+), 7 deletions(-) - -diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c -index 3f53e1d7f..3d2a14e03 100644 ---- a/gio/tests/gdbus-subscribe.c -+++ b/gio/tests/gdbus-subscribe.c -@@ -7,6 +7,9 @@ - - #include "gdbus-tests.h" - -+/* From the D-Bus Specification */ -+#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 -+ - #define DBUS_SERVICE_DBUS "org.freedesktop.DBus" - #define DBUS_PATH_DBUS "/org/freedesktop/DBus" - #define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS -@@ -22,6 +25,9 @@ - #define EXAMPLE_INTERFACE "org.gtk.GDBus.ExampleInterface" - #define FOO_SIGNAL "Foo" - -+#define ALREADY_OWNED_NAME "org.gtk.Test.AlreadyOwned" -+#define OWNED_LATER_NAME "org.gtk.Test.OwnedLater" -+ - /* Log @s in a debug message. */ - static inline const char * - nonnull (const char *s, -@@ -101,7 +107,8 @@ typedef struct - - typedef struct - { -- TestConn sender; -+ const char *string_sender; -+ TestConn unique_sender; - const char *path; - const char *iface; - const char *member; -@@ -109,11 +116,18 @@ typedef struct - GDBusSignalFlags flags; - } TestSubscribe; - -+typedef struct -+{ -+ const char *name; -+ TestConn owner; -+} TestOwnName; -+ - typedef enum - { - TEST_ACTION_NONE = 0, - TEST_ACTION_SUBSCRIBE, - TEST_ACTION_EMIT_SIGNAL, -+ TEST_ACTION_OWN_NAME, - } TestAction; - - typedef struct -@@ -122,6 +136,7 @@ typedef struct - union { - TestEmitSignal signal; - TestSubscribe subscribe; -+ TestOwnName own_name; - } u; - } TestStep; - -@@ -247,7 +262,7 @@ static const TestPlan plan_match_twice = - { - .action = TEST_ACTION_SUBSCRIBE, - .u.subscribe = { -- .sender = TEST_CONN_SERVICE, -+ .unique_sender = TEST_CONN_SERVICE, - .path = EXAMPLE_PATH, - .iface = EXAMPLE_INTERFACE, - }, -@@ -267,7 +282,7 @@ static const TestPlan plan_match_twice = - { - .action = TEST_ACTION_SUBSCRIBE, - .u.subscribe = { -- .sender = TEST_CONN_SERVICE, -+ .unique_sender = TEST_CONN_SERVICE, - .path = EXAMPLE_PATH, - .iface = EXAMPLE_INTERFACE, - }, -@@ -296,7 +311,7 @@ static const TestPlan plan_limit_by_unique_name = - /* Subscriber wants to receive signals from service */ - .action = TEST_ACTION_SUBSCRIBE, - .u.subscribe = { -- .sender = TEST_CONN_SERVICE, -+ .unique_sender = TEST_CONN_SERVICE, - .path = EXAMPLE_PATH, - .iface = EXAMPLE_INTERFACE, - }, -@@ -343,6 +358,62 @@ static const TestPlan plan_limit_by_unique_name = - }, - }; - -+static const TestPlan plan_limit_by_well_known_name = -+{ -+ .description = "A subscription via a well-known name only accepts messages " -+ "sent by the owner of that well-known name", -+ .steps = { -+ { -+ /* Service already owns one name */ -+ .action = TEST_ACTION_OWN_NAME, -+ .u.own_name = { -+ .name = ALREADY_OWNED_NAME, -+ .owner = TEST_CONN_SERVICE -+ }, -+ }, -+ { -+ /* Subscriber wants to receive signals from service */ -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .string_sender = ALREADY_OWNED_NAME, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ /* Subscriber wants to receive signals from service by another name */ -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .string_sender = OWNED_LATER_NAME, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ /* Service claims another name */ -+ .action = TEST_ACTION_OWN_NAME, -+ .u.own_name = { -+ .name = OWNED_LATER_NAME, -+ .owner = TEST_CONN_SERVICE -+ }, -+ }, -+ { -+ /* Now the subscriber gets this signal twice, once for each -+ * subscription; and similarly each of the two proxies gets this -+ * signal twice */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 2, -+ .received_by_proxy = 2 -+ }, -+ }, -+ }, -+}; -+ - typedef struct - { - const TestPlan *plan; -@@ -540,11 +611,16 @@ fixture_subscribe (Fixture *f, - GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER]; - const char *sender; - -- if (subscribe->sender != TEST_CONN_NONE) -+ if (subscribe->string_sender != NULL) -+ { -+ sender = subscribe->string_sender; -+ g_test_message ("\tSender: %s", sender); -+ } -+ else if (subscribe->unique_sender != TEST_CONN_NONE) - { -- sender = f->unique_names[subscribe->sender]; -+ sender = f->unique_names[subscribe->unique_sender]; - g_test_message ("\tSender: %s %s", -- test_conn_descriptions[subscribe->sender], -+ test_conn_descriptions[subscribe->unique_sender], - sender); - } - else -@@ -689,6 +765,43 @@ fixture_emit_signal (Fixture *f, - connection_wait_for_bus (f->conns[signal->sender]); - } - -+static void -+fixture_own_name (Fixture *f, -+ const TestOwnName *own_name) -+{ -+ GVariant *call_result; -+ guint32 flags; -+ guint32 result_code; -+ -+ g_test_message ("\tName: %s", own_name->name); -+ g_test_message ("\tOwner: %s", -+ test_conn_descriptions[own_name->owner]); -+ -+ /* For simplicity, we do this via a direct bus call rather than -+ * using g_bus_own_name_on_connection(). The flags in -+ * GBusNameOwnerFlags are numerically equal to those in the -+ * D-Bus wire protocol. */ -+ flags = G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE; -+ call_result = g_dbus_connection_call_sync (f->conns[own_name->owner], -+ DBUS_SERVICE_DBUS, -+ DBUS_PATH_DBUS, -+ DBUS_INTERFACE_DBUS, -+ "RequestName", -+ g_variant_new ("(su)", -+ own_name->name, -+ flags), -+ G_VARIANT_TYPE ("(u)"), -+ G_DBUS_CALL_FLAGS_NONE, -+ -1, -+ NULL, -+ &f->error); -+ g_assert_no_error (f->error); -+ g_assert_nonnull (call_result); -+ g_variant_get (call_result, "(u)", &result_code); -+ g_assert_cmpuint (result_code, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER); -+ g_variant_unref (call_result); -+} -+ - static void - fixture_run_plan (Fixture *f, - const TestPlan *plan, -@@ -721,6 +834,11 @@ fixture_run_plan (Fixture *f, - fixture_emit_signal (f, &step->u.signal, i); - break; - -+ case TEST_ACTION_OWN_NAME: -+ g_test_message ("Step %u: claiming bus name", i); -+ fixture_own_name (f, &step->u.own_name); -+ break; -+ - case TEST_ACTION_NONE: - /* Padding to fill the rest of the array, do nothing */ - break; -@@ -933,6 +1051,7 @@ main (int argc, - ADD_SUBSCRIBE_TEST (broadcast_from_anyone); - ADD_SUBSCRIBE_TEST (match_twice); - ADD_SUBSCRIBE_TEST (limit_by_unique_name); -+ ADD_SUBSCRIBE_TEST (limit_by_well_known_name); - - return g_test_run(); - } --- -2.45.0 - - -From 59ff44e332059175a47af3ed02da28714b70c51b Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Fri, 8 Mar 2024 19:44:03 +0000 -Subject: [PATCH 05/19] tests: Add a test-case for what happens if a unique - name doesn't exist - -On GNOME/glib#3268 there was some concern about whether this would -allow an attacker to send signals and have them be matched to a -GDBusProxy in this situation, but it seems that was a false alarm. - -Signed-off-by: Simon McVittie ---- - gio/tests/gdbus-subscribe.c | 48 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - -diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c -index 3d2a14e03..350ec9f52 100644 ---- a/gio/tests/gdbus-subscribe.c -+++ b/gio/tests/gdbus-subscribe.c -@@ -358,6 +358,53 @@ static const TestPlan plan_limit_by_unique_name = - }, - }; - -+static const TestPlan plan_nonexistent_unique_name = -+{ -+ .description = "A subscription via a unique name that doesn't exist " -+ "accepts no messages", -+ .steps = { -+ { -+ /* Subscriber wants to receive signals from service */ -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ /* This relies on the implementation detail that the dbus-daemon -+ * (and presumably other bus implementations) never actually generates -+ * a unique name in this format */ -+ .string_sender = ":0.this.had.better.not.exist", -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ }, -+ }, -+ { -+ /* Attacker wants to trick subscriber into thinking that service -+ * sent a signal */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_ATTACKER, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* Attacker tries harder, by sending a signal unicast directly to -+ * the subscriber */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_ATTACKER, -+ .unicast_to = TEST_CONN_SUBSCRIBER, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, -+ }, -+}; -+ - static const TestPlan plan_limit_by_well_known_name = - { - .description = "A subscription via a well-known name only accepts messages " -@@ -1051,6 +1098,7 @@ main (int argc, - ADD_SUBSCRIBE_TEST (broadcast_from_anyone); - ADD_SUBSCRIBE_TEST (match_twice); - ADD_SUBSCRIBE_TEST (limit_by_unique_name); -+ ADD_SUBSCRIBE_TEST (nonexistent_unique_name); - ADD_SUBSCRIBE_TEST (limit_by_well_known_name); - - return g_test_run(); --- -2.45.0 - - -From 600d631e0978fd529877f481c10a7b3e971337cf Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Fri, 8 Mar 2024 20:10:29 +0000 -Subject: [PATCH 06/19] tests: Add test coverage for signals that match the - message bus's name - -This is a special case of unique names, even though it's syntactically -a well-known name. - -Signed-off-by: Simon McVittie ---- - gio/tests/gdbus-subscribe.c | 161 ++++++++++++++++++++++++++++++++++-- - 1 file changed, 154 insertions(+), 7 deletions(-) - -diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c -index 350ec9f52..af100de7d 100644 ---- a/gio/tests/gdbus-subscribe.c -+++ b/gio/tests/gdbus-subscribe.c -@@ -13,6 +13,7 @@ - #define DBUS_SERVICE_DBUS "org.freedesktop.DBus" - #define DBUS_PATH_DBUS "/org/freedesktop/DBus" - #define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS -+#define NAME_OWNER_CHANGED "NameOwnerChanged" - - /* A signal that each connection emits to indicate that it has finished - * emitting other signals */ -@@ -101,6 +102,7 @@ typedef struct - const char *iface; - const char *member; - const char *arg0; -+ const char *args; - guint received_by_conn; - guint received_by_proxy; - } TestEmitSignal; -@@ -120,6 +122,8 @@ typedef struct - { - const char *name; - TestConn owner; -+ guint received_by_conn; -+ guint received_by_proxy; - } TestOwnName; - - typedef enum -@@ -461,6 +465,63 @@ static const TestPlan plan_limit_by_well_known_name = - }, - }; - -+static const TestPlan plan_limit_to_message_bus = -+{ -+ .description = "A subscription to the message bus only accepts messages " -+ "from the message bus", -+ .steps = { -+ { -+ /* Subscriber wants to receive signals from the message bus itself */ -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .string_sender = DBUS_SERVICE_DBUS, -+ .path = DBUS_PATH_DBUS, -+ .iface = DBUS_INTERFACE_DBUS, -+ }, -+ }, -+ { -+ /* Attacker wants to trick subscriber into thinking that the message -+ * bus sent a signal */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_ATTACKER, -+ .path = DBUS_PATH_DBUS, -+ .iface = DBUS_INTERFACE_DBUS, -+ .member = NAME_OWNER_CHANGED, -+ .arg0 = "would I lie to you?", -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* Attacker tries harder, by sending a signal unicast directly to -+ * the subscriber, and using more realistic arguments */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .unicast_to = TEST_CONN_SUBSCRIBER, -+ .sender = TEST_CONN_ATTACKER, -+ .path = DBUS_PATH_DBUS, -+ .iface = DBUS_INTERFACE_DBUS, -+ .member = NAME_OWNER_CHANGED, -+ .args = "('com.example.Name', '', ':1.12')", -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* When the message bus sends a signal (in this case triggered by -+ * owning a name), it should still get through */ -+ .action = TEST_ACTION_OWN_NAME, -+ .u.own_name = { -+ .name = OWNED_LATER_NAME, -+ .owner = TEST_CONN_SERVICE, -+ .received_by_conn = 1, -+ .received_by_proxy = 1 -+ }, -+ }, -+ }, -+}; -+ - typedef struct - { - const TestPlan *plan; -@@ -591,7 +652,18 @@ fixture_received_signal (Fixture *f, - } - } - -- g_assert_cmpint (received->sender, !=, TEST_CONN_NONE); -+ if (g_str_equal (sender_name, DBUS_SERVICE_DBUS)) -+ { -+ g_test_message ("Signal received from message bus %s", -+ sender_name); -+ } -+ else -+ { -+ g_test_message ("Signal received from %s %s", -+ test_conn_descriptions[received->sender], -+ sender_name); -+ g_assert_cmpint (received->sender, !=, TEST_CONN_NONE); -+ } - - g_test_message ("Signal received from %s %s via %s", - test_conn_descriptions[received->sender], -@@ -607,13 +679,56 @@ fixture_received_signal (Fixture *f, - g_test_message ("\tString argument 0: %s", received->arg0); - g_test_message ("\tSent in step: %u", received->step); - } -- else -+ else if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)"))) - { -- g_assert_cmpstr (g_variant_get_type_string (parameters), ==, "(uu)"); - g_variant_get (parameters, "(uu)", NULL, &received->step); - g_test_message ("\tArgument 0: (not a string)"); - g_test_message ("\tSent in step: %u", received->step); - } -+ else if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)"))) -+ { -+ const char *name; -+ const char *old_owner; -+ const char *new_owner; -+ -+ /* The only signal of this signature that we legitimately receive -+ * during this test is NameOwnerChanged, so just assert that it -+ * is from the message bus and can be matched to a plausible step. -+ * (This is less thorough than the above, and will not work if we -+ * add a test scenario where a name's ownership is repeatedly -+ * changed while watching NameOwnerChanged - so don't do that.) */ -+ g_assert_cmpstr (sender_name, ==, DBUS_SERVICE_DBUS); -+ g_assert_cmpstr (path, ==, DBUS_PATH_DBUS); -+ g_assert_cmpstr (iface, ==, DBUS_INTERFACE_DBUS); -+ g_assert_cmpstr (member, ==, NAME_OWNER_CHANGED); -+ -+ g_variant_get (parameters, "(&s&s&s)", &name, &old_owner, &new_owner); -+ -+ for (i = 0; i < G_N_ELEMENTS (f->plan->steps); i++) -+ { -+ const TestStep *step = &f->plan->steps[i]; -+ -+ if (step->action == TEST_ACTION_OWN_NAME) -+ { -+ const TestOwnName *own_name = &step->u.own_name; -+ -+ if (g_str_equal (name, own_name->name) -+ && g_str_equal (new_owner, f->unique_names[own_name->owner]) -+ && own_name->received_by_conn > 0) -+ { -+ received->step = i; -+ break; -+ } -+ } -+ -+ if (i >= G_N_ELEMENTS (f->plan->steps)) -+ g_error ("Could not match message to a test step"); -+ } -+ } -+ else -+ { -+ g_error ("Unexpected message received"); -+ } - - g_ptr_array_add (f->received, g_steal_pointer (&received)); - } -@@ -782,10 +897,15 @@ fixture_emit_signal (Fixture *f, - * Otherwise put something that will not match any arg0. - * Either way, put the sequence number in argument 1 so we can - * correlate sent messages with received messages later. */ -- if (signal->arg0 != NULL) -+ if (signal->args != NULL) - { -- g_test_message ("\tString argument 0: %s", signal->arg0); - /* floating */ -+ body = g_variant_new_parsed (signal->args); -+ g_assert_nonnull (body); -+ } -+ else if (signal->arg0 != NULL) -+ { -+ g_test_message ("\tString argument 0: %s", signal->arg0); - body = g_variant_new ("(su)", signal->arg0, (guint32) step_number); - } - else -@@ -933,8 +1053,6 @@ fixture_run_plan (Fixture *f, - - g_assert_cmpuint (received->step, <, G_N_ELEMENTS (f->received_by_conn)); - g_assert_cmpuint (received->step, <, G_N_ELEMENTS (f->received_by_proxy)); -- g_assert_cmpint (plan->steps[received->step].action, -- ==, TEST_ACTION_EMIT_SIGNAL); - - if (received->received_by_proxy != NULL) - f->received_by_proxy[received->step] += 1; -@@ -974,6 +1092,34 @@ fixture_run_plan (Fixture *f, - g_assert_cmpuint (f->received_by_proxy[i], ==, 0); - } - } -+ else if (step->action == TEST_ACTION_OWN_NAME) -+ { -+ const TestOwnName *own_name = &plan->steps[i].u.own_name; -+ -+ if (mode != SUBSCRIPTION_MODE_PROXY) -+ { -+ g_test_message ("NameOwnerChanged from step %u was received %u " -+ "times by GDBusConnection, expected %u", -+ i, f->received_by_conn[i], own_name->received_by_conn); -+ g_assert_cmpuint (f->received_by_conn[i], ==, own_name->received_by_conn); -+ } -+ else -+ { -+ g_assert_cmpuint (f->received_by_conn[i], ==, 0); -+ } -+ -+ if (mode != SUBSCRIPTION_MODE_CONN) -+ { -+ g_test_message ("NameOwnerChanged from step %u was received %u " -+ "times by GDBusProxy, expected %u", -+ i, f->received_by_proxy[i], own_name->received_by_proxy); -+ g_assert_cmpuint (f->received_by_proxy[i], ==, own_name->received_by_proxy); -+ } -+ else -+ { -+ g_assert_cmpuint (f->received_by_proxy[i], ==, 0); -+ } -+ } - } - } - -@@ -1100,6 +1246,7 @@ main (int argc, - ADD_SUBSCRIBE_TEST (limit_by_unique_name); - ADD_SUBSCRIBE_TEST (nonexistent_unique_name); - ADD_SUBSCRIBE_TEST (limit_by_well_known_name); -+ ADD_SUBSCRIBE_TEST (limit_to_message_bus); - - return g_test_run(); - } --- -2.45.0 - - -From d338bad6baa8a198953b109c00a96b02a18a8103 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Thu, 14 Mar 2024 19:18:15 +0000 -Subject: [PATCH 07/19] gdbusprivate: Add symbolic constants for the message - bus itself - -Using these is a bit more clearly correct than repeating them everywhere. -To avoid excessive diffstat in a branch for a bug fix, I'm not -immediately replacing all existing occurrences of the same literals with -these names. - -The names of these constants are chosen to be consistent with libdbus, -despite using somewhat outdated terminology (D-Bus now uses the term -"well-known bus name" for what used to be called a service name, -reserving the word "service" to mean specifically the programs that -have .service files and participate in service activation). - -Signed-off-by: Simon McVittie ---- - gio/gdbusprivate.h | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h -index 8f8a93ba7..e9bca11ca 100644 ---- a/gio/gdbusprivate.h -+++ b/gio/gdbusprivate.h -@@ -29,6 +29,11 @@ - - G_BEGIN_DECLS - -+/* Bus name, interface and object path of the message bus itself */ -+#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" -+#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS -+#define DBUS_PATH_DBUS "/org/freedesktop/DBus" -+ - /* ---------------------------------------------------------------------------------------------------- */ - - typedef struct GDBusWorker GDBusWorker; --- -2.45.0 - - -From a207a6f5adc9e6cea929c07a9d7533cc90043d01 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Wed, 1 May 2024 19:43:24 +0100 -Subject: [PATCH 08/19] gdbusconnection: Move SignalData, SignalSubscriber - higher up - -Subsequent changes will need to access these data structures from -on_worker_message_received(). No functional change here, only moving -code around. - -[Backport to 2.66.x: fix minor conflicts] -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 128 +++++++++++++++++++++--------------------- - 1 file changed, 65 insertions(+), 63 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index 2808b1e46..8d841d78b 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -299,6 +299,71 @@ _g_strv_has_string (const gchar* const *haystack, - - /* ---------------------------------------------------------------------------------------------------- */ - -+typedef struct -+{ -+ /* All fields are immutable after construction. */ -+ gatomicrefcount ref_count; -+ GDBusSignalCallback callback; -+ gpointer user_data; -+ GDestroyNotify user_data_free_func; -+ guint id; -+ GMainContext *context; -+} SignalSubscriber; -+ -+static SignalSubscriber * -+signal_subscriber_ref (SignalSubscriber *subscriber) -+{ -+ g_atomic_ref_count_inc (&subscriber->ref_count); -+ return subscriber; -+} -+ -+static void -+signal_subscriber_unref (SignalSubscriber *subscriber) -+{ -+ if (g_atomic_ref_count_dec (&subscriber->ref_count)) -+ { -+ /* Destroy the user data. It doesn’t matter which thread -+ * signal_subscriber_unref() is called in (or whether it’s called with a -+ * lock held), as call_destroy_notify() always defers to the next -+ * #GMainContext iteration. */ -+ call_destroy_notify (subscriber->context, -+ subscriber->user_data_free_func, -+ subscriber->user_data); -+ -+ g_main_context_unref (subscriber->context); -+ g_free (subscriber); -+ } -+} -+ -+typedef struct -+{ -+ gchar *rule; -+ gchar *sender; -+ gchar *sender_unique_name; /* if sender is unique or org.freedesktop.DBus, then that name... otherwise blank */ -+ gchar *interface_name; -+ gchar *member; -+ gchar *object_path; -+ gchar *arg0; -+ GDBusSignalFlags flags; -+ GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */ -+} SignalData; -+ -+static void -+signal_data_free (SignalData *signal_data) -+{ -+ g_free (signal_data->rule); -+ g_free (signal_data->sender); -+ g_free (signal_data->sender_unique_name); -+ g_free (signal_data->interface_name); -+ g_free (signal_data->member); -+ g_free (signal_data->object_path); -+ g_free (signal_data->arg0); -+ g_ptr_array_unref (signal_data->subscribers); -+ g_free (signal_data); -+} -+ -+/* ---------------------------------------------------------------------------------------------------- */ -+ - #ifdef G_OS_WIN32 - #define CONNECTION_ENSURE_LOCK(obj) do { ; } while (FALSE) - #else -@@ -3253,69 +3318,6 @@ g_dbus_connection_remove_filter (GDBusConnection *connection, - - /* ---------------------------------------------------------------------------------------------------- */ - --typedef struct --{ -- gchar *rule; -- gchar *sender; -- gchar *sender_unique_name; /* if sender is unique or org.freedesktop.DBus, then that name... otherwise blank */ -- gchar *interface_name; -- gchar *member; -- gchar *object_path; -- gchar *arg0; -- GDBusSignalFlags flags; -- GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */ --} SignalData; -- --static void --signal_data_free (SignalData *signal_data) --{ -- g_free (signal_data->rule); -- g_free (signal_data->sender); -- g_free (signal_data->sender_unique_name); -- g_free (signal_data->interface_name); -- g_free (signal_data->member); -- g_free (signal_data->object_path); -- g_free (signal_data->arg0); -- g_ptr_array_unref (signal_data->subscribers); -- g_free (signal_data); --} -- --typedef struct --{ -- /* All fields are immutable after construction. */ -- gatomicrefcount ref_count; -- GDBusSignalCallback callback; -- gpointer user_data; -- GDestroyNotify user_data_free_func; -- guint id; -- GMainContext *context; --} SignalSubscriber; -- --static SignalSubscriber * --signal_subscriber_ref (SignalSubscriber *subscriber) --{ -- g_atomic_ref_count_inc (&subscriber->ref_count); -- return subscriber; --} -- --static void --signal_subscriber_unref (SignalSubscriber *subscriber) --{ -- if (g_atomic_ref_count_dec (&subscriber->ref_count)) -- { -- /* Destroy the user data. It doesn’t matter which thread -- * signal_subscriber_unref() is called in (or whether it’s called with a -- * lock held), as call_destroy_notify() always defers to the next -- * #GMainContext iteration. */ -- call_destroy_notify (subscriber->context, -- subscriber->user_data_free_func, -- subscriber->user_data); -- -- g_main_context_unref (subscriber->context); -- g_free (subscriber); -- } --} -- - static gchar * - args_to_rule (const gchar *sender, - const gchar *interface_name, --- -2.45.0 - - -From 998cee11197dda4f48334921900bca0e6a8cd62b Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Thu, 14 Mar 2024 19:30:12 +0000 -Subject: [PATCH 09/19] gdbusconnection: Factor out signal_data_new_take() - -No functional changes, except that the implicit ownership-transfer -for the rule field becomes explicit (the local variable is set to NULL -afterwards). - -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 42 ++++++++++++++++++++++++++++++++---------- - 1 file changed, 32 insertions(+), 10 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index 8d841d78b..67091574a 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -348,6 +348,30 @@ typedef struct - GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */ - } SignalData; - -+static SignalData * -+signal_data_new_take (gchar *rule, -+ gchar *sender, -+ gchar *sender_unique_name, -+ gchar *interface_name, -+ gchar *member, -+ gchar *object_path, -+ gchar *arg0, -+ GDBusSignalFlags flags) -+{ -+ SignalData *signal_data = g_new0 (SignalData, 1); -+ -+ signal_data->rule = rule; -+ signal_data->sender = sender; -+ signal_data->sender_unique_name = sender_unique_name; -+ signal_data->interface_name = interface_name; -+ signal_data->member = member; -+ signal_data->object_path = object_path; -+ signal_data->arg0 = arg0; -+ signal_data->flags = flags; -+ signal_data->subscribers = g_ptr_array_new_with_free_func ((GDestroyNotify) signal_subscriber_unref); -+ return g_steal_pointer (&signal_data); -+} -+ - static void - signal_data_free (SignalData *signal_data) - { -@@ -3584,16 +3608,14 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - goto out; - } - -- signal_data = g_new0 (SignalData, 1); -- signal_data->rule = rule; -- signal_data->sender = g_strdup (sender); -- signal_data->sender_unique_name = g_strdup (sender_unique_name); -- signal_data->interface_name = g_strdup (interface_name); -- signal_data->member = g_strdup (member); -- signal_data->object_path = g_strdup (object_path); -- signal_data->arg0 = g_strdup (arg0); -- signal_data->flags = flags; -- signal_data->subscribers = g_ptr_array_new_with_free_func ((GDestroyNotify) signal_subscriber_unref); -+ signal_data = signal_data_new_take (g_steal_pointer (&rule), -+ g_strdup (sender), -+ g_strdup (sender_unique_name), -+ g_strdup (interface_name), -+ g_strdup (member), -+ g_strdup (object_path), -+ g_strdup (arg0), -+ flags); - g_ptr_array_add (signal_data->subscribers, subscriber); - - g_hash_table_insert (connection->map_rule_to_signal_data, --- -2.45.0 - - -From 6df7b138b1f5b4c53ad124182b80e05cdba16c3c Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Tue, 23 Apr 2024 20:31:57 +0100 -Subject: [PATCH 10/19] gdbusconnection: Factor out add_signal_data() - -No functional changes. - -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 64 +++++++++++++++++++++++++------------------ - 1 file changed, 37 insertions(+), 27 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index 67091574a..a570e5856 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -3462,6 +3462,42 @@ is_signal_data_for_name_lost_or_acquired (SignalData *signal_data) - - /* ---------------------------------------------------------------------------------------------------- */ - -+/* called in any thread, connection lock is held */ -+static void -+add_signal_data (GDBusConnection *connection, -+ SignalData *signal_data) -+{ -+ GPtrArray *signal_data_array; -+ -+ g_hash_table_insert (connection->map_rule_to_signal_data, -+ signal_data->rule, -+ signal_data); -+ -+ /* Add the match rule to the bus... -+ * -+ * Avoid adding match rules for NameLost and NameAcquired messages - the bus will -+ * always send such messages to us. -+ */ -+ if (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) -+ { -+ if (!is_signal_data_for_name_lost_or_acquired (signal_data)) -+ add_match_rule (connection, signal_data->rule); -+ } -+ -+ signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, -+ signal_data->sender_unique_name); -+ if (signal_data_array == NULL) -+ { -+ signal_data_array = g_ptr_array_new (); -+ g_hash_table_insert (connection->map_sender_unique_name_to_signal_data_array, -+ g_strdup (signal_data->sender_unique_name), -+ signal_data_array); -+ } -+ g_ptr_array_add (signal_data_array, signal_data); -+} -+ -+/* ---------------------------------------------------------------------------------------------------- */ -+ - /** - * g_dbus_connection_signal_subscribe: - * @connection: a #GDBusConnection -@@ -3551,7 +3587,6 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - gchar *rule; - SignalData *signal_data; - SignalSubscriber *subscriber; -- GPtrArray *signal_data_array; - const gchar *sender_unique_name; - - /* Right now we abort if AddMatch() fails since it can only fail with the bus being in -@@ -3617,32 +3652,7 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - g_strdup (arg0), - flags); - g_ptr_array_add (signal_data->subscribers, subscriber); -- -- g_hash_table_insert (connection->map_rule_to_signal_data, -- signal_data->rule, -- signal_data); -- -- /* Add the match rule to the bus... -- * -- * Avoid adding match rules for NameLost and NameAcquired messages - the bus will -- * always send such messages to us. -- */ -- if (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) -- { -- if (!is_signal_data_for_name_lost_or_acquired (signal_data)) -- add_match_rule (connection, signal_data->rule); -- } -- -- signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, -- signal_data->sender_unique_name); -- if (signal_data_array == NULL) -- { -- signal_data_array = g_ptr_array_new (); -- g_hash_table_insert (connection->map_sender_unique_name_to_signal_data_array, -- g_strdup (signal_data->sender_unique_name), -- signal_data_array); -- } -- g_ptr_array_add (signal_data_array, signal_data); -+ add_signal_data (connection, signal_data); - - out: - g_hash_table_insert (connection->map_id_to_signal_data, --- -2.45.0 - - -From dd4a94708ef1bd63763bedcb93161746cbc9c7e6 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Thu, 14 Mar 2024 19:51:59 +0000 -Subject: [PATCH 11/19] gdbusconnection: Factor out - remove_signal_data_if_unused - -No functional change, just removing some nesting. The check for whether -signal_data->subscribers is empty changes from a conditional that tests -whether it is into an early-return if it isn't. - -A subsequent commit will add additional conditions that make us consider -a SignalData to be still in use and therefore not eligible to be removed. - -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 83 +++++++++++++++++++++++++------------------ - 1 file changed, 48 insertions(+), 35 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index a570e5856..b2268e637 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -3666,6 +3666,52 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - - /* ---------------------------------------------------------------------------------------------------- */ - -+/* -+ * Called in any thread. -+ * Must hold the connection lock when calling this, unless -+ * connection->finalizing is TRUE. -+ * May free signal_data, so do not dereference it after this. -+ */ -+static void -+remove_signal_data_if_unused (GDBusConnection *connection, -+ SignalData *signal_data) -+{ -+ GPtrArray *signal_data_array; -+ -+ if (signal_data->subscribers->len != 0) -+ return; -+ -+ g_warn_if_fail (g_hash_table_remove (connection->map_rule_to_signal_data, signal_data->rule)); -+ -+ signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, -+ signal_data->sender_unique_name); -+ g_warn_if_fail (signal_data_array != NULL); -+ g_warn_if_fail (g_ptr_array_remove (signal_data_array, signal_data)); -+ -+ if (signal_data_array->len == 0) -+ { -+ g_warn_if_fail (g_hash_table_remove (connection->map_sender_unique_name_to_signal_data_array, -+ signal_data->sender_unique_name)); -+ } -+ -+ /* remove the match rule from the bus unless NameLost or NameAcquired (see subscribe()) */ -+ if ((connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) && -+ !is_signal_data_for_name_lost_or_acquired (signal_data) && -+ !g_dbus_connection_is_closed (connection) && -+ !connection->finalizing) -+ { -+ /* The check for g_dbus_connection_is_closed() means that -+ * sending the RemoveMatch message can't fail with -+ * G_IO_ERROR_CLOSED, because we're holding the lock, -+ * so on_worker_closed() can't happen between the check we just -+ * did, and releasing the lock later. -+ */ -+ remove_match_rule (connection, signal_data->rule); -+ } -+ -+ signal_data_free (signal_data); -+} -+ - /* called in any thread */ - /* must hold lock when calling this (except if connection->finalizing is TRUE) - * returns the number of removed subscribers */ -@@ -3674,7 +3720,6 @@ unsubscribe_id_internal (GDBusConnection *connection, - guint subscription_id) - { - SignalData *signal_data; -- GPtrArray *signal_data_array; - guint n; - guint n_removed = 0; - -@@ -3701,40 +3746,8 @@ unsubscribe_id_internal (GDBusConnection *connection, - GUINT_TO_POINTER (subscription_id))); - n_removed++; - g_ptr_array_remove_index_fast (signal_data->subscribers, n); -- -- if (signal_data->subscribers->len == 0) -- { -- g_warn_if_fail (g_hash_table_remove (connection->map_rule_to_signal_data, signal_data->rule)); -- -- signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, -- signal_data->sender_unique_name); -- g_warn_if_fail (signal_data_array != NULL); -- g_warn_if_fail (g_ptr_array_remove (signal_data_array, signal_data)); -- -- if (signal_data_array->len == 0) -- { -- g_warn_if_fail (g_hash_table_remove (connection->map_sender_unique_name_to_signal_data_array, -- signal_data->sender_unique_name)); -- } -- -- /* remove the match rule from the bus unless NameLost or NameAcquired (see subscribe()) */ -- if ((connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) && -- !is_signal_data_for_name_lost_or_acquired (signal_data) && -- !g_dbus_connection_is_closed (connection) && -- !connection->finalizing) -- { -- /* The check for g_dbus_connection_is_closed() means that -- * sending the RemoveMatch message can't fail with -- * G_IO_ERROR_CLOSED, because we're holding the lock, -- * so on_worker_closed() can't happen between the check we just -- * did, and releasing the lock later. -- */ -- remove_match_rule (connection, signal_data->rule); -- } -- -- signal_data_free (signal_data); -- } -- -+ /* May free signal_data */ -+ remove_signal_data_if_unused (connection, signal_data); - goto out; - } - --- -2.45.0 - - -From 64758288c6e71dd92270771b6b81891e4be87fa9 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Tue, 23 Apr 2024 20:39:05 +0100 -Subject: [PATCH 12/19] gdbusconnection: Stop storing sender_unique_name in - SignalData - -This will become confusing when we start tracking the owner of a -well-known-name sender, and it's redundant anyway. Instead, track the -1 bit of data that we actually need: whether it's a well-known name. - -Strictly speaking this too is redundant, because it's syntactically -derivable from the sender, but only via extra string operations. -A subsequent commit will add a data structure to keep track of the -owner of a well-known-name sender, at which point this boolean will -be replaced by the presence or absence of that data structure. - -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 36 ++++++++++++++++++++++++------------ - 1 file changed, 24 insertions(+), 12 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index b2268e637..e17703d0f 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -339,19 +339,19 @@ typedef struct - { - gchar *rule; - gchar *sender; -- gchar *sender_unique_name; /* if sender is unique or org.freedesktop.DBus, then that name... otherwise blank */ - gchar *interface_name; - gchar *member; - gchar *object_path; - gchar *arg0; - GDBusSignalFlags flags; - GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */ -+ gboolean sender_is_its_own_owner; - } SignalData; - - static SignalData * - signal_data_new_take (gchar *rule, - gchar *sender, -- gchar *sender_unique_name, -+ gboolean sender_is_its_own_owner, - gchar *interface_name, - gchar *member, - gchar *object_path, -@@ -362,7 +362,7 @@ signal_data_new_take (gchar *rule, - - signal_data->rule = rule; - signal_data->sender = sender; -- signal_data->sender_unique_name = sender_unique_name; -+ signal_data->sender_is_its_own_owner = sender_is_its_own_owner; - signal_data->interface_name = interface_name; - signal_data->member = member; - signal_data->object_path = object_path; -@@ -377,7 +377,6 @@ signal_data_free (SignalData *signal_data) - { - g_free (signal_data->rule); - g_free (signal_data->sender); -- g_free (signal_data->sender_unique_name); - g_free (signal_data->interface_name); - g_free (signal_data->member); - g_free (signal_data->object_path); -@@ -3453,7 +3452,7 @@ remove_match_rule (GDBusConnection *connection, - static gboolean - is_signal_data_for_name_lost_or_acquired (SignalData *signal_data) - { -- return g_strcmp0 (signal_data->sender_unique_name, "org.freedesktop.DBus") == 0 && -+ return g_strcmp0 (signal_data->sender, "org.freedesktop.DBus") == 0 && - g_strcmp0 (signal_data->interface_name, "org.freedesktop.DBus") == 0 && - g_strcmp0 (signal_data->object_path, "/org/freedesktop/DBus") == 0 && - (g_strcmp0 (signal_data->member, "NameLost") == 0 || -@@ -3465,7 +3464,8 @@ is_signal_data_for_name_lost_or_acquired (SignalData *signal_data) - /* called in any thread, connection lock is held */ - static void - add_signal_data (GDBusConnection *connection, -- SignalData *signal_data) -+ SignalData *signal_data, -+ const char *sender_unique_name) - { - GPtrArray *signal_data_array; - -@@ -3485,12 +3485,12 @@ add_signal_data (GDBusConnection *connection, - } - - signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, -- signal_data->sender_unique_name); -+ sender_unique_name); - if (signal_data_array == NULL) - { - signal_data_array = g_ptr_array_new (); - g_hash_table_insert (connection->map_sender_unique_name_to_signal_data_array, -- g_strdup (signal_data->sender_unique_name), -+ g_strdup (sender_unique_name), - signal_data_array); - } - g_ptr_array_add (signal_data_array, signal_data); -@@ -3587,6 +3587,7 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - gchar *rule; - SignalData *signal_data; - SignalSubscriber *subscriber; -+ gboolean sender_is_its_own_owner; - const gchar *sender_unique_name; - - /* Right now we abort if AddMatch() fails since it can only fail with the bus being in -@@ -3622,6 +3623,11 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - rule = args_to_rule (sender, interface_name, member, object_path, arg0, flags); - - if (sender != NULL && (g_dbus_is_unique_name (sender) || g_strcmp0 (sender, "org.freedesktop.DBus") == 0)) -+ sender_is_its_own_owner = TRUE; -+ else -+ sender_is_its_own_owner = FALSE; -+ -+ if (sender_is_its_own_owner) - sender_unique_name = sender; - else - sender_unique_name = ""; -@@ -3645,14 +3651,14 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - - signal_data = signal_data_new_take (g_steal_pointer (&rule), - g_strdup (sender), -- g_strdup (sender_unique_name), -+ sender_is_its_own_owner, - g_strdup (interface_name), - g_strdup (member), - g_strdup (object_path), - g_strdup (arg0), - flags); - g_ptr_array_add (signal_data->subscribers, subscriber); -- add_signal_data (connection, signal_data); -+ add_signal_data (connection, signal_data, sender_unique_name); - - out: - g_hash_table_insert (connection->map_id_to_signal_data, -@@ -3676,22 +3682,28 @@ static void - remove_signal_data_if_unused (GDBusConnection *connection, - SignalData *signal_data) - { -+ const gchar *sender_unique_name; - GPtrArray *signal_data_array; - - if (signal_data->subscribers->len != 0) - return; - -+ if (signal_data->sender_is_its_own_owner) -+ sender_unique_name = signal_data->sender; -+ else -+ sender_unique_name = ""; -+ - g_warn_if_fail (g_hash_table_remove (connection->map_rule_to_signal_data, signal_data->rule)); - - signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, -- signal_data->sender_unique_name); -+ sender_unique_name); - g_warn_if_fail (signal_data_array != NULL); - g_warn_if_fail (g_ptr_array_remove (signal_data_array, signal_data)); - - if (signal_data_array->len == 0) - { - g_warn_if_fail (g_hash_table_remove (connection->map_sender_unique_name_to_signal_data_array, -- signal_data->sender_unique_name)); -+ sender_unique_name)); - } - - /* remove the match rule from the bus unless NameLost or NameAcquired (see subscribe()) */ --- -2.45.0 - - -From 3dd78b5a67c0dea7c453d29345cf42f6c30a600b Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Wed, 1 May 2024 15:43:09 +0100 -Subject: [PATCH 13/19] gdbus: Track name owners for signal subscriptions - -We will use this in a subsequent commit to prevent signals from an -impostor from being delivered to a subscriber. - -To avoid message reordering leading to misleading situations, this does -not use the existing mechanism for watching bus name ownership, which -delivers the ownership changes to other main-contexts. Instead, it all -happens on the single thread used by the GDBusWorker, so the order in -which messages are received is the order in which they are processed. - -[Backported to glib-2-74, resolving minor conflicts] -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 350 +++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 343 insertions(+), 7 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index e17703d0f..6d18b2457 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -336,6 +336,31 @@ signal_subscriber_unref (SignalSubscriber *subscriber) - } - - typedef struct -+{ -+ /* -+ * 1 reference while waiting for GetNameOwner() to finish -+ * 1 reference for each SignalData that points to this one as its -+ * shared_name_watcher -+ */ -+ grefcount ref_count; -+ -+ gchar *owner; -+ guint32 get_name_owner_serial; -+} WatchedName; -+ -+static WatchedName * -+watched_name_new (void) -+{ -+ WatchedName *watched_name = g_new0 (WatchedName, 1); -+ -+ g_ref_count_init (&watched_name->ref_count); -+ watched_name->owner = NULL; -+ return g_steal_pointer (&watched_name); -+} -+ -+typedef struct SignalData SignalData; -+ -+struct SignalData - { - gchar *rule; - gchar *sender; -@@ -345,13 +370,36 @@ typedef struct - gchar *arg0; - GDBusSignalFlags flags; - GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */ -- gboolean sender_is_its_own_owner; --} SignalData; -+ -+ /* -+ * If the sender is a well-known name, this is an unowned SignalData -+ * representing the NameOwnerChanged signal that tracks its owner. -+ * NULL if sender is NULL. -+ * NULL if sender is its own owner (a unique name or DBUS_SERVICE_DBUS). -+ * -+ * Invariants: if not NULL, then -+ * shared_name_watcher->sender == DBUS_SERVICE_DBUS -+ * shared_name_watcher->interface_name == DBUS_INTERFACE_DBUS -+ * shared_name_watcher->member == "NameOwnerChanged" -+ * shared_name_watcher->object_path == DBUS_PATH_DBUS -+ * shared_name_watcher->arg0 == sender -+ * shared_name_watcher->flags == NONE -+ * shared_name_watcher->watched_name == NULL -+ */ -+ SignalData *shared_name_watcher; -+ -+ /* -+ * Non-NULL if this SignalData is another SignalData's shared_name_watcher. -+ * One reference for each SignalData that has this one as its -+ * shared_name_watcher. -+ * Otherwise NULL. -+ */ -+ WatchedName *watched_name; -+}; - - static SignalData * - signal_data_new_take (gchar *rule, - gchar *sender, -- gboolean sender_is_its_own_owner, - gchar *interface_name, - gchar *member, - gchar *object_path, -@@ -362,7 +410,6 @@ signal_data_new_take (gchar *rule, - - signal_data->rule = rule; - signal_data->sender = sender; -- signal_data->sender_is_its_own_owner = sender_is_its_own_owner; - signal_data->interface_name = interface_name; - signal_data->member = member; - signal_data->object_path = object_path; -@@ -375,6 +422,17 @@ signal_data_new_take (gchar *rule, - static void - signal_data_free (SignalData *signal_data) - { -+ /* The SignalData should not be freed while it still has subscribers */ -+ g_assert (signal_data->subscribers->len == 0); -+ -+ /* The SignalData should not be freed while it is watching for -+ * NameOwnerChanged on behalf of another SignalData */ -+ g_assert (signal_data->watched_name == NULL); -+ -+ /* The SignalData should be detached from its name watcher, if any, -+ * before it is freed */ -+ g_assert (signal_data->shared_name_watcher == NULL); -+ - g_free (signal_data->rule); - g_free (signal_data->sender); - g_free (signal_data->interface_name); -@@ -382,6 +440,7 @@ signal_data_free (SignalData *signal_data) - g_free (signal_data->object_path); - g_free (signal_data->arg0); - g_ptr_array_unref (signal_data->subscribers); -+ - g_free (signal_data); - } - -@@ -513,6 +572,7 @@ struct _GDBusConnection - - /* Map used for managing method replies, protected by @lock */ - GHashTable *map_method_serial_to_task; /* guint32 -> GTask* */ -+ GHashTable *map_method_serial_to_name_watcher; /* guint32 -> unowned SignalData* */ - - /* Maps used for managing signal subscription, protected by @lock */ - GHashTable *map_rule_to_signal_data; /* match rule (gchar*) -> SignalData */ -@@ -760,6 +820,7 @@ g_dbus_connection_finalize (GObject *object) - g_error_free (connection->initialization_error); - - g_hash_table_unref (connection->map_method_serial_to_task); -+ g_hash_table_unref (connection->map_method_serial_to_name_watcher); - - g_hash_table_unref (connection->map_rule_to_signal_data); - g_hash_table_unref (connection->map_id_to_signal_data); -@@ -1155,6 +1216,7 @@ g_dbus_connection_init (GDBusConnection *connection) - g_mutex_init (&connection->init_lock); - - connection->map_method_serial_to_task = g_hash_table_new (g_direct_hash, g_direct_equal); -+ connection->map_method_serial_to_name_watcher = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); - - connection->map_rule_to_signal_data = g_hash_table_new (g_str_hash, - g_str_equal); -@@ -2281,6 +2343,191 @@ g_dbus_connection_send_message_with_reply_sync (GDBusConnection *connecti - - /* ---------------------------------------------------------------------------------------------------- */ - -+/* -+ * Called in any thread. -+ * Must hold the connection lock when calling this, unless -+ * connection->finalizing is TRUE. -+ */ -+static void -+name_watcher_unref_watched_name (GDBusConnection *connection, -+ SignalData *name_watcher) -+{ -+ WatchedName *watched_name = name_watcher->watched_name; -+ -+ g_assert (watched_name != NULL); -+ -+ if (!g_ref_count_dec (&watched_name->ref_count)) -+ return; -+ -+ /* Removing watched_name from the name_watcher may result in -+ * name_watcher being freed, so we must make sure name_watcher is no -+ * longer in map_method_serial_to_name_watcher. -+ * -+ * If we stop watching the name while our GetNameOwner call was still -+ * in-flight, then when the reply eventually arrives, we will not find -+ * its serial number in the map and harmlessly ignore it as a result. */ -+ if (watched_name->get_name_owner_serial != 0) -+ g_hash_table_remove (connection->map_method_serial_to_name_watcher, -+ GUINT_TO_POINTER (watched_name->get_name_owner_serial)); -+ -+ name_watcher->watched_name = NULL; -+ g_free (watched_name->owner); -+ g_free (watched_name); -+} -+ -+/* called in GDBusWorker thread with lock held */ -+static void -+name_watcher_set_name_owner_unlocked (SignalData *name_watcher, -+ const char *new_owner) -+{ -+ if (new_owner != NULL && new_owner[0] == '\0') -+ new_owner = NULL; -+ -+ g_assert (name_watcher->watched_name != NULL); -+ g_set_str (&name_watcher->watched_name->owner, new_owner); -+} -+ -+/* called in GDBusWorker thread with lock held */ -+static void -+name_watcher_deliver_name_owner_changed_unlocked (SignalData *name_watcher, -+ GDBusMessage *message) -+{ -+ GVariant *body; -+ -+ body = g_dbus_message_get_body (message); -+ -+ if (G_LIKELY (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(sss)")))) -+ { -+ const char *name; -+ const char *new_owner; -+ -+ g_variant_get (body, "(&s&s&s)", &name, NULL, &new_owner); -+ -+ /* Our caller already checked this */ -+ g_assert (g_strcmp0 (name_watcher->arg0, name) == 0); -+ -+ if (G_LIKELY (new_owner[0] == '\0' || g_dbus_is_unique_name (new_owner))) -+ name_watcher_set_name_owner_unlocked (name_watcher, new_owner); -+ else -+ g_warning ("Received NameOwnerChanged signal with invalid owner \"%s\" for \"%s\"", -+ new_owner, name); -+ } -+ else -+ { -+ g_warning ("Received NameOwnerChanged signal with unexpected " -+ "signature %s", -+ body == NULL ? "()" : g_variant_get_type_string (body)); -+ -+ } -+} -+ -+/* called in GDBusWorker thread with lock held */ -+static void -+name_watcher_deliver_get_name_owner_reply_unlocked (SignalData *name_watcher, -+ GDBusConnection *connection, -+ GDBusMessage *message) -+{ -+ GDBusMessageType type; -+ GVariant *body; -+ WatchedName *watched_name; -+ -+ watched_name = name_watcher->watched_name; -+ g_assert (watched_name != NULL); -+ g_assert (watched_name->get_name_owner_serial != 0); -+ -+ type = g_dbus_message_get_message_type (message); -+ body = g_dbus_message_get_body (message); -+ -+ if (type == G_DBUS_MESSAGE_TYPE_ERROR) -+ { -+ if (g_strcmp0 (g_dbus_message_get_error_name (message), -+ "org.freedesktop.DBus.Error.NameHasNoOwner")) -+ name_watcher_set_name_owner_unlocked (name_watcher, NULL); -+ /* else it's something like NoReply or AccessDenied, which tells -+ * us nothing - leave the owner set to whatever we most recently -+ * learned from NameOwnerChanged, or NULL */ -+ } -+ else if (type != G_DBUS_MESSAGE_TYPE_METHOD_RETURN) -+ { -+ g_warning ("Received GetNameOwner reply with unexpected type %d", -+ type); -+ } -+ else if (G_LIKELY (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(s)")))) -+ { -+ const char *new_owner; -+ -+ g_variant_get (body, "(&s)", &new_owner); -+ -+ if (G_LIKELY (g_dbus_is_unique_name (new_owner))) -+ name_watcher_set_name_owner_unlocked (name_watcher, new_owner); -+ else -+ g_warning ("Received GetNameOwner reply with invalid owner \"%s\" for \"%s\"", -+ new_owner, name_watcher->arg0); -+ } -+ else -+ { -+ g_warning ("Received GetNameOwner reply with unexpected signature %s", -+ body == NULL ? "()" : g_variant_get_type_string (body)); -+ } -+ -+ g_hash_table_remove (connection->map_method_serial_to_name_watcher, -+ GUINT_TO_POINTER (watched_name->get_name_owner_serial)); -+ watched_name->get_name_owner_serial = 0; -+} -+ -+/* Called in a user thread, lock is held */ -+static void -+name_watcher_call_get_name_owner_unlocked (GDBusConnection *connection, -+ SignalData *name_watcher) -+{ -+ GDBusMessage *message; -+ GError *local_error = NULL; -+ WatchedName *watched_name; -+ -+ g_assert (g_strcmp0 (name_watcher->sender, DBUS_SERVICE_DBUS) == 0); -+ g_assert (g_strcmp0 (name_watcher->interface_name, DBUS_INTERFACE_DBUS) == 0); -+ g_assert (g_strcmp0 (name_watcher->member, "NameOwnerChanged") == 0); -+ g_assert (g_strcmp0 (name_watcher->object_path, DBUS_PATH_DBUS) == 0); -+ /* arg0 of the NameOwnerChanged message is the well-known name whose owner -+ * we are interested in */ -+ g_assert (g_dbus_is_name (name_watcher->arg0)); -+ g_assert (name_watcher->flags == G_DBUS_SIGNAL_FLAGS_NONE); -+ -+ watched_name = name_watcher->watched_name; -+ g_assert (watched_name != NULL); -+ g_assert (watched_name->owner == NULL); -+ g_assert (watched_name->get_name_owner_serial == 0); -+ g_assert (name_watcher->shared_name_watcher == NULL); -+ -+ message = g_dbus_message_new_method_call (DBUS_SERVICE_DBUS, -+ DBUS_PATH_DBUS, -+ DBUS_INTERFACE_DBUS, -+ "GetNameOwner"); -+ g_dbus_message_set_body (message, g_variant_new ("(s)", name_watcher->arg0)); -+ -+ if (g_dbus_connection_send_message_unlocked (connection, message, -+ G_DBUS_SEND_MESSAGE_FLAGS_NONE, -+ &watched_name->get_name_owner_serial, -+ &local_error)) -+ { -+ g_assert (watched_name->get_name_owner_serial != 0); -+ g_hash_table_insert (connection->map_method_serial_to_name_watcher, -+ GUINT_TO_POINTER (watched_name->get_name_owner_serial), -+ name_watcher); -+ } -+ else -+ { -+ g_critical ("Error while sending GetNameOwner() message: %s", -+ local_error->message); -+ g_clear_error (&local_error); -+ g_assert (watched_name->get_name_owner_serial == 0); -+ } -+ -+ g_object_unref (message); -+} -+ -+/* ---------------------------------------------------------------------------------------------------- */ -+ - typedef struct - { - guint id; -@@ -2392,6 +2639,7 @@ on_worker_message_received (GDBusWorker *worker, - { - guint32 reply_serial; - GTask *task; -+ SignalData *name_watcher; - - reply_serial = g_dbus_message_get_reply_serial (message); - CONNECTION_LOCK (connection); -@@ -2407,6 +2655,19 @@ on_worker_message_received (GDBusWorker *worker, - { - //g_debug ("message reply/error for serial %d but no SendMessageData found for %p", reply_serial, connection); - } -+ -+ name_watcher = g_hash_table_lookup (connection->map_method_serial_to_name_watcher, -+ GUINT_TO_POINTER (reply_serial)); -+ -+ if (name_watcher != NULL) -+ { -+ g_assert (name_watcher->watched_name != NULL); -+ g_assert (name_watcher->watched_name->get_name_owner_serial == reply_serial); -+ name_watcher_deliver_get_name_owner_reply_unlocked (name_watcher, -+ connection, -+ message); -+ } -+ - CONNECTION_UNLOCK (connection); - } - else if (message_type == G_DBUS_MESSAGE_TYPE_SIGNAL) -@@ -3586,6 +3847,7 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - { - gchar *rule; - SignalData *signal_data; -+ SignalData *name_watcher = NULL; - SignalSubscriber *subscriber; - gboolean sender_is_its_own_owner; - const gchar *sender_unique_name; -@@ -3651,13 +3913,59 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection, - - signal_data = signal_data_new_take (g_steal_pointer (&rule), - g_strdup (sender), -- sender_is_its_own_owner, - g_strdup (interface_name), - g_strdup (member), - g_strdup (object_path), - g_strdup (arg0), - flags); - g_ptr_array_add (signal_data->subscribers, subscriber); -+ -+ /* If subscribing to a signal from a specific sender with a well-known -+ * name, we must first subscribe to NameOwnerChanged signals for that -+ * well-known name, so that we can match the current owner of the name -+ * against the sender of each signal. */ -+ if (sender != NULL && !sender_is_its_own_owner) -+ { -+ gchar *name_owner_rule = NULL; -+ -+ /* We already checked that sender != NULL implies MESSAGE_BUS_CONNECTION */ -+ g_assert (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION); -+ -+ name_owner_rule = args_to_rule (DBUS_SERVICE_DBUS, -+ DBUS_INTERFACE_DBUS, -+ "NameOwnerChanged", -+ DBUS_PATH_DBUS, -+ sender, -+ G_DBUS_SIGNAL_FLAGS_NONE); -+ name_watcher = g_hash_table_lookup (connection->map_rule_to_signal_data, name_owner_rule); -+ -+ if (name_watcher == NULL) -+ { -+ name_watcher = signal_data_new_take (g_steal_pointer (&name_owner_rule), -+ g_strdup (DBUS_SERVICE_DBUS), -+ g_strdup (DBUS_INTERFACE_DBUS), -+ g_strdup ("NameOwnerChanged"), -+ g_strdup (DBUS_PATH_DBUS), -+ g_strdup (sender), -+ G_DBUS_SIGNAL_FLAGS_NONE); -+ add_signal_data (connection, name_watcher, DBUS_SERVICE_DBUS); -+ } -+ -+ if (name_watcher->watched_name == NULL) -+ { -+ name_watcher->watched_name = watched_name_new (); -+ name_watcher_call_get_name_owner_unlocked (connection, name_watcher); -+ } -+ else -+ { -+ g_ref_count_inc (&name_watcher->watched_name->ref_count); -+ } -+ -+ signal_data->shared_name_watcher = name_watcher; -+ -+ g_clear_pointer (&name_owner_rule, g_free); -+ } -+ - add_signal_data (connection, signal_data, sender_unique_name); - - out: -@@ -3685,10 +3993,18 @@ remove_signal_data_if_unused (GDBusConnection *connection, - const gchar *sender_unique_name; - GPtrArray *signal_data_array; - -+ /* Cannot remove while there are still subscribers */ - if (signal_data->subscribers->len != 0) - return; - -- if (signal_data->sender_is_its_own_owner) -+ /* Cannot remove while another SignalData is still using this one -+ * as its shared_name_watcher, which holds watched_name->ref_count > 0 */ -+ if (signal_data->watched_name != NULL) -+ return; -+ -+ /* Point of no return: we have committed to removing it */ -+ -+ if (signal_data->sender != NULL && signal_data->shared_name_watcher == NULL) - sender_unique_name = signal_data->sender; - else - sender_unique_name = ""; -@@ -3721,6 +4037,15 @@ remove_signal_data_if_unused (GDBusConnection *connection, - remove_match_rule (connection, signal_data->rule); - } - -+ if (signal_data->shared_name_watcher != NULL) -+ { -+ SignalData *name_watcher = g_steal_pointer (&signal_data->shared_name_watcher); -+ -+ name_watcher_unref_watched_name (connection, name_watcher); -+ /* May free signal_data */ -+ remove_signal_data_if_unused (connection, name_watcher); -+ } -+ - signal_data_free (signal_data); - } - -@@ -3990,6 +4315,17 @@ schedule_callbacks (GDBusConnection *connection, - continue; - } - -+ if (signal_data->watched_name != NULL) -+ { -+ /* Invariant: SignalData should only have a watched_name if it -+ * represents the NameOwnerChanged signal */ -+ g_assert (g_strcmp0 (sender, DBUS_SERVICE_DBUS) == 0); -+ g_assert (g_strcmp0 (interface, DBUS_INTERFACE_DBUS) == 0); -+ g_assert (g_strcmp0 (path, DBUS_PATH_DBUS) == 0); -+ g_assert (g_strcmp0 (member, "NameOwnerChanged") == 0); -+ name_watcher_deliver_name_owner_changed_unlocked (signal_data, message); -+ } -+ - for (m = 0; m < signal_data->subscribers->len; m++) - { - SignalSubscriber *subscriber = signal_data->subscribers->pdata[m]; -@@ -4051,7 +4387,7 @@ distribute_signals (GDBusConnection *connection, - schedule_callbacks (connection, signal_data_array, message, sender); - } - -- /* collect subscribers not matching on sender */ -+ /* collect subscribers not matching on sender, or matching a well-known name */ - signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, ""); - if (signal_data_array != NULL) - schedule_callbacks (connection, signal_data_array, message, sender); --- -2.45.0 - - -From ccaea1caa6ebafd931b6221f241dc90d5fd96e62 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Thu, 14 Mar 2024 20:42:41 +0000 -Subject: [PATCH 14/19] gdbusconnection: Don't deliver signals if the sender - doesn't match - -Otherwise a malicious connection on a shared bus, especially the system -bus, could trick GDBus clients into processing signals sent by the -malicious connection as though they had come from the real owner of a -well-known service name. - -Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/3268 -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index 6d18b2457..85f99c5c6 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -4296,6 +4296,46 @@ schedule_callbacks (GDBusConnection *connection, - if (signal_data->object_path != NULL && g_strcmp0 (signal_data->object_path, path) != 0) - continue; - -+ if (signal_data->shared_name_watcher != NULL) -+ { -+ /* We want signals from a specified well-known name, which means -+ * the signal's sender needs to be the unique name that currently -+ * owns that well-known name, and we will have found this -+ * SignalData in -+ * connection->map_sender_unique_name_to_signal_data_array[""]. */ -+ const WatchedName *watched_name; -+ const char *current_owner; -+ -+ g_assert (signal_data->sender != NULL); -+ /* Invariant: We never need to watch for the owner of a unique -+ * name, or for the owner of DBUS_SERVICE_DBUS, either of which -+ * is always its own owner */ -+ g_assert (!g_dbus_is_unique_name (signal_data->sender)); -+ g_assert (g_strcmp0 (signal_data->sender, DBUS_SERVICE_DBUS) != 0); -+ -+ watched_name = signal_data->shared_name_watcher->watched_name; -+ g_assert (watched_name != NULL); -+ current_owner = watched_name->owner; -+ -+ /* Skip the signal if the actual sender is not known to own -+ * the required name */ -+ if (current_owner == NULL || g_strcmp0 (current_owner, sender) != 0) -+ continue; -+ } -+ else if (signal_data->sender != NULL) -+ { -+ /* We want signals from a unique name or o.fd.DBus... */ -+ g_assert (g_dbus_is_unique_name (signal_data->sender) -+ || g_str_equal (signal_data->sender, DBUS_SERVICE_DBUS)); -+ -+ /* ... which means we must have found this SignalData in -+ * connection->map_sender_unique_name_to_signal_data_array[signal_data->sender], -+ * therefore we would only have found it if the signal's -+ * actual sender matches the required signal_data->sender */ -+ g_assert (g_strcmp0 (signal_data->sender, sender) == 0); -+ } -+ /* else the sender is unspecified and we will accept anything */ -+ - if (signal_data->arg0 != NULL) - { - if (arg0 == NULL) --- -2.45.0 - - -From 9fe1b11d43ca8f8d77ecf5e3f0976306d6d099ec Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Fri, 8 Mar 2024 19:51:50 +0000 -Subject: [PATCH 15/19] tests: Add a test for matching by two well-known names - -The expected result is that because TEST_CONN_SERVICE owns -ALREADY_OWNED_NAME but not (yet) OWNED_LATER_NAME, the signal will be -delivered to the subscriber for the former but not the latter. -Before #3268 was fixed, it was incorrectly delivered to both. - -Reproduces: https://gitlab.gnome.org/GNOME/glib/-/issues/3268 (partially) -Signed-off-by: Simon McVittie ---- - gio/tests/gdbus-subscribe.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c -index af100de7d..171d6107d 100644 ---- a/gio/tests/gdbus-subscribe.c -+++ b/gio/tests/gdbus-subscribe.c -@@ -440,6 +440,19 @@ static const TestPlan plan_limit_by_well_known_name = - .iface = EXAMPLE_INTERFACE, - }, - }, -+ { -+ /* When the service sends a signal with the name it already owns, -+ * it should get through */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 1, -+ .received_by_proxy = 1 -+ }, -+ }, - { - /* Service claims another name */ - .action = TEST_ACTION_OWN_NAME, --- -2.45.0 - - -From d9c20bc802c6f2fc8e36c51acad7a751de5f1b3f Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Fri, 8 Mar 2024 19:53:22 +0000 -Subject: [PATCH 16/19] tests: Add a test for signal filtering by well-known - name - -The vulnerability reported as GNOME/glib#3268 can be characterized -as: these signals from an attacker should not be delivered to either -the GDBusConnection or the GDBusProxy, but in fact they are (in at -least some scenarios). - -Reproduces: https://gitlab.gnome.org/GNOME/glib/-/issues/3268 -Signed-off-by: Simon McVittie ---- - gio/tests/gdbus-subscribe.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c -index 171d6107d..5406ba7e2 100644 ---- a/gio/tests/gdbus-subscribe.c -+++ b/gio/tests/gdbus-subscribe.c -@@ -440,6 +440,33 @@ static const TestPlan plan_limit_by_well_known_name = - .iface = EXAMPLE_INTERFACE, - }, - }, -+ { -+ /* Attacker wants to trick subscriber into thinking that service -+ * sent a signal */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_ATTACKER, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, -+ { -+ /* Attacker tries harder, by sending a signal unicast directly to -+ * the subscriber */ -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_ATTACKER, -+ .unicast_to = TEST_CONN_SUBSCRIBER, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 0, -+ .received_by_proxy = 0 -+ }, -+ }, - { - /* When the service sends a signal with the name it already owns, - * it should get through */ --- -2.45.0 - - -From 420402151349d1e34ea13b7585c76d3a51ba48f7 Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Tue, 23 Apr 2024 21:39:43 +0100 -Subject: [PATCH 17/19] tests: Ensure that unsubscribing with GetNameOwner - in-flight doesn't crash - -This was a bug that existed during development of this branch; make sure -it doesn't come back. - -This test fails with a use-after-free and crash if we comment out the -part of name_watcher_unref_watched_name() that removes the name watcher -from `map_method_serial_to_name_watcher`. - -It would also fail with an assertion failure if we asserted in -name_watcher_unref_watched_name() that get_name_owner_serial == 0 -(i.e. that GetNameOwner is not in-flight at destruction). - -Signed-off-by: Simon McVittie ---- - gio/tests/gdbus-subscribe.c | 52 ++++++++++++++++++++++++++++++++++++- - 1 file changed, 51 insertions(+), 1 deletion(-) - -diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c -index 5406ba7e2..4cba4f565 100644 ---- a/gio/tests/gdbus-subscribe.c -+++ b/gio/tests/gdbus-subscribe.c -@@ -116,6 +116,7 @@ typedef struct - const char *member; - const char *arg0; - GDBusSignalFlags flags; -+ gboolean unsubscribe_immediately; - } TestSubscribe; - - typedef struct -@@ -141,6 +142,7 @@ typedef struct - TestEmitSignal signal; - TestSubscribe subscribe; - TestOwnName own_name; -+ guint unsubscribe_undo_step; - } u; - } TestStep; - -@@ -505,6 +507,43 @@ static const TestPlan plan_limit_by_well_known_name = - }, - }; - -+static const TestPlan plan_unsubscribe_immediately = -+{ -+ .description = "Unsubscribing before GetNameOwner can return doesn't result in a crash", -+ .steps = { -+ { -+ /* Service already owns one name */ -+ .action = TEST_ACTION_OWN_NAME, -+ .u.own_name = { -+ .name = ALREADY_OWNED_NAME, -+ .owner = TEST_CONN_SERVICE -+ }, -+ }, -+ { -+ .action = TEST_ACTION_SUBSCRIBE, -+ .u.subscribe = { -+ .string_sender = ALREADY_OWNED_NAME, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .unsubscribe_immediately = TRUE -+ }, -+ }, -+ { -+ .action = TEST_ACTION_EMIT_SIGNAL, -+ .u.signal = { -+ .sender = TEST_CONN_SERVICE, -+ .path = EXAMPLE_PATH, -+ .iface = EXAMPLE_INTERFACE, -+ .member = FOO_SIGNAL, -+ .received_by_conn = 0, -+ /* The proxy can't unsubscribe, except by destroying the proxy -+ * completely, which we don't currently implement in this test */ -+ .received_by_proxy = 1 -+ }, -+ }, -+ }, -+}; -+ - static const TestPlan plan_limit_to_message_bus = - { - .description = "A subscription to the message bus only accepts messages " -@@ -855,8 +894,18 @@ fixture_subscribe (Fixture *f, - subscribe->flags, - subscribed_signal_cb, - f, NULL); -+ - g_assert_cmpuint (id, !=, 0); -- f->subscriptions[step_number] = id; -+ -+ if (subscribe->unsubscribe_immediately) -+ { -+ g_test_message ("\tImmediately unsubscribing"); -+ g_dbus_connection_signal_unsubscribe (subscriber, id); -+ } -+ else -+ { -+ f->subscriptions[step_number] = id; -+ } - } - - if (f->mode != SUBSCRIPTION_MODE_CONN) -@@ -1287,6 +1336,7 @@ main (int argc, - ADD_SUBSCRIBE_TEST (nonexistent_unique_name); - ADD_SUBSCRIBE_TEST (limit_by_well_known_name); - ADD_SUBSCRIBE_TEST (limit_to_message_bus); -+ ADD_SUBSCRIBE_TEST (unsubscribe_immediately); - - return g_test_run(); - } --- -2.45.0 - - -From 6762e278c870dfaad4b26329da5e24b2e9bdceda Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Wed, 8 May 2024 14:46:08 +0000 -Subject: [PATCH 18/19] gdbusconnection: Allow name owners to have the syntax - of a well-known name - -In a D-Bus-Specification-compliant message bus, the owner of a well-known -name is a unique name. However, ibus has its own small implementation -of a message bus (src/ibusbus.c) in which org.freedesktop.IBus is -special-cased to also have itself as its owner (like org.freedesktop.DBus -on a standard message bus), and connects to that bus with the -G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION flag. The ability to do -this regressed when CVE-2024-34397 was fixed. - -Relax the checks to allow the owner of a well-known name to be any valid -D-Bus name, even if it is not syntactically a unique name. - -Fixes: 683b14b9 "gdbus: Track name owners for signal subscriptions" -Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/3353 -Bug-Debian: https://bugs.debian.org/1070730 -Bug-Debian: https://bugs.debian.org/1070736 -Bug-Debian: https://bugs.debian.org/1070743 -Bug-Debian: https://bugs.debian.org/1070745 -Signed-off-by: Simon McVittie ---- - gio/gdbusconnection.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index 85f99c5c6..348b5b985 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -2406,7 +2406,10 @@ name_watcher_deliver_name_owner_changed_unlocked (SignalData *name_watcher, - /* Our caller already checked this */ - g_assert (g_strcmp0 (name_watcher->arg0, name) == 0); - -- if (G_LIKELY (new_owner[0] == '\0' || g_dbus_is_unique_name (new_owner))) -+ /* FIXME: This should be validating that `new_owner` is a unique name, -+ * but IBus’ implementation of a message bus is not compliant with the spec. -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/3353 */ -+ if (G_LIKELY (new_owner[0] == '\0' || g_dbus_is_name (new_owner))) - name_watcher_set_name_owner_unlocked (name_watcher, new_owner); - else - g_warning ("Received NameOwnerChanged signal with invalid owner \"%s\" for \"%s\"", -@@ -2458,7 +2461,10 @@ name_watcher_deliver_get_name_owner_reply_unlocked (SignalData *name_watcher, - - g_variant_get (body, "(&s)", &new_owner); - -- if (G_LIKELY (g_dbus_is_unique_name (new_owner))) -+ /* FIXME: This should be validating that `new_owner` is a unique name, -+ * but IBus’ implementation of a message bus is not compliant with the spec. -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/3353 */ -+ if (G_LIKELY (g_dbus_is_name (new_owner))) - name_watcher_set_name_owner_unlocked (name_watcher, new_owner); - else - g_warning ("Received GetNameOwner reply with invalid owner \"%s\" for \"%s\"", --- -2.45.0 - - -From 9ad45e2d6699157d8b233bc67881e55f9b71f613 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Wed, 8 May 2024 22:53:51 +0200 -Subject: [PATCH 19/19] gdbusmessage: Clean the cached arg0 when setting the - message body - -We're now caching arg0 but such value is not cleared when a new body is -set as it's in the connection filter test cases where we've a leak as -highlighted by both valgrind and leak sanitizer ---- - gio/gdbusmessage.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c -index 40a77dd92..7489c0ac4 100644 ---- a/gio/gdbusmessage.c -+++ b/gio/gdbusmessage.c -@@ -1127,10 +1127,12 @@ g_dbus_message_set_body (GDBusMessage *message, - - if (message->body != NULL) - g_variant_unref (message->body); -+ -+ g_clear_pointer (&message->arg0_cache, g_variant_unref); -+ - if (body == NULL) - { - message->body = NULL; -- message->arg0_cache = NULL; - g_dbus_message_set_signature (message, NULL); - } - else -@@ -1144,8 +1146,6 @@ g_dbus_message_set_body (GDBusMessage *message, - if (g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE) && - g_variant_n_children (message->body) > 0) - message->arg0_cache = g_variant_get_child_value (message->body, 0); -- else -- message->arg0_cache = NULL; - - type_string = g_variant_get_type_string (body); - type_string_len = strlen (type_string); --- -2.45.0 - diff --git a/base/rx-glib2/glib-change-version.patch b/base/rx-glib2/glib-change-version.patch deleted file mode 100644 index a8b378b..0000000 --- a/base/rx-glib2/glib-change-version.patch +++ /dev/null @@ -1,2133 +0,0 @@ -diff -Naur a/gio/gdbus-2.0/codegen/meson.build b/gio/gdbus-2.0/codegen/meson.build ---- a/gio/gdbus-2.0/codegen/meson.build 2021-08-19 21:27:25.686339000 +0600 -+++ b/gio/gdbus-2.0/codegen/meson.build 2024-06-20 09:59:13.236516507 +0600 -@@ -24,7 +24,7 @@ - # Provide tools for others when we're a subproject and they use the Meson GNOME module - meson.override_find_program('gdbus-codegen', gdbus_codegen) - --codegen_dir = join_paths(glib_datadir, 'glib-2.0', 'codegen') -+codegen_dir = join_paths(glib_datadir, 'glib-2.00', 'codegen') - - gdbus_codegen_built_files = [] - gdbus_codegen_built_files += configure_file(input : 'config.py.in', -diff -Naur a/gio/gschema-2.00.its b/gio/gschema-2.00.its ---- a/gio/gschema-2.00.its 1970-01-01 06:00:00.000000000 +0600 -+++ b/gio/gschema-2.00.its 2021-08-19 21:27:25.713339800 +0600 -@@ -0,0 +1,25 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff -Naur a/gio/gschema-2.00.loc b/gio/gschema-2.00.loc ---- a/gio/gschema-2.00.loc 1970-01-01 06:00:00.000000000 +0600 -+++ b/gio/gschema-2.00.loc 2021-08-19 21:27:25.713339800 +0600 -@@ -0,0 +1,10 @@ -+ -+ -+ -+ -+ -+ -+ -diff -Naur a/gio/gschema.its b/gio/gschema.its ---- a/gio/gschema.its 2021-08-19 21:27:25.713339000 +0600 -+++ b/gio/gschema.its 1970-01-01 06:00:00.000000000 +0600 -@@ -1,25 +0,0 @@ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -diff -Naur a/gio/gschema.loc b/gio/gschema.loc ---- a/gio/gschema.loc 2021-08-19 21:27:25.713339000 +0600 -+++ b/gio/gschema.loc 1970-01-01 06:00:00.000000000 +0600 -@@ -1,10 +0,0 @@ -- -- -- -- -- -- -- -diff -Naur a/gio/meson.build b/gio/meson.build ---- a/gio/meson.build 2021-08-19 21:27:25.727340000 +0600 -+++ b/gio/meson.build 2024-06-20 10:39:38.014030594 +0600 -@@ -170,7 +170,7 @@ - - gnetworking_h = configure_file(input : 'gnetworking.h.in', - output : 'gnetworking.h', -- install_dir : join_paths(get_option('includedir'), 'glib-2.0/gio'), -+ install_dir : join_paths(get_option('includedir'), 'glib-2.00/gio'), - configuration : gnetworking_h_conf) - - gdbus_headers = files( -@@ -420,7 +420,7 @@ - internal_deps += [xdgmime_lib] - internal_objects += [xdgmime_lib.extract_all_objects()] - -- install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio') -+ install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.00/gio') - - if glib_conf.has('HAVE_NETLINK') - unix_sources += files( -@@ -725,7 +725,7 @@ - gio_headers += application_headers - gio_headers += settings_headers - gio_headers += gdbus_headers --install_headers(gio_headers, subdir : 'glib-2.0/gio/') -+install_headers(gio_headers, subdir : 'glib-2.00/gio/') - - # We can't use gnome.mkenums() because the GNOME module looks for glib-mkenums - # in PATH, which means you can't bootstrap glib with its own glib-mkenums. -@@ -734,7 +734,7 @@ - capture : true, - input : gio_headers, - install : true, -- install_dir : join_paths(get_option('includedir'), 'glib-2.0/gio'), -+ install_dir : join_paths(get_option('includedir'), 'glib-2.00/gio'), - command : [python, glib_mkenums, - '--template', files('gioenumtypes.h.template'), - '@INPUT@', gnetworking_h]) -@@ -800,7 +800,7 @@ - gio_dtrace_hdr = [] - endif - --libgio = library('gio-2.0', -+libgio = library('gio-2.00', - gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources, - gio_dtrace_hdr, gio_dtrace_obj, - objects : internal_objects, -@@ -825,7 +825,7 @@ - pkgconfig_giomodulesdir = join_paths('${libdir}', 'gio', 'modules') - endif - --schemas_subdir = join_paths('glib-2.0', 'schemas') -+schemas_subdir = join_paths('glib-2.00', 'schemas') - - libgio_dep = declare_dependency(link_with : libgio, - dependencies : [libgmodule_dep, libgobject_dep, gioenumtypes_dep], -@@ -833,7 +833,7 @@ - - pkg.generate(libgio, - libraries_private : [osx_ldflags], -- requires : ['glib-2.0', 'gobject-2.0'], -+ requires : ['glib-2.00', 'gobject-2.00'], - variables : ['datadir=' + join_paths('${prefix}', get_option('datadir')), - 'schemasdir=' + join_paths('${datadir}', schemas_subdir), - 'bindir=' + join_paths('${prefix}', get_option('bindir')), -@@ -848,13 +848,13 @@ - 'gsettings=' + join_paths('${bindir}', 'gsettings')], - version : glib_version, - install_dir : glib_pkgconfigreldir, -- filebase : 'gio-2.0', -+ filebase : 'gio-2.00', - name : 'GIO', - description : 'glib I/O library', - ) - - if meson.version().version_compare('>=0.54.0') -- meson.override_dependency('gio-2.0', libgio_dep) -+ meson.override_dependency('gio-2.00', libgio_dep) - endif - - -@@ -871,16 +871,16 @@ - meson.override_dependency('gio-win32-2.0', libgio_dep) - endif - else -- pkg.generate(requires : ['gobject-2.0', 'gio-2.0'], -- subdirs : ['gio-unix-2.0'], -+ pkg.generate(requires : ['gobject-2.00', 'gio-2.00'], -+ subdirs : ['gio-unix-2.00'], - version : glib_version, - install_dir : glib_pkgconfigreldir, -- filebase : 'gio-unix-2.0', -+ filebase : 'gio-unix-2.00', - name : 'GIO unix specific APIs', - description : 'unix specific headers for glib I/O library', - ) - if meson.version().version_compare('>=0.54.0') -- meson.override_dependency('gio-unix-2.0', libgio_dep) -+ meson.override_dependency('gio-unix-2.00', libgio_dep) - endif - endif - -@@ -997,7 +997,7 @@ - install_data('gschema.dtd', - install_dir : join_paths(get_option('datadir'), schemas_subdir)) - --install_data(['gschema.loc', 'gschema.its'], -+install_data(['gschema-2.00.loc', 'gschema-2.00.its'], - install_dir : join_paths(get_option('datadir'), 'gettext/its')) - - executable('gdbus', 'gdbus-tool.c', -diff -Naur a/glib/meson.build b/glib/meson.build ---- a/glib/meson.build 2021-08-19 21:27:25.779340000 +0600 -+++ b/glib/meson.build 2024-06-20 09:41:17.032294858 +0600 -@@ -1,5 +1,5 @@ - configure_file(input : 'glibconfig.h.in', output : 'glibconfig.h', -- install_dir : join_paths(get_option('libdir'), 'glib-2.0/include'), -+ install_dir : join_paths(get_option('libdir'), 'glib-2.00/include'), - configuration : glibconfig_conf) - - subdir('libcharset') -@@ -128,7 +128,7 @@ - 'glib-unix.h', - 'glib-object.h', - ) --install_headers(glib_headers, subdir : 'glib-2.0') -+install_headers(glib_headers, subdir : 'glib-2.00') - - glib_deprecated_headers = files( - 'deprecated/gallocator.h', -@@ -138,7 +138,7 @@ - 'deprecated/grel.h', - 'deprecated/gthread.h', - ) --install_headers(glib_deprecated_headers, subdir : 'glib-2.0/glib/deprecated') -+install_headers(glib_deprecated_headers, subdir : 'glib-2.00/glib/deprecated') - - glib_sub_headers = files( - 'glib-autocleanups.h', -@@ -220,7 +220,7 @@ - 'gwin32.h', - 'gprintf.h', - ) --install_headers(glib_sub_headers, subdir : 'glib-2.0/glib') -+install_headers(glib_sub_headers, subdir : 'glib-2.00/glib') - - deprecated_sources = files( - 'deprecated/gallocator.c', -@@ -366,7 +366,7 @@ - endif - - glib_c_args = ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre_static_args + glib_hidden_visibility_args --libglib = library('glib-2.0', -+libglib = library('glib-2.00', - glib_dtrace_obj, glib_dtrace_hdr, - sources : [deprecated_sources, glib_sources], - objects : [charset_lib.extract_all_objects()] + gnulib_objects + pcre_objects, -@@ -391,8 +391,8 @@ - pkg.generate(libglib, - libraries : [libintl_deps], - libraries_private : [osx_ldflags, win32_ldflags], -- subdirs : ['glib-2.0'], -- extra_cflags : ['-I${libdir}/glib-2.0/include'] + win32_cflags, -+ subdirs : ['glib-2.00'], -+ extra_cflags : ['-I${libdir}/glib-2.00/include'] + win32_cflags, - variables : ['bindir=' + join_paths('${prefix}', get_option('bindir')), - 'glib_genmarshal=' + join_paths('${bindir}', 'glib-genmarshal'), - 'gobject_query=' + join_paths('${bindir}', 'gobject-query'), -@@ -405,7 +405,7 @@ - ) - - if meson.version().version_compare('>=0.54.0') -- meson.override_dependency('glib-2.0', libglib_dep) -+ meson.override_dependency('glib-2.00', libglib_dep) - endif - - # On Windows, glib needs a spawn helper for g_spawn* API -@@ -468,7 +468,7 @@ - endif - configure_file( - input: 'libglib-gdb.py.in', -- output: 'libglib-2.0.so.@0@-gdb.py'.format(library_version), -+ output: 'libglib-2.00.so.@0@-gdb.py'.format(library_version), - configuration: gdb_conf, - install_dir: gdb_install_dir, - ) -diff -Naur a/glib-gettextize.in b/glib-gettextize.in ---- a/glib-gettextize.in 2021-08-19 21:27:25.746340000 +0600 -+++ b/glib-gettextize.in 2024-06-20 10:31:50.068973445 +0600 -@@ -51,7 +51,7 @@ - datarootdir=@datarootdir@ - datadir=@datadir@ - --gettext_dir=$datadir/glib-2.0/gettext -+gettext_dir=$datadir/glib-2.00/gettext - - while test $# -gt 0; do - case "$1" in -diff -Naur a/gmodule/meson.build b/gmodule/meson.build ---- a/gmodule/meson.build 2021-08-19 21:27:25.798340000 +0600 -+++ b/gmodule/meson.build 2024-06-20 09:41:58.491030409 +0600 -@@ -59,7 +59,7 @@ - output : 'gmoduleconf.h', - configuration : gmoduleconf_conf) - --install_headers(['gmodule.h'], subdir : 'glib-2.0') -+install_headers(['gmodule.h'], subdir : 'glib-2.00') - - gmodule_sources = ['gmodule.c'] - if host_system == 'windows' -@@ -72,7 +72,7 @@ - gmodule_sources += [gmodule_win_res] - endif - --libgmodule = library('gmodule-2.0', -+libgmodule = library('gmodule-2.00', - sources : gmodule_sources, - version : library_version, - soversion : soversion, -@@ -88,31 +88,31 @@ - - pkg.generate(libgmodule, - libraries : [thread_dep], -- requires : ['glib-2.0'], -+ requires : ['glib-2.00'], - version : glib_version, - variables : [supported_var], - install_dir : glib_pkgconfigreldir, -- filebase : 'gmodule-no-export-2.0', -+ filebase : 'gmodule-no-export-2.00', - name : 'GModule', - description : 'Dynamic module loader for GLib', - ) - - pkg.generate(libraries : [libgmodule, export_dynamic_ldflags], -- requires : ['glib-2.0'], -+ requires : ['glib-2.00'], - version : glib_version, - variables : [supported_var], - install_dir : glib_pkgconfigreldir, -- filebase : 'gmodule-export-2.0', -+ filebase : 'gmodule-export-2.00', - name : 'GModule', - description : 'Dynamic module loader for GLib', - ) - - pkg.generate(libraries : [libgmodule, export_dynamic_ldflags], -- requires : ['glib-2.0'], -+ requires : ['glib-2.00'], - version : glib_version, - variables : [supported_var], - install_dir : glib_pkgconfigreldir, -- filebase : 'gmodule-2.0', -+ filebase : 'gmodule-2.00', - name : 'GModule', - description : 'Dynamic module loader for GLib', - ) -@@ -122,7 +122,7 @@ - dependencies : [libglib_dep]) - - if meson.version().version_compare('>=0.54.0') -- meson.override_dependency('gmodule-no-export-2.0', libgmodule_dep) -- meson.override_dependency('gmodule-export-2.0', libgmodule_dep) -- meson.override_dependency('gmodule-2.0', libgmodule_dep) -+ meson.override_dependency('gmodule-no-export-2.00', libgmodule_dep) -+ meson.override_dependency('gmodule-export-2.00', libgmodule_dep) -+ meson.override_dependency('gmodule-2.00', libgmodule_dep) - endif -diff -Naur a/gobject/meson.build b/gobject/meson.build ---- a/gobject/meson.build 2021-08-19 21:27:25.803341000 +0600 -+++ b/gobject/meson.build 2024-06-20 09:42:28.155841189 +0600 -@@ -20,7 +20,7 @@ - 'gvaluetypes.h', - 'gobjectnotifyqueue.c', # sic - ) --install_headers(gobject_install_headers, subdir : 'glib-2.0/gobject') -+install_headers(gobject_install_headers, subdir : 'glib-2.00/gobject') - - gobject_sources = files( - 'gatomicarray.c', -@@ -101,7 +101,7 @@ - capture : true, - input : glib_enumtypes_input_headers, - install : true, -- install_dir : join_paths(get_option('includedir'), 'glib-2.0/gobject'), -+ install_dir : join_paths(get_option('includedir'), 'glib-2.00/gobject'), - command : [python, glib_mkenums, - '--template', files('glib-enumtypes.h.template'), - '@INPUT@']) -@@ -117,7 +117,7 @@ - - glib_enumtypes_dep = declare_dependency(sources : [glib_enumtypes_h]) - --libgobject = library('gobject-2.0', -+libgobject = library('gobject-2.00', - gobject_dtrace_obj, gobject_dtrace_hdr, glib_enumtypes_h, glib_enumtypes_c, - sources : gobject_sources, - version : library_version, -@@ -131,10 +131,10 @@ - ) - - pkg.generate(libgobject, -- requires : ['glib-2.0'], -+ requires : ['glib-2.00'], - version : glib_version, - install_dir : glib_pkgconfigreldir, -- filebase : 'gobject-2.0', -+ filebase : 'gobject-2.00', - name : 'GObject', - description : 'GLib Type, Object, Parameter and Signal Library', - ) -@@ -144,7 +144,7 @@ - dependencies : [libglib_dep, glib_enumtypes_dep]) - - if meson.version().version_compare('>=0.54.0') -- meson.override_dependency('gobject-2.0', libgobject_dep) -+ meson.override_dependency('gobject-2.00', libgobject_dep) - endif - - executable('gobject-query', 'gobject-query.c', -@@ -156,7 +156,7 @@ - gdb_conf.set('datadir', glib_datadir) - configure_file( - input: 'libgobject-gdb.py.in', -- output: 'libgobject-2.0.so.@0@-gdb.py'.format(library_version), -+ output: 'libgobject-2.00.so.@0@-gdb.py'.format(library_version), - configuration: gdb_conf, - install_dir: gdb_install_dir, - ) -diff -Naur a/gthread/meson.build b/gthread/meson.build ---- a/gthread/meson.build 2021-08-19 21:27:25.805341000 +0600 -+++ b/gthread/meson.build 2024-06-20 09:42:40.519762324 +0600 -@@ -12,7 +12,7 @@ - gthread_sources += [gthread_win_res] - endif - --libgthread = library('gthread-2.0', -+libgthread = library('gthread-2.00', - sources : gthread_sources, - version : library_version, - soversion : soversion, -@@ -25,10 +25,10 @@ - - pkg.generate(libgthread, - libraries : [thread_dep], -- requires : ['glib-2.0'], -+ requires : ['glib-2.00'], - version : glib_version, - install_dir : glib_pkgconfigreldir, -- filebase : 'gthread-2.0', -+ filebase : 'gthread-2.00', - name : 'GThread', - description : 'Thread support for GLib', - ) -@@ -36,5 +36,5 @@ - libgthread_dep = declare_dependency(link_with : libgthread) - - if meson.version().version_compare('>=0.54.0') -- meson.override_dependency('gthread-2.0', libgthread_dep) -+ meson.override_dependency('gthread-2.00', libgthread_dep) - endif -diff -Naur a/m4macros/glib-2.00.m4 b/m4macros/glib-2.00.m4 ---- a/m4macros/glib-2.00.m4 1970-01-01 06:00:00.000000000 +0600 -+++ b/m4macros/glib-2.00.m4 2024-06-20 09:43:31.857434862 +0600 -@@ -0,0 +1,215 @@ -+# Configure paths for GLIB -+# Owen Taylor 1997-2001 -+ -+# Increment this whenever this file is changed. -+#serial 4 -+ -+dnl AM_PATH_GLIB_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) -+dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject, -+dnl gthread, or gio is specified in MODULES, pass to pkg-config -+dnl -+AC_DEFUN([AM_PATH_GLIB_2_0], -+[dnl -+dnl Get the cflags and libraries from pkg-config -+dnl -+ -+dnl We can't use PKG_PREREQ because that needs 0.29. -+m4_ifndef([PKG_PROG_PKG_CONFIG], -+ [pkg.m4 version 0.28 or later is required]) -+ -+AC_ARG_ENABLE(glibtest, [ --disable-glibtest do not try to compile and run a test GLIB program], -+ , enable_glibtest=yes) -+ -+ min_glib_version=ifelse([$1], [], [2.0.0], [$1]) -+ pkg_config_args="glib-2.00 >= $min_glib_version" -+ for module in . $4 -+ do -+ case "$module" in -+ gmodule) -+ pkg_config_args="$pkg_config_args gmodule-2.00" -+ ;; -+ gmodule-no-export) -+ pkg_config_args="$pkg_config_args gmodule-no-export-2.00" -+ ;; -+ gobject) -+ pkg_config_args="$pkg_config_args gobject-2.00" -+ ;; -+ gthread) -+ pkg_config_args="$pkg_config_args gthread-2.00" -+ ;; -+ gio*) -+ pkg_config_args="$pkg_config_args $module-2.00" -+ ;; -+ esac -+ done -+ -+ PKG_PROG_PKG_CONFIG([0.16]) -+ -+ no_glib="" -+ -+ if test "x$PKG_CONFIG" = x ; then -+ no_glib=yes -+ PKG_CONFIG=no -+ fi -+ -+ dnl For GLIB_CFLAGS and GLIB_LIBS -+ PKG_CHECK_MODULES([GLIB], [$pkg_config_args], [:], [:]) -+ -+ dnl For the tools -+ PKG_CHECK_VAR([GLIB_GENMARSHAL], [glib-2.00], [glib_genmarshal]) -+ PKG_CHECK_VAR([GOBJECT_QUERY], [glib-2.00], [gobject_query]) -+ PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.00], [glib_mkenums]) -+ PKG_CHECK_VAR([GLIB_COMPILE_RESOURCES], [gio-2.00], [glib_compile_resources]) -+ -+ AC_MSG_CHECKING(for GLIB - version >= $min_glib_version) -+ -+ if test x$PKG_CONFIG != xno ; then -+ ## don't try to run the test against uninstalled libtool libs -+ if $PKG_CONFIG --uninstalled $pkg_config_args; then -+ echo "Will use uninstalled version of GLib found in PKG_CONFIG_PATH" -+ enable_glibtest=no -+ fi -+ -+ if $PKG_CONFIG --atleast-version $min_glib_version $pkg_config_args; then -+ : -+ else -+ no_glib=yes -+ fi -+ fi -+ -+ if test x"$no_glib" = x ; then -+ glib_config_major_version=`$PKG_CONFIG --modversion glib-2.00 | \ -+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` -+ glib_config_minor_version=`$PKG_CONFIG --modversion glib-2.00 | \ -+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` -+ glib_config_micro_version=`$PKG_CONFIG --modversion glib-2.00 | \ -+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` -+ if test "x$enable_glibtest" = "xyes" ; then -+ ac_save_CFLAGS="$CFLAGS" -+ ac_save_LIBS="$LIBS" -+ CFLAGS="$CFLAGS $GLIB_CFLAGS" -+ LIBS="$GLIB_LIBS $LIBS" -+dnl -+dnl Now check if the installed GLib is sufficiently new. (Also sanity -+dnl checks the results of pkg-config to some extent) -+dnl -+ rm -f conf.glibtest -+ AC_RUN_IFELSE([AC_LANG_SOURCE([[ -+#include -+#include -+#include -+ -+int -+main (void) -+{ -+ unsigned int major, minor, micro; -+ -+ fclose (fopen ("conf.glibtest", "w")); -+ -+ if (sscanf("$min_glib_version", "%u.%u.%u", &major, &minor, µ) != 3) { -+ printf("%s, bad version string\n", "$min_glib_version"); -+ exit(1); -+ } -+ -+ if ((glib_major_version != $glib_config_major_version) || -+ (glib_minor_version != $glib_config_minor_version) || -+ (glib_micro_version != $glib_config_micro_version)) -+ { -+ printf("\n*** 'pkg-config --modversion glib-2.00' returned %d.%d.%d, but GLIB (%d.%d.%d)\n", -+ $glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version, -+ glib_major_version, glib_minor_version, glib_micro_version); -+ printf ("*** was found! If pkg-config was correct, then it is best\n"); -+ printf ("*** to remove the old version of GLib. You may also be able to fix the error\n"); -+ printf("*** by modifying your LD_LIBRARY_PATH environment variable, or by editing\n"); -+ printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); -+ printf("*** required on your system.\n"); -+ printf("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n"); -+ printf("*** to point to the correct configuration files\n"); -+ } -+ else if ((glib_major_version != GLIB_MAJOR_VERSION) || -+ (glib_minor_version != GLIB_MINOR_VERSION) || -+ (glib_micro_version != GLIB_MICRO_VERSION)) -+ { -+ printf("*** GLib header files (version %d.%d.%d) do not match\n", -+ GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); -+ printf("*** library (version %d.%d.%d)\n", -+ glib_major_version, glib_minor_version, glib_micro_version); -+ } -+ else -+ { -+ if ((glib_major_version > major) || -+ ((glib_major_version == major) && (glib_minor_version > minor)) || -+ ((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro))) -+ { -+ return 0; -+ } -+ else -+ { -+ printf("\n*** An old version of GLib (%u.%u.%u) was found.\n", -+ glib_major_version, glib_minor_version, glib_micro_version); -+ printf("*** You need a version of GLib newer than %u.%u.%u. The latest version of\n", -+ major, minor, micro); -+ printf("*** GLib is always available from ftp://ftp.gtk.org.\n"); -+ printf("***\n"); -+ printf("*** If you have already installed a sufficiently new version, this error\n"); -+ printf("*** probably means that the wrong copy of the pkg-config shell script is\n"); -+ printf("*** being found. The easiest way to fix this is to remove the old version\n"); -+ printf("*** of GLib, but you can also set the PKG_CONFIG environment to point to the\n"); -+ printf("*** correct copy of pkg-config. (In this case, you will have to\n"); -+ printf("*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf\n"); -+ printf("*** so that the correct libraries are found at run-time))\n"); -+ } -+ } -+ return 1; -+} -+]])],[],[no_glib=yes],[echo $ac_n "cross compiling; assumed OK... $ac_c"]) -+ CFLAGS="$ac_save_CFLAGS" -+ LIBS="$ac_save_LIBS" -+ fi -+ fi -+ if test "x$no_glib" = x ; then -+ AC_MSG_RESULT(yes (version $glib_config_major_version.$glib_config_minor_version.$glib_config_micro_version)) -+ ifelse([$2], , :, [$2]) -+ else -+ AC_MSG_RESULT(no) -+ if test "$PKG_CONFIG" = "no" ; then -+ echo "*** A new enough version of pkg-config was not found." -+ echo "*** See http://www.freedesktop.org/software/pkgconfig/" -+ else -+ if test -f conf.glibtest ; then -+ : -+ else -+ echo "*** Could not run GLib test program, checking why..." -+ ac_save_CFLAGS="$CFLAGS" -+ ac_save_LIBS="$LIBS" -+ CFLAGS="$CFLAGS $GLIB_CFLAGS" -+ LIBS="$LIBS $GLIB_LIBS" -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -+#include -+#include -+]], [[ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ]])], -+ [ echo "*** The test program compiled, but did not run. This usually means" -+ echo "*** that the run-time linker is not finding GLib or finding the wrong" -+ echo "*** version of GLib. If it is not finding GLib, you'll need to set your" -+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" -+ echo "*** to the installed location Also, make sure you have run ldconfig if that" -+ echo "*** is required on your system" -+ echo "***" -+ echo "*** If you have an old version installed, it is best to remove it, although" -+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ], -+ [ echo "*** The test program failed to compile or link. See the file config.log for the" -+ echo "*** exact error that occurred. This usually means GLib is incorrectly installed."]) -+ CFLAGS="$ac_save_CFLAGS" -+ LIBS="$ac_save_LIBS" -+ fi -+ fi -+ GLIB_CFLAGS="" -+ GLIB_LIBS="" -+ GLIB_GENMARSHAL="" -+ GOBJECT_QUERY="" -+ GLIB_MKENUMS="" -+ GLIB_COMPILE_RESOURCES="" -+ ifelse([$3], , :, [$3]) -+ fi -+ rm -f conf.glibtest -+]) -diff -Naur a/m4macros/glib-2.0.m4 b/m4macros/glib-2.0.m4 ---- a/m4macros/glib-2.0.m4 2021-08-19 21:27:25.805341000 +0600 -+++ b/m4macros/glib-2.0.m4 1970-01-01 06:00:00.000000000 +0600 -@@ -1,215 +0,0 @@ --# Configure paths for GLIB --# Owen Taylor 1997-2001 -- --# Increment this whenever this file is changed. --#serial 4 -- --dnl AM_PATH_GLIB_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) --dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject, --dnl gthread, or gio is specified in MODULES, pass to pkg-config --dnl --AC_DEFUN([AM_PATH_GLIB_2_0], --[dnl --dnl Get the cflags and libraries from pkg-config --dnl -- --dnl We can't use PKG_PREREQ because that needs 0.29. --m4_ifndef([PKG_PROG_PKG_CONFIG], -- [pkg.m4 version 0.28 or later is required]) -- --AC_ARG_ENABLE(glibtest, [ --disable-glibtest do not try to compile and run a test GLIB program], -- , enable_glibtest=yes) -- -- min_glib_version=ifelse([$1], [], [2.0.0], [$1]) -- pkg_config_args="glib-2.0 >= $min_glib_version" -- for module in . $4 -- do -- case "$module" in -- gmodule) -- pkg_config_args="$pkg_config_args gmodule-2.0" -- ;; -- gmodule-no-export) -- pkg_config_args="$pkg_config_args gmodule-no-export-2.0" -- ;; -- gobject) -- pkg_config_args="$pkg_config_args gobject-2.0" -- ;; -- gthread) -- pkg_config_args="$pkg_config_args gthread-2.0" -- ;; -- gio*) -- pkg_config_args="$pkg_config_args $module-2.0" -- ;; -- esac -- done -- -- PKG_PROG_PKG_CONFIG([0.16]) -- -- no_glib="" -- -- if test "x$PKG_CONFIG" = x ; then -- no_glib=yes -- PKG_CONFIG=no -- fi -- -- dnl For GLIB_CFLAGS and GLIB_LIBS -- PKG_CHECK_MODULES([GLIB], [$pkg_config_args], [:], [:]) -- -- dnl For the tools -- PKG_CHECK_VAR([GLIB_GENMARSHAL], [glib-2.0], [glib_genmarshal]) -- PKG_CHECK_VAR([GOBJECT_QUERY], [glib-2.0], [gobject_query]) -- PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.0], [glib_mkenums]) -- PKG_CHECK_VAR([GLIB_COMPILE_RESOURCES], [gio-2.0], [glib_compile_resources]) -- -- AC_MSG_CHECKING(for GLIB - version >= $min_glib_version) -- -- if test x$PKG_CONFIG != xno ; then -- ## don't try to run the test against uninstalled libtool libs -- if $PKG_CONFIG --uninstalled $pkg_config_args; then -- echo "Will use uninstalled version of GLib found in PKG_CONFIG_PATH" -- enable_glibtest=no -- fi -- -- if $PKG_CONFIG --atleast-version $min_glib_version $pkg_config_args; then -- : -- else -- no_glib=yes -- fi -- fi -- -- if test x"$no_glib" = x ; then -- glib_config_major_version=`$PKG_CONFIG --modversion glib-2.0 | \ -- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` -- glib_config_minor_version=`$PKG_CONFIG --modversion glib-2.0 | \ -- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` -- glib_config_micro_version=`$PKG_CONFIG --modversion glib-2.0 | \ -- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` -- if test "x$enable_glibtest" = "xyes" ; then -- ac_save_CFLAGS="$CFLAGS" -- ac_save_LIBS="$LIBS" -- CFLAGS="$CFLAGS $GLIB_CFLAGS" -- LIBS="$GLIB_LIBS $LIBS" --dnl --dnl Now check if the installed GLib is sufficiently new. (Also sanity --dnl checks the results of pkg-config to some extent) --dnl -- rm -f conf.glibtest -- AC_RUN_IFELSE([AC_LANG_SOURCE([[ --#include --#include --#include -- --int --main (void) --{ -- unsigned int major, minor, micro; -- -- fclose (fopen ("conf.glibtest", "w")); -- -- if (sscanf("$min_glib_version", "%u.%u.%u", &major, &minor, µ) != 3) { -- printf("%s, bad version string\n", "$min_glib_version"); -- exit(1); -- } -- -- if ((glib_major_version != $glib_config_major_version) || -- (glib_minor_version != $glib_config_minor_version) || -- (glib_micro_version != $glib_config_micro_version)) -- { -- printf("\n*** 'pkg-config --modversion glib-2.0' returned %d.%d.%d, but GLIB (%d.%d.%d)\n", -- $glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version, -- glib_major_version, glib_minor_version, glib_micro_version); -- printf ("*** was found! If pkg-config was correct, then it is best\n"); -- printf ("*** to remove the old version of GLib. You may also be able to fix the error\n"); -- printf("*** by modifying your LD_LIBRARY_PATH environment variable, or by editing\n"); -- printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); -- printf("*** required on your system.\n"); -- printf("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n"); -- printf("*** to point to the correct configuration files\n"); -- } -- else if ((glib_major_version != GLIB_MAJOR_VERSION) || -- (glib_minor_version != GLIB_MINOR_VERSION) || -- (glib_micro_version != GLIB_MICRO_VERSION)) -- { -- printf("*** GLib header files (version %d.%d.%d) do not match\n", -- GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); -- printf("*** library (version %d.%d.%d)\n", -- glib_major_version, glib_minor_version, glib_micro_version); -- } -- else -- { -- if ((glib_major_version > major) || -- ((glib_major_version == major) && (glib_minor_version > minor)) || -- ((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro))) -- { -- return 0; -- } -- else -- { -- printf("\n*** An old version of GLib (%u.%u.%u) was found.\n", -- glib_major_version, glib_minor_version, glib_micro_version); -- printf("*** You need a version of GLib newer than %u.%u.%u. The latest version of\n", -- major, minor, micro); -- printf("*** GLib is always available from ftp://ftp.gtk.org.\n"); -- printf("***\n"); -- printf("*** If you have already installed a sufficiently new version, this error\n"); -- printf("*** probably means that the wrong copy of the pkg-config shell script is\n"); -- printf("*** being found. The easiest way to fix this is to remove the old version\n"); -- printf("*** of GLib, but you can also set the PKG_CONFIG environment to point to the\n"); -- printf("*** correct copy of pkg-config. (In this case, you will have to\n"); -- printf("*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf\n"); -- printf("*** so that the correct libraries are found at run-time))\n"); -- } -- } -- return 1; --} --]])],[],[no_glib=yes],[echo $ac_n "cross compiling; assumed OK... $ac_c"]) -- CFLAGS="$ac_save_CFLAGS" -- LIBS="$ac_save_LIBS" -- fi -- fi -- if test "x$no_glib" = x ; then -- AC_MSG_RESULT(yes (version $glib_config_major_version.$glib_config_minor_version.$glib_config_micro_version)) -- ifelse([$2], , :, [$2]) -- else -- AC_MSG_RESULT(no) -- if test "$PKG_CONFIG" = "no" ; then -- echo "*** A new enough version of pkg-config was not found." -- echo "*** See http://www.freedesktop.org/software/pkgconfig/" -- else -- if test -f conf.glibtest ; then -- : -- else -- echo "*** Could not run GLib test program, checking why..." -- ac_save_CFLAGS="$CFLAGS" -- ac_save_LIBS="$LIBS" -- CFLAGS="$CFLAGS $GLIB_CFLAGS" -- LIBS="$LIBS $GLIB_LIBS" -- AC_LINK_IFELSE([AC_LANG_PROGRAM([[ --#include --#include --]], [[ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ]])], -- [ echo "*** The test program compiled, but did not run. This usually means" -- echo "*** that the run-time linker is not finding GLib or finding the wrong" -- echo "*** version of GLib. If it is not finding GLib, you'll need to set your" -- echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" -- echo "*** to the installed location Also, make sure you have run ldconfig if that" -- echo "*** is required on your system" -- echo "***" -- echo "*** If you have an old version installed, it is best to remove it, although" -- echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ], -- [ echo "*** The test program failed to compile or link. See the file config.log for the" -- echo "*** exact error that occurred. This usually means GLib is incorrectly installed."]) -- CFLAGS="$ac_save_CFLAGS" -- LIBS="$ac_save_LIBS" -- fi -- fi -- GLIB_CFLAGS="" -- GLIB_LIBS="" -- GLIB_GENMARSHAL="" -- GOBJECT_QUERY="" -- GLIB_MKENUMS="" -- GLIB_COMPILE_RESOURCES="" -- ifelse([$3], , :, [$3]) -- fi -- rm -f conf.glibtest --]) -diff -Naur a/m4macros/glib-gettext-2.00.m4 b/m4macros/glib-gettext-2.00.m4 ---- a/m4macros/glib-gettext-2.00.m4 1970-01-01 06:00:00.000000000 +0600 -+++ b/m4macros/glib-gettext-2.00.m4 2021-08-19 21:27:25.805341000 +0600 -@@ -0,0 +1,486 @@ -+# Copyright (C) 1995-2002 Free Software Foundation, Inc. -+# Copyright (C) 2001-2003,2004 Red Hat, Inc. -+# -+# This file is free software, distributed under the terms of the GNU -+# General Public License. As a special exception to the GNU General -+# Public License, this file may be distributed as part of a program -+# that contains a configuration script generated by Autoconf, under -+# the same distribution terms as the rest of that program. -+# -+# This file can be copied and used freely without restrictions. It can -+# be used in projects which are not available under the GNU Public License -+# but which still want to provide support for the GNU gettext functionality. -+# -+# Macro to add for using GNU gettext. -+# Ulrich Drepper , 1995, 1996 -+# -+# Modified to never use included libintl. -+# Owen Taylor , 12/15/1998 -+# -+# Major rework to remove unused code -+# Owen Taylor , 12/11/2002 -+# -+# Added better handling of ALL_LINGUAS from GNU gettext version -+# written by Bruno Haible, Owen Taylor 5/30/3002 -+# -+# Modified to require ngettext -+# Matthias Clasen 08/06/2004 -+ -+# Increment this whenever this file is changed. -+#serial 1 -+ -+# We need this here as well, since someone might use autoconf-2.5x -+# to configure GLib then an older version to configure a package -+# using AM_GLIB_GNU_GETTEXT -+AC_PREREQ(2.53) -+ -+dnl -+dnl We go to great lengths to make sure that aclocal won't -+dnl try to pull in the installed version of these macros -+dnl when running aclocal in the glib directory. -+dnl -+m4_copy([AC_DEFUN],[glib_DEFUN]) -+m4_copy([AC_REQUIRE],[glib_REQUIRE]) -+dnl -+dnl At the end, if we're not within glib, we'll define the public -+dnl definitions in terms of our private definitions. -+dnl -+ -+# GLIB_LC_MESSAGES -+#-------------------- -+glib_DEFUN([GLIB_LC_MESSAGES], -+ [AC_CHECK_HEADERS([locale.h]) -+ if test $ac_cv_header_locale_h = yes; then -+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, -+ [AC_TRY_LINK([#include ], [return LC_MESSAGES], -+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) -+ if test $am_cv_val_LC_MESSAGES = yes; then -+ AC_DEFINE(HAVE_LC_MESSAGES, 1, -+ [Define if your file defines LC_MESSAGES.]) -+ fi -+ fi]) -+ -+# GLIB_PATH_PROG_WITH_TEST -+#---------------------------- -+dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, -+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) -+glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], -+[# Extract the first word of "$2", so it can be a program name with args. -+set dummy $2; ac_word=[$]2 -+AC_MSG_CHECKING([for $ac_word]) -+AC_CACHE_VAL(ac_cv_path_$1, -+[case "[$]$1" in -+ /*) -+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path. -+ ;; -+ *) -+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" -+ for ac_dir in ifelse([$5], , $PATH, [$5]); do -+ test -z "$ac_dir" && ac_dir=. -+ if test -f $ac_dir/$ac_word; then -+ if [$3]; then -+ ac_cv_path_$1="$ac_dir/$ac_word" -+ break -+ fi -+ fi -+ done -+ IFS="$ac_save_ifs" -+dnl If no 4th arg is given, leave the cache variable unset, -+dnl so AC_PATH_PROGS will keep looking. -+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" -+])dnl -+ ;; -+esac])dnl -+$1="$ac_cv_path_$1" -+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then -+ AC_MSG_RESULT([$]$1) -+else -+ AC_MSG_RESULT(no) -+fi -+AC_SUBST($1)dnl -+]) -+ -+dnl Checks for special options needed on Mac OS X. -+dnl Defines INTL_MACOSX_LIBS. -+dnl -+dnl Copied from intlmacosx.m4 in gettext, GPL. -+dnl Copyright (C) 2004-2013 Free Software Foundation, Inc. -+glib_DEFUN([glib_gt_INTL_MACOSX], -+[ -+ dnl Check for API introduced in Mac OS X 10.2. -+ AC_CACHE_CHECK([for CFPreferencesCopyAppValue], -+ [gt_cv_func_CFPreferencesCopyAppValue], -+ [gt_save_LIBS="$LIBS" -+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" -+ AC_LINK_IFELSE( -+ [AC_LANG_PROGRAM( -+ [[#include ]], -+ [[CFPreferencesCopyAppValue(NULL, NULL)]])], -+ [gt_cv_func_CFPreferencesCopyAppValue=yes], -+ [gt_cv_func_CFPreferencesCopyAppValue=no]) -+ LIBS="$gt_save_LIBS"]) -+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then -+ AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], -+ [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) -+ fi -+ dnl Check for API introduced in Mac OS X 10.3. -+ AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], -+ [gt_save_LIBS="$LIBS" -+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" -+ AC_LINK_IFELSE( -+ [AC_LANG_PROGRAM( -+ [[#include ]], -+ [[CFLocaleCopyCurrent();]])], -+ [gt_cv_func_CFLocaleCopyCurrent=yes], -+ [gt_cv_func_CFLocaleCopyCurrent=no]) -+ LIBS="$gt_save_LIBS"]) -+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then -+ AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], -+ [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) -+ fi -+ INTL_MACOSX_LIBS= -+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then -+ INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" -+ fi -+ AC_SUBST([INTL_MACOSX_LIBS]) -+]) -+ -+# GLIB_WITH_NLS -+#----------------- -+glib_DEFUN([GLIB_WITH_NLS], -+ dnl NLS is obligatory -+ [USE_NLS=yes -+ AC_SUBST(USE_NLS) -+ -+ gt_cv_have_gettext=no -+ -+ CATOBJEXT=NONE -+ XGETTEXT=: -+ INTLLIBS= -+ -+ glib_gt_INTL_MACOSX -+ -+ AC_CHECK_HEADER(libintl.h, -+ [gt_cv_func_dgettext_libintl="no" -+ libintl_extra_libs="" -+ -+ # -+ # First check in libc -+ # -+ AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc, -+ [AC_TRY_LINK([ -+#include -+], -+ [return !ngettext ("","", 1)], -+ gt_cv_func_ngettext_libc=yes, -+ gt_cv_func_ngettext_libc=no) -+ ]) -+ -+ if test "$gt_cv_func_ngettext_libc" = "yes" ; then -+ AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, -+ [AC_TRY_LINK([ -+#include -+], -+ [return !dgettext ("","")], -+ gt_cv_func_dgettext_libc=yes, -+ gt_cv_func_dgettext_libc=no) -+ ]) -+ fi -+ -+ if test "$gt_cv_func_ngettext_libc" = "yes" ; then -+ AC_CHECK_FUNCS(bind_textdomain_codeset) -+ fi -+ -+ # -+ # If we don't have everything we want, check in libintl -+ # -+ if test "$gt_cv_func_dgettext_libc" != "yes" \ -+ || test "$gt_cv_func_ngettext_libc" != "yes" \ -+ || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then -+ -+ AC_CHECK_LIB(intl, bindtextdomain, -+ [AC_CHECK_LIB(intl, ngettext, -+ [AC_CHECK_LIB(intl, dgettext, -+ gt_cv_func_dgettext_libintl=yes)])]) -+ -+ if test "$gt_cv_func_dgettext_libintl" != "yes" ; then -+ AC_MSG_CHECKING([if -liconv is needed to use gettext]) -+ AC_MSG_RESULT([]) -+ AC_CHECK_LIB(intl, ngettext, -+ [AC_CHECK_LIB(intl, dcgettext, -+ [gt_cv_func_dgettext_libintl=yes -+ libintl_extra_libs=-liconv], -+ :,-liconv)], -+ :,-liconv) -+ fi -+ -+ # -+ # If we found libintl, then check in it for bind_textdomain_codeset(); -+ # we'll prefer libc if neither have bind_textdomain_codeset(), -+ # and both have dgettext and ngettext -+ # -+ if test "$gt_cv_func_dgettext_libintl" = "yes" ; then -+ glib_save_LIBS="$LIBS" -+ LIBS="$LIBS -lintl $libintl_extra_libs" -+ unset ac_cv_func_bind_textdomain_codeset -+ AC_CHECK_FUNCS(bind_textdomain_codeset) -+ LIBS="$glib_save_LIBS" -+ -+ if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then -+ gt_cv_func_dgettext_libc=no -+ else -+ if test "$gt_cv_func_dgettext_libc" = "yes" \ -+ && test "$gt_cv_func_ngettext_libc" = "yes"; then -+ gt_cv_func_dgettext_libintl=no -+ fi -+ fi -+ fi -+ fi -+ -+ if test "$gt_cv_func_dgettext_libc" = "yes" \ -+ || test "$gt_cv_func_dgettext_libintl" = "yes"; then -+ gt_cv_have_gettext=yes -+ fi -+ -+ if test "$gt_cv_func_dgettext_libintl" = "yes"; then -+ INTLLIBS="-lintl $libintl_extra_libs $INTL_MACOSX_LIBS" -+ fi -+ -+ if test "$gt_cv_have_gettext" = "yes"; then -+ AC_DEFINE(HAVE_GETTEXT,1, -+ [Define if the GNU gettext() function is already present or preinstalled.]) -+ GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, -+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl -+ if test "$MSGFMT" != "no"; then -+ glib_save_LIBS="$LIBS" -+ LIBS="$LIBS $INTLLIBS" -+ AC_CHECK_FUNCS(dcgettext) -+ MSGFMT_OPTS= -+ AC_MSG_CHECKING([if msgfmt accepts -c]) -+ GLIB_RUN_PROG([$MSGFMT -c -o /dev/null],[ -+msgid "" -+msgstr "" -+"Content-Type: text/plain; charset=UTF-8\n" -+"Project-Id-Version: test 1.0\n" -+"PO-Revision-Date: 2007-02-15 12:01+0100\n" -+"Last-Translator: test \n" -+"Language-Team: C \n" -+"MIME-Version: 1.0\n" -+"Content-Transfer-Encoding: 8bit\n" -+], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) -+ AC_SUBST(MSGFMT_OPTS) -+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) -+ GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, -+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) -+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; -+ return _nl_msg_cat_cntr], -+ [CATOBJEXT=.gmo -+ DATADIRNAME=share], -+ [case $host in -+ *-*-solaris*) -+ dnl On Solaris, if bind_textdomain_codeset is in libc, -+ dnl GNU format message catalog is always supported, -+ dnl since both are added to the libc all together. -+ dnl Hence, we'd like to go with DATADIRNAME=share and -+ dnl and CATOBJEXT=.gmo in this case. -+ AC_CHECK_FUNC(bind_textdomain_codeset, -+ [CATOBJEXT=.gmo -+ DATADIRNAME=share], -+ [CATOBJEXT=.mo -+ DATADIRNAME=lib]) -+ ;; -+ *-*-openbsd*) -+ CATOBJEXT=.mo -+ DATADIRNAME=share -+ ;; -+ *) -+ CATOBJEXT=.mo -+ DATADIRNAME=lib -+ ;; -+ esac]) -+ LIBS="$glib_save_LIBS" -+ INSTOBJEXT=.mo -+ else -+ gt_cv_have_gettext=no -+ fi -+ fi -+ ]) -+ -+ if test "$gt_cv_have_gettext" = "yes" ; then -+ AC_DEFINE(ENABLE_NLS, 1, -+ [always defined to indicate that i18n is enabled]) -+ fi -+ -+ dnl Test whether we really found GNU xgettext. -+ if test "$XGETTEXT" != ":"; then -+ dnl If it is not GNU xgettext we define it as : so that the -+ dnl Makefiles still can work. -+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then -+ : ; -+ else -+ AC_MSG_RESULT( -+ [found xgettext program is not GNU xgettext; ignore it]) -+ XGETTEXT=":" -+ fi -+ fi -+ -+ # We need to process the po/ directory. -+ POSUB=po -+ -+ AC_OUTPUT_COMMANDS( -+ [case "$CONFIG_FILES" in *po/Makefile.in*) -+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile -+ esac]) -+ -+ dnl These rules are solely for the distribution goal. While doing this -+ dnl we only have to keep exactly one list of the available catalogs -+ dnl in configure.ac. -+ for lang in $ALL_LINGUAS; do -+ GMOFILES="$GMOFILES $lang.gmo" -+ POFILES="$POFILES $lang.po" -+ done -+ -+ dnl Make all variables we use known to autoconf. -+ AC_SUBST(CATALOGS) -+ AC_SUBST(CATOBJEXT) -+ AC_SUBST(DATADIRNAME) -+ AC_SUBST(GMOFILES) -+ AC_SUBST(INSTOBJEXT) -+ AC_SUBST(INTLLIBS) -+ AC_SUBST(PO_IN_DATADIR_TRUE) -+ AC_SUBST(PO_IN_DATADIR_FALSE) -+ AC_SUBST(POFILES) -+ AC_SUBST(POSUB) -+ ]) -+ -+# AM_GLIB_GNU_GETTEXT -+# ------------------- -+# Do checks necessary for use of gettext. If a suitable implementation -+# of gettext is found in either in libintl or in the C library, -+# it will set INTLLIBS to the libraries needed for use of gettext -+# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable -+# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() -+# on various variables needed by the Makefile.in.in installed by -+# glib-gettextize. -+dnl -+AU_DEFUN([GLIB_GNU_GETTEXT], -+ [AC_REQUIRE([AC_PROG_CC])dnl -+ -+ GLIB_LC_MESSAGES -+ GLIB_WITH_NLS -+ -+ if test "$gt_cv_have_gettext" = "yes"; then -+ if test "x$ALL_LINGUAS" = "x"; then -+ LINGUAS= -+ else -+ AC_MSG_CHECKING(for catalogs to be installed) -+ NEW_LINGUAS= -+ for presentlang in $ALL_LINGUAS; do -+ useit=no -+ if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then -+ desiredlanguages="$LINGUAS" -+ else -+ desiredlanguages="$ALL_LINGUAS" -+ fi -+ for desiredlang in $desiredlanguages; do -+ # Use the presentlang catalog if desiredlang is -+ # a. equal to presentlang, or -+ # b. a variant of presentlang (because in this case, -+ # presentlang can be used as a fallback for messages -+ # which are not translated in the desiredlang catalog). -+ case "$desiredlang" in -+ "$presentlang"*) useit=yes;; -+ esac -+ done -+ if test $useit = yes; then -+ NEW_LINGUAS="$NEW_LINGUAS $presentlang" -+ fi -+ done -+ LINGUAS=$NEW_LINGUAS -+ AC_MSG_RESULT($LINGUAS) -+ fi -+ -+ dnl Construct list of names of catalog files to be constructed. -+ if test -n "$LINGUAS"; then -+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done -+ fi -+ fi -+ -+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly -+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir). -+ dnl Try to locate is. -+ MKINSTALLDIRS= -+ if test -n "$ac_aux_dir"; then -+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" -+ fi -+ if test -z "$MKINSTALLDIRS"; then -+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" -+ fi -+ AC_SUBST(MKINSTALLDIRS) -+ -+ dnl Generate list of files to be processed by xgettext which will -+ dnl be included in po/Makefile. -+ test -d po || mkdir po -+ if test "x$srcdir" != "x."; then -+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then -+ posrcprefix="$srcdir/" -+ else -+ posrcprefix="../$srcdir/" -+ fi -+ else -+ posrcprefix="../" -+ fi -+ rm -f po/POTFILES -+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ -+ < $srcdir/po/POTFILES.in > po/POTFILES -+ ], -+ [[$0: This macro is deprecated. You should use upstream gettext instead.]]) -+ -+# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) -+# ------------------------------- -+# Define VARIABLE to the location where catalog files will -+# be installed by po/Makefile. -+glib_DEFUN([GLIB_DEFINE_LOCALEDIR], -+[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl -+glib_save_prefix="$prefix" -+glib_save_exec_prefix="$exec_prefix" -+glib_save_datarootdir="$datarootdir" -+test "x$prefix" = xNONE && prefix=$ac_default_prefix -+test "x$exec_prefix" = xNONE && exec_prefix=$prefix -+datarootdir=`eval echo "${datarootdir}"` -+if test "x$CATOBJEXT" = "x.mo" ; then -+ localedir=`eval echo "${libdir}/locale"` -+else -+ localedir=`eval echo "${datadir}/locale"` -+fi -+prefix="$glib_save_prefix" -+exec_prefix="$glib_save_exec_prefix" -+datarootdir="$glib_save_datarootdir" -+AC_DEFINE_UNQUOTED($1, "$localedir", -+ [Define the location where the catalogs will be installed]) -+]) -+ -+dnl -+dnl Now the definitions that aclocal will find -+dnl -+ifdef(glib_configure_ac,[],[ -+AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) -+AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) -+])dnl -+ -+# GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL]) -+# -+# Create a temporary file with TEST-FILE as its contents and pass the -+# file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with -+# 0 and perform ACTION-IF-FAIL for any other exit status. -+AC_DEFUN([GLIB_RUN_PROG], -+[cat >conftest.foo <<_ACEOF -+$2 -+_ACEOF -+if AC_RUN_LOG([$1 conftest.foo]); then -+ m4_ifval([$3], [$3], [:]) -+m4_ifvaln([$4], [else $4])dnl -+echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD -+sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD -+fi]) -+ -diff -Naur a/m4macros/glib-gettext.m4 b/m4macros/glib-gettext.m4 ---- a/m4macros/glib-gettext.m4 2021-08-19 21:27:25.805341000 +0600 -+++ b/m4macros/glib-gettext.m4 1970-01-01 06:00:00.000000000 +0600 -@@ -1,486 +0,0 @@ --# Copyright (C) 1995-2002 Free Software Foundation, Inc. --# Copyright (C) 2001-2003,2004 Red Hat, Inc. --# --# This file is free software, distributed under the terms of the GNU --# General Public License. As a special exception to the GNU General --# Public License, this file may be distributed as part of a program --# that contains a configuration script generated by Autoconf, under --# the same distribution terms as the rest of that program. --# --# This file can be copied and used freely without restrictions. It can --# be used in projects which are not available under the GNU Public License --# but which still want to provide support for the GNU gettext functionality. --# --# Macro to add for using GNU gettext. --# Ulrich Drepper , 1995, 1996 --# --# Modified to never use included libintl. --# Owen Taylor , 12/15/1998 --# --# Major rework to remove unused code --# Owen Taylor , 12/11/2002 --# --# Added better handling of ALL_LINGUAS from GNU gettext version --# written by Bruno Haible, Owen Taylor 5/30/3002 --# --# Modified to require ngettext --# Matthias Clasen 08/06/2004 -- --# Increment this whenever this file is changed. --#serial 1 -- --# We need this here as well, since someone might use autoconf-2.5x --# to configure GLib then an older version to configure a package --# using AM_GLIB_GNU_GETTEXT --AC_PREREQ(2.53) -- --dnl --dnl We go to great lengths to make sure that aclocal won't --dnl try to pull in the installed version of these macros --dnl when running aclocal in the glib directory. --dnl --m4_copy([AC_DEFUN],[glib_DEFUN]) --m4_copy([AC_REQUIRE],[glib_REQUIRE]) --dnl --dnl At the end, if we're not within glib, we'll define the public --dnl definitions in terms of our private definitions. --dnl -- --# GLIB_LC_MESSAGES --#-------------------- --glib_DEFUN([GLIB_LC_MESSAGES], -- [AC_CHECK_HEADERS([locale.h]) -- if test $ac_cv_header_locale_h = yes; then -- AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, -- [AC_TRY_LINK([#include ], [return LC_MESSAGES], -- am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) -- if test $am_cv_val_LC_MESSAGES = yes; then -- AC_DEFINE(HAVE_LC_MESSAGES, 1, -- [Define if your file defines LC_MESSAGES.]) -- fi -- fi]) -- --# GLIB_PATH_PROG_WITH_TEST --#---------------------------- --dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, --dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) --glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], --[# Extract the first word of "$2", so it can be a program name with args. --set dummy $2; ac_word=[$]2 --AC_MSG_CHECKING([for $ac_word]) --AC_CACHE_VAL(ac_cv_path_$1, --[case "[$]$1" in -- /*) -- ac_cv_path_$1="[$]$1" # Let the user override the test with a path. -- ;; -- *) -- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" -- for ac_dir in ifelse([$5], , $PATH, [$5]); do -- test -z "$ac_dir" && ac_dir=. -- if test -f $ac_dir/$ac_word; then -- if [$3]; then -- ac_cv_path_$1="$ac_dir/$ac_word" -- break -- fi -- fi -- done -- IFS="$ac_save_ifs" --dnl If no 4th arg is given, leave the cache variable unset, --dnl so AC_PATH_PROGS will keep looking. --ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" --])dnl -- ;; --esac])dnl --$1="$ac_cv_path_$1" --if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then -- AC_MSG_RESULT([$]$1) --else -- AC_MSG_RESULT(no) --fi --AC_SUBST($1)dnl --]) -- --dnl Checks for special options needed on Mac OS X. --dnl Defines INTL_MACOSX_LIBS. --dnl --dnl Copied from intlmacosx.m4 in gettext, GPL. --dnl Copyright (C) 2004-2013 Free Software Foundation, Inc. --glib_DEFUN([glib_gt_INTL_MACOSX], --[ -- dnl Check for API introduced in Mac OS X 10.2. -- AC_CACHE_CHECK([for CFPreferencesCopyAppValue], -- [gt_cv_func_CFPreferencesCopyAppValue], -- [gt_save_LIBS="$LIBS" -- LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" -- AC_LINK_IFELSE( -- [AC_LANG_PROGRAM( -- [[#include ]], -- [[CFPreferencesCopyAppValue(NULL, NULL)]])], -- [gt_cv_func_CFPreferencesCopyAppValue=yes], -- [gt_cv_func_CFPreferencesCopyAppValue=no]) -- LIBS="$gt_save_LIBS"]) -- if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then -- AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], -- [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) -- fi -- dnl Check for API introduced in Mac OS X 10.3. -- AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], -- [gt_save_LIBS="$LIBS" -- LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" -- AC_LINK_IFELSE( -- [AC_LANG_PROGRAM( -- [[#include ]], -- [[CFLocaleCopyCurrent();]])], -- [gt_cv_func_CFLocaleCopyCurrent=yes], -- [gt_cv_func_CFLocaleCopyCurrent=no]) -- LIBS="$gt_save_LIBS"]) -- if test $gt_cv_func_CFLocaleCopyCurrent = yes; then -- AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], -- [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) -- fi -- INTL_MACOSX_LIBS= -- if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then -- INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" -- fi -- AC_SUBST([INTL_MACOSX_LIBS]) --]) -- --# GLIB_WITH_NLS --#----------------- --glib_DEFUN([GLIB_WITH_NLS], -- dnl NLS is obligatory -- [USE_NLS=yes -- AC_SUBST(USE_NLS) -- -- gt_cv_have_gettext=no -- -- CATOBJEXT=NONE -- XGETTEXT=: -- INTLLIBS= -- -- glib_gt_INTL_MACOSX -- -- AC_CHECK_HEADER(libintl.h, -- [gt_cv_func_dgettext_libintl="no" -- libintl_extra_libs="" -- -- # -- # First check in libc -- # -- AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc, -- [AC_TRY_LINK([ --#include --], -- [return !ngettext ("","", 1)], -- gt_cv_func_ngettext_libc=yes, -- gt_cv_func_ngettext_libc=no) -- ]) -- -- if test "$gt_cv_func_ngettext_libc" = "yes" ; then -- AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, -- [AC_TRY_LINK([ --#include --], -- [return !dgettext ("","")], -- gt_cv_func_dgettext_libc=yes, -- gt_cv_func_dgettext_libc=no) -- ]) -- fi -- -- if test "$gt_cv_func_ngettext_libc" = "yes" ; then -- AC_CHECK_FUNCS(bind_textdomain_codeset) -- fi -- -- # -- # If we don't have everything we want, check in libintl -- # -- if test "$gt_cv_func_dgettext_libc" != "yes" \ -- || test "$gt_cv_func_ngettext_libc" != "yes" \ -- || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then -- -- AC_CHECK_LIB(intl, bindtextdomain, -- [AC_CHECK_LIB(intl, ngettext, -- [AC_CHECK_LIB(intl, dgettext, -- gt_cv_func_dgettext_libintl=yes)])]) -- -- if test "$gt_cv_func_dgettext_libintl" != "yes" ; then -- AC_MSG_CHECKING([if -liconv is needed to use gettext]) -- AC_MSG_RESULT([]) -- AC_CHECK_LIB(intl, ngettext, -- [AC_CHECK_LIB(intl, dcgettext, -- [gt_cv_func_dgettext_libintl=yes -- libintl_extra_libs=-liconv], -- :,-liconv)], -- :,-liconv) -- fi -- -- # -- # If we found libintl, then check in it for bind_textdomain_codeset(); -- # we'll prefer libc if neither have bind_textdomain_codeset(), -- # and both have dgettext and ngettext -- # -- if test "$gt_cv_func_dgettext_libintl" = "yes" ; then -- glib_save_LIBS="$LIBS" -- LIBS="$LIBS -lintl $libintl_extra_libs" -- unset ac_cv_func_bind_textdomain_codeset -- AC_CHECK_FUNCS(bind_textdomain_codeset) -- LIBS="$glib_save_LIBS" -- -- if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then -- gt_cv_func_dgettext_libc=no -- else -- if test "$gt_cv_func_dgettext_libc" = "yes" \ -- && test "$gt_cv_func_ngettext_libc" = "yes"; then -- gt_cv_func_dgettext_libintl=no -- fi -- fi -- fi -- fi -- -- if test "$gt_cv_func_dgettext_libc" = "yes" \ -- || test "$gt_cv_func_dgettext_libintl" = "yes"; then -- gt_cv_have_gettext=yes -- fi -- -- if test "$gt_cv_func_dgettext_libintl" = "yes"; then -- INTLLIBS="-lintl $libintl_extra_libs $INTL_MACOSX_LIBS" -- fi -- -- if test "$gt_cv_have_gettext" = "yes"; then -- AC_DEFINE(HAVE_GETTEXT,1, -- [Define if the GNU gettext() function is already present or preinstalled.]) -- GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, -- [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl -- if test "$MSGFMT" != "no"; then -- glib_save_LIBS="$LIBS" -- LIBS="$LIBS $INTLLIBS" -- AC_CHECK_FUNCS(dcgettext) -- MSGFMT_OPTS= -- AC_MSG_CHECKING([if msgfmt accepts -c]) -- GLIB_RUN_PROG([$MSGFMT -c -o /dev/null],[ --msgid "" --msgstr "" --"Content-Type: text/plain; charset=UTF-8\n" --"Project-Id-Version: test 1.0\n" --"PO-Revision-Date: 2007-02-15 12:01+0100\n" --"Last-Translator: test \n" --"Language-Team: C \n" --"MIME-Version: 1.0\n" --"Content-Transfer-Encoding: 8bit\n" --], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) -- AC_SUBST(MSGFMT_OPTS) -- AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) -- GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, -- [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) -- AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; -- return _nl_msg_cat_cntr], -- [CATOBJEXT=.gmo -- DATADIRNAME=share], -- [case $host in -- *-*-solaris*) -- dnl On Solaris, if bind_textdomain_codeset is in libc, -- dnl GNU format message catalog is always supported, -- dnl since both are added to the libc all together. -- dnl Hence, we'd like to go with DATADIRNAME=share and -- dnl and CATOBJEXT=.gmo in this case. -- AC_CHECK_FUNC(bind_textdomain_codeset, -- [CATOBJEXT=.gmo -- DATADIRNAME=share], -- [CATOBJEXT=.mo -- DATADIRNAME=lib]) -- ;; -- *-*-openbsd*) -- CATOBJEXT=.mo -- DATADIRNAME=share -- ;; -- *) -- CATOBJEXT=.mo -- DATADIRNAME=lib -- ;; -- esac]) -- LIBS="$glib_save_LIBS" -- INSTOBJEXT=.mo -- else -- gt_cv_have_gettext=no -- fi -- fi -- ]) -- -- if test "$gt_cv_have_gettext" = "yes" ; then -- AC_DEFINE(ENABLE_NLS, 1, -- [always defined to indicate that i18n is enabled]) -- fi -- -- dnl Test whether we really found GNU xgettext. -- if test "$XGETTEXT" != ":"; then -- dnl If it is not GNU xgettext we define it as : so that the -- dnl Makefiles still can work. -- if $XGETTEXT --omit-header /dev/null 2> /dev/null; then -- : ; -- else -- AC_MSG_RESULT( -- [found xgettext program is not GNU xgettext; ignore it]) -- XGETTEXT=":" -- fi -- fi -- -- # We need to process the po/ directory. -- POSUB=po -- -- AC_OUTPUT_COMMANDS( -- [case "$CONFIG_FILES" in *po/Makefile.in*) -- sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile -- esac]) -- -- dnl These rules are solely for the distribution goal. While doing this -- dnl we only have to keep exactly one list of the available catalogs -- dnl in configure.ac. -- for lang in $ALL_LINGUAS; do -- GMOFILES="$GMOFILES $lang.gmo" -- POFILES="$POFILES $lang.po" -- done -- -- dnl Make all variables we use known to autoconf. -- AC_SUBST(CATALOGS) -- AC_SUBST(CATOBJEXT) -- AC_SUBST(DATADIRNAME) -- AC_SUBST(GMOFILES) -- AC_SUBST(INSTOBJEXT) -- AC_SUBST(INTLLIBS) -- AC_SUBST(PO_IN_DATADIR_TRUE) -- AC_SUBST(PO_IN_DATADIR_FALSE) -- AC_SUBST(POFILES) -- AC_SUBST(POSUB) -- ]) -- --# AM_GLIB_GNU_GETTEXT --# ------------------- --# Do checks necessary for use of gettext. If a suitable implementation --# of gettext is found in either in libintl or in the C library, --# it will set INTLLIBS to the libraries needed for use of gettext --# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable --# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() --# on various variables needed by the Makefile.in.in installed by --# glib-gettextize. --dnl --AU_DEFUN([GLIB_GNU_GETTEXT], -- [AC_REQUIRE([AC_PROG_CC])dnl -- -- GLIB_LC_MESSAGES -- GLIB_WITH_NLS -- -- if test "$gt_cv_have_gettext" = "yes"; then -- if test "x$ALL_LINGUAS" = "x"; then -- LINGUAS= -- else -- AC_MSG_CHECKING(for catalogs to be installed) -- NEW_LINGUAS= -- for presentlang in $ALL_LINGUAS; do -- useit=no -- if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then -- desiredlanguages="$LINGUAS" -- else -- desiredlanguages="$ALL_LINGUAS" -- fi -- for desiredlang in $desiredlanguages; do -- # Use the presentlang catalog if desiredlang is -- # a. equal to presentlang, or -- # b. a variant of presentlang (because in this case, -- # presentlang can be used as a fallback for messages -- # which are not translated in the desiredlang catalog). -- case "$desiredlang" in -- "$presentlang"*) useit=yes;; -- esac -- done -- if test $useit = yes; then -- NEW_LINGUAS="$NEW_LINGUAS $presentlang" -- fi -- done -- LINGUAS=$NEW_LINGUAS -- AC_MSG_RESULT($LINGUAS) -- fi -- -- dnl Construct list of names of catalog files to be constructed. -- if test -n "$LINGUAS"; then -- for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done -- fi -- fi -- -- dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly -- dnl find the mkinstalldirs script in another subdir but ($top_srcdir). -- dnl Try to locate is. -- MKINSTALLDIRS= -- if test -n "$ac_aux_dir"; then -- MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" -- fi -- if test -z "$MKINSTALLDIRS"; then -- MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" -- fi -- AC_SUBST(MKINSTALLDIRS) -- -- dnl Generate list of files to be processed by xgettext which will -- dnl be included in po/Makefile. -- test -d po || mkdir po -- if test "x$srcdir" != "x."; then -- if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then -- posrcprefix="$srcdir/" -- else -- posrcprefix="../$srcdir/" -- fi -- else -- posrcprefix="../" -- fi -- rm -f po/POTFILES -- sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ -- < $srcdir/po/POTFILES.in > po/POTFILES -- ], -- [[$0: This macro is deprecated. You should use upstream gettext instead.]]) -- --# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) --# ------------------------------- --# Define VARIABLE to the location where catalog files will --# be installed by po/Makefile. --glib_DEFUN([GLIB_DEFINE_LOCALEDIR], --[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl --glib_save_prefix="$prefix" --glib_save_exec_prefix="$exec_prefix" --glib_save_datarootdir="$datarootdir" --test "x$prefix" = xNONE && prefix=$ac_default_prefix --test "x$exec_prefix" = xNONE && exec_prefix=$prefix --datarootdir=`eval echo "${datarootdir}"` --if test "x$CATOBJEXT" = "x.mo" ; then -- localedir=`eval echo "${libdir}/locale"` --else -- localedir=`eval echo "${datadir}/locale"` --fi --prefix="$glib_save_prefix" --exec_prefix="$glib_save_exec_prefix" --datarootdir="$glib_save_datarootdir" --AC_DEFINE_UNQUOTED($1, "$localedir", -- [Define the location where the catalogs will be installed]) --]) -- --dnl --dnl Now the definitions that aclocal will find --dnl --ifdef(glib_configure_ac,[],[ --AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) --AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) --])dnl -- --# GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL]) --# --# Create a temporary file with TEST-FILE as its contents and pass the --# file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with --# 0 and perform ACTION-IF-FAIL for any other exit status. --AC_DEFUN([GLIB_RUN_PROG], --[cat >conftest.foo <<_ACEOF --$2 --_ACEOF --if AC_RUN_LOG([$1 conftest.foo]); then -- m4_ifval([$3], [$3], [:]) --m4_ifvaln([$4], [else $4])dnl --echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD --sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD --fi]) -- -diff -Naur a/m4macros/gsettings-2.00.m4 b/m4macros/gsettings-2.00.m4 ---- a/m4macros/gsettings-2.00.m4 1970-01-01 06:00:00.000000000 +0600 -+++ b/m4macros/gsettings-2.00.m4 2024-06-20 09:44:11.288183349 +0600 -@@ -0,0 +1,88 @@ -+# Increment this whenever this file is changed. -+#serial 2 -+ -+dnl GLIB_GSETTINGS -+dnl Defines GSETTINGS_SCHEMAS_INSTALL which controls whether -+dnl the schema should be compiled -+dnl -+ -+AC_DEFUN([GLIB_GSETTINGS], -+[ -+ dnl We can't use PKG_PREREQ because that needs 0.29. -+ m4_ifndef([PKG_PROG_PKG_CONFIG], -+ [pkg.m4 version 0.28 or later is required]) -+ -+ m4_pattern_allow([AM_V_GEN]) -+ AC_ARG_ENABLE(schemas-compile, -+ AS_HELP_STRING([--disable-schemas-compile], -+ [Disable regeneration of gschemas.compiled on install]), -+ [case ${enableval} in -+ yes) GSETTINGS_DISABLE_SCHEMAS_COMPILE="" ;; -+ no) GSETTINGS_DISABLE_SCHEMAS_COMPILE="1" ;; -+ *) AC_MSG_ERROR([bad value ${enableval} for --enable-schemas-compile]) ;; -+ esac]) -+ AC_SUBST([GSETTINGS_DISABLE_SCHEMAS_COMPILE]) -+ PKG_PROG_PKG_CONFIG([0.16]) -+ AC_SUBST(gsettingsschemadir, [${datadir}/glib-2.00/schemas]) -+ AS_IF([test x$cross_compiling != xyes], -+ [PKG_CHECK_VAR([GLIB_COMPILE_SCHEMAS], [gio-2.00], [glib_compile_schemas])], -+ [AC_PATH_PROG([GLIB_COMPILE_SCHEMAS], [glib-compile-schemas])]) -+ AC_SUBST(GLIB_COMPILE_SCHEMAS) -+ if test "x$GLIB_COMPILE_SCHEMAS" = "x"; then -+ ifelse([$2],,[AC_MSG_ERROR([glib-compile-schemas not found.])],[$2]) -+ else -+ ifelse([$1],,[:],[$1]) -+ fi -+ -+ GSETTINGS_RULES=' -+.PHONY : uninstall-gsettings-schemas install-gsettings-schemas clean-gsettings-schemas -+ -+mostlyclean-am: clean-gsettings-schemas -+ -+gsettings__enum_file = $(addsuffix .enums.xml,$(gsettings_ENUM_NAMESPACE)) -+ -+%.gschema.valid: %.gschema.xml $(gsettings__enum_file) -+ $(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) --strict --dry-run $(addprefix --schema-file=,$(gsettings__enum_file)) --schema-file=$< && mkdir -p [$](@D) && touch [$]@ -+ -+all-am: $(gsettings_SCHEMAS:.xml=.valid) -+uninstall-am: uninstall-gsettings-schemas -+install-data-am: install-gsettings-schemas -+ -+.SECONDARY: $(gsettings_SCHEMAS) -+ -+install-gsettings-schemas: $(gsettings_SCHEMAS) $(gsettings__enum_file) -+ @$(NORMAL_INSTALL) -+ if test -n "$^"; then \ -+ test -z "$(gsettingsschemadir)" || $(MKDIR_P) "$(DESTDIR)$(gsettingsschemadir)"; \ -+ $(INSTALL_DATA) $^ "$(DESTDIR)$(gsettingsschemadir)"; \ -+ test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir); \ -+ fi -+ -+uninstall-gsettings-schemas: -+ @$(NORMAL_UNINSTALL) -+ @list='\''$(gsettings_SCHEMAS) $(gsettings__enum_file)'\''; test -n "$(gsettingsschemadir)" || list=; \ -+ files=`for p in $$list; do echo $$p; done | sed -e '\''s|^.*/||'\''`; \ -+ test -n "$$files" || exit 0; \ -+ echo " ( cd '\''$(DESTDIR)$(gsettingsschemadir)'\'' && rm -f" $$files ")"; \ -+ cd "$(DESTDIR)$(gsettingsschemadir)" && rm -f $$files -+ test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir) -+ -+clean-gsettings-schemas: -+ rm -f $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file) -+ -+ifdef gsettings_ENUM_NAMESPACE -+$(gsettings__enum_file): $(gsettings_ENUM_FILES) -+ $(AM_V_GEN) glib-mkenums --comments '\'''\'' --fhead "" --vhead " <@type@ id='\''$(gsettings_ENUM_NAMESPACE).@EnumName@'\''>" --vprod " " --vtail " " --ftail "" [$]^ > [$]@.tmp && mv [$]@.tmp [$]@ -+endif -+' -+ _GSETTINGS_SUBST(GSETTINGS_RULES) -+]) -+ -+dnl _GSETTINGS_SUBST(VARIABLE) -+dnl Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST -+AC_DEFUN([_GSETTINGS_SUBST], -+[ -+AC_SUBST([$1]) -+m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])]) -+] -+) -diff -Naur a/m4macros/gsettings.m4 b/m4macros/gsettings.m4 ---- a/m4macros/gsettings.m4 2021-08-19 21:27:25.805341000 +0600 -+++ b/m4macros/gsettings.m4 1970-01-01 06:00:00.000000000 +0600 -@@ -1,88 +0,0 @@ --# Increment this whenever this file is changed. --#serial 2 -- --dnl GLIB_GSETTINGS --dnl Defines GSETTINGS_SCHEMAS_INSTALL which controls whether --dnl the schema should be compiled --dnl -- --AC_DEFUN([GLIB_GSETTINGS], --[ -- dnl We can't use PKG_PREREQ because that needs 0.29. -- m4_ifndef([PKG_PROG_PKG_CONFIG], -- [pkg.m4 version 0.28 or later is required]) -- -- m4_pattern_allow([AM_V_GEN]) -- AC_ARG_ENABLE(schemas-compile, -- AS_HELP_STRING([--disable-schemas-compile], -- [Disable regeneration of gschemas.compiled on install]), -- [case ${enableval} in -- yes) GSETTINGS_DISABLE_SCHEMAS_COMPILE="" ;; -- no) GSETTINGS_DISABLE_SCHEMAS_COMPILE="1" ;; -- *) AC_MSG_ERROR([bad value ${enableval} for --enable-schemas-compile]) ;; -- esac]) -- AC_SUBST([GSETTINGS_DISABLE_SCHEMAS_COMPILE]) -- PKG_PROG_PKG_CONFIG([0.16]) -- AC_SUBST(gsettingsschemadir, [${datadir}/glib-2.0/schemas]) -- AS_IF([test x$cross_compiling != xyes], -- [PKG_CHECK_VAR([GLIB_COMPILE_SCHEMAS], [gio-2.0], [glib_compile_schemas])], -- [AC_PATH_PROG([GLIB_COMPILE_SCHEMAS], [glib-compile-schemas])]) -- AC_SUBST(GLIB_COMPILE_SCHEMAS) -- if test "x$GLIB_COMPILE_SCHEMAS" = "x"; then -- ifelse([$2],,[AC_MSG_ERROR([glib-compile-schemas not found.])],[$2]) -- else -- ifelse([$1],,[:],[$1]) -- fi -- -- GSETTINGS_RULES=' --.PHONY : uninstall-gsettings-schemas install-gsettings-schemas clean-gsettings-schemas -- --mostlyclean-am: clean-gsettings-schemas -- --gsettings__enum_file = $(addsuffix .enums.xml,$(gsettings_ENUM_NAMESPACE)) -- --%.gschema.valid: %.gschema.xml $(gsettings__enum_file) -- $(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) --strict --dry-run $(addprefix --schema-file=,$(gsettings__enum_file)) --schema-file=$< && mkdir -p [$](@D) && touch [$]@ -- --all-am: $(gsettings_SCHEMAS:.xml=.valid) --uninstall-am: uninstall-gsettings-schemas --install-data-am: install-gsettings-schemas -- --.SECONDARY: $(gsettings_SCHEMAS) -- --install-gsettings-schemas: $(gsettings_SCHEMAS) $(gsettings__enum_file) -- @$(NORMAL_INSTALL) -- if test -n "$^"; then \ -- test -z "$(gsettingsschemadir)" || $(MKDIR_P) "$(DESTDIR)$(gsettingsschemadir)"; \ -- $(INSTALL_DATA) $^ "$(DESTDIR)$(gsettingsschemadir)"; \ -- test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir); \ -- fi -- --uninstall-gsettings-schemas: -- @$(NORMAL_UNINSTALL) -- @list='\''$(gsettings_SCHEMAS) $(gsettings__enum_file)'\''; test -n "$(gsettingsschemadir)" || list=; \ -- files=`for p in $$list; do echo $$p; done | sed -e '\''s|^.*/||'\''`; \ -- test -n "$$files" || exit 0; \ -- echo " ( cd '\''$(DESTDIR)$(gsettingsschemadir)'\'' && rm -f" $$files ")"; \ -- cd "$(DESTDIR)$(gsettingsschemadir)" && rm -f $$files -- test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir) -- --clean-gsettings-schemas: -- rm -f $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file) -- --ifdef gsettings_ENUM_NAMESPACE --$(gsettings__enum_file): $(gsettings_ENUM_FILES) -- $(AM_V_GEN) glib-mkenums --comments '\'''\'' --fhead "" --vhead " <@type@ id='\''$(gsettings_ENUM_NAMESPACE).@EnumName@'\''>" --vprod " " --vtail " " --ftail "" [$]^ > [$]@.tmp && mv [$]@.tmp [$]@ --endif --' -- _GSETTINGS_SUBST(GSETTINGS_RULES) --]) -- --dnl _GSETTINGS_SUBST(VARIABLE) --dnl Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST --AC_DEFUN([_GSETTINGS_SUBST], --[ --AC_SUBST([$1]) --m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])]) --] --) -diff -Naur a/meson.build b/meson.build ---- a/meson.build 2021-08-19 21:27:25.806341000 +0600 -+++ b/meson.build 2024-06-20 10:30:45.898377006 +0600 -@@ -71,7 +71,7 @@ - glib_libdir = join_paths(glib_prefix, get_option('libdir')) - glib_libexecdir = join_paths(glib_prefix, get_option('libexecdir')) - glib_datadir = join_paths(glib_prefix, get_option('datadir')) --glib_pkgdatadir = join_paths(glib_datadir, 'glib-2.0') -+glib_pkgdatadir = join_paths(glib_datadir, 'glib-2.00') - glib_includedir = join_paths(glib_prefix, get_option('includedir')) - if get_option('gio_module_dir') != '' - glib_giomodulesdir = join_paths(glib_prefix, get_option('gio_module_dir')) -@@ -129,10 +129,10 @@ - glib_conf.set('GLIB_MICRO_VERSION', micro_version) - glib_conf.set('GLIB_INTERFACE_AGE', interface_age) - glib_conf.set('GLIB_BINARY_AGE', binary_age) --glib_conf.set_quoted('GETTEXT_PACKAGE', 'glib20') -+glib_conf.set_quoted('GETTEXT_PACKAGE', 'glib200') - glib_conf.set_quoted('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new') - glib_conf.set_quoted('PACKAGE_NAME', 'glib') --glib_conf.set_quoted('PACKAGE_STRING', 'glib @0@'.format(meson.project_version())) -+glib_conf.set_quoted('PACKAGE_STRING', 'glib @00@'.format(meson.project_version())) - glib_conf.set_quoted('PACKAGE_TARNAME', 'glib') - glib_conf.set_quoted('PACKAGE_URL', '') - glib_conf.set_quoted('PACKAGE_VERSION', meson.project_version()) -@@ -2356,20 +2356,20 @@ - endif - - # Install m4 macros that other projects use --install_data('m4macros/glib-2.0.m4', 'm4macros/glib-gettext.m4', 'm4macros/gsettings.m4', -+install_data('m4macros/glib-2.00.m4', 'm4macros/glib-gettext-2.00.m4', 'm4macros/gsettings-2.00.m4', - install_dir : join_paths(get_option('datadir'), 'aclocal')) - - if host_system != 'windows' - # Install Valgrind suppression file (except on Windows, - # as Valgrind is currently not supported on Windows) - install_data('glib.supp', -- install_dir : join_paths(get_option('datadir'), 'glib-2.0', 'valgrind')) -+ install_dir : join_paths(get_option('datadir'), 'glib-2.00', 'valgrind')) - endif - - configure_file(output : 'config.h', configuration : glib_conf) - - if host_system == 'windows' -- install_headers([ 'msvc_recommended_pragmas.h' ], subdir : 'glib-2.0') -+ install_headers([ 'msvc_recommended_pragmas.h' ], subdir : 'glib-2.00') - endif - - if get_option('man') -diff -Naur a/po/Makefile.in.in b/po/Makefile.in.in ---- a/po/Makefile.in.in 2021-08-19 21:27:25.806341000 +0600 -+++ b/po/Makefile.in.in 2024-06-20 09:44:43.530977685 +0600 -@@ -30,7 +30,7 @@ - libdir = @libdir@ - localedir = $(libdir)/locale - gnulocaledir = $(datadir)/locale --gettextsrcdir = $(datadir)/glib-2.0/gettext/po -+gettextsrcdir = $(datadir)/glib-2.00/gettext/po - subdir = po - - INSTALL = @INSTALL@ -diff -Naur a/po/meson.build b/po/meson.build ---- a/po/meson.build 2021-08-19 21:27:25.851341000 +0600 -+++ b/po/meson.build 2024-06-20 09:44:23.055108292 +0600 -@@ -1,5 +1,5 @@ - i18n = import('i18n') - --i18n.gettext('glib20', preset: 'glib') -+i18n.gettext('glib200', preset: 'glib') - - install_data('Makefile.in.in', install_dir : glib_pkgdatadir + '/gettext/po') diff --git a/base/rx-glib2/glib2.spec b/base/rx-glib2/glib2.spec deleted file mode 100644 index e6266cf..0000000 --- a/base/rx-glib2/glib2.spec +++ /dev/null @@ -1,1012 +0,0 @@ -%bcond_without sysprof - -Name: glib2.00 -Version: 2.68.4 -Release: 15%{?dist} -Summary: A library of handy utility functions - -License: LGPLv2+ -URL: http://www.gtk.org -Source0: http://download.gnome.org/sources/glib/2.68/glib-%{version}.tar.xz - -# Required for RHEL core crypto components policy. Good for Fedora too. -# https://bugzilla.redhat.com/show_bug.cgi?id=1630260 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903 -Patch0: gnutls-hmac.patch - -# Add GPowerProfileMonitor -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1965 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2194 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2222 -Patch1: 1965.patch -Patch2: 2194.patch -Patch3: 2222.patch - -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2244 -Patch4: 2244.patch - -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2291 -Patch5: 2291.patch - -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1968 -Patch6: 1968.patch -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2435 -Patch7: 2435.patch - -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3126 -Patch8: 3126.patch -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3136 -Patch9: 3136.patch -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3163 -Patch10: 3163.patch - -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2826 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3272 -Patch11: 2826.patch -Patch12: 3272.patch - -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2408 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2816 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2847 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3158 -Patch13: 2408.patch -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3353 -Patch14: 3353.patch - -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3845 -Patch15: 3845.patch - -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3720 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4038 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4053 -# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4057 -Patch16: 4038.patch - - -Patch200: glib-change-version.patch - -BuildRequires: chrpath -BuildRequires: gcc -BuildRequires: gcc-c++ -BuildRequires: gettext -BuildRequires: gtk-doc -BuildRequires: perl-interpreter -# for sys/inotify.h -BuildRequires: glibc-devel -BuildRequires: libattr-devel -BuildRequires: libselinux-devel -BuildRequires: meson -# for sys/sdt.h -BuildRequires: systemtap-sdt-devel -BuildRequires: pkgconfig(libelf) -BuildRequires: pkgconfig(libffi) -BuildRequires: pkgconfig(libpcre) -BuildRequires: pkgconfig(mount) -%if %{with sysprof} -BuildRequires: pkgconfig(sysprof-capture-4) -%endif -BuildRequires: pkgconfig(zlib) -BuildRequires: python3-devel - -# 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. -%if 0%{?__isa_bits} == 64 -Requires: libgnutls.so.30()(64bit) -%else -Requires: libgnutls.so.30 -%endif - -# Remove gamin dependency -#Obsoletes: glib2-fam < 2.67.1-3 - -# glib 2.59.0 hash table changes broke older gcr versions / password prompts in gnome-shell -#Conflicts: gcr < 3.28.1 - -Provides: bundled(gnulib) -Provides: bundled(gvdb) -Provides: bundled(libcharset) -Provides: bundled(xdgmime) - -%description -GLib is the low-level core library that forms the basis for projects -such as GTK+ and GNOME. It provides data structure handling for C, -portability wrappers, and interfaces for such runtime functionality -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} - -%description devel -The glib2-devel package includes the header files for the GLib library. - - -%package static -Summary: glib static -Requires: %{name}-devel = %{version}-%{release} - -%description static -The %{name}-static subpackage contains static libraries for %{name}. - - -%prep -%autosetup -n glib-%{version} -p1 - -%build -# Bug 1324770: Also explicitly remove PCRE sources since we use --with-pcre=system -rm glib/pcre/*.[ch] - -export PKG_CONFIG_PATH=%{_libdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}} -export LDFLAGS="-L%{_libdir} -L%{_syslibdir} -Wl,-rpath=%{_libdir} $LDFLAGS" - -%meson \ - -Dman=false \ - -Ddtrace=true \ - -Dsystemtap=true \ -%if %{with sysprof} - -Dsysprof=enabled \ -%endif - -Dglib_debug=disabled \ - -Dgtk_doc=false \ - -Dinstalled_tests=false \ - -Dgnutls=true \ - --default-library=both \ - %{nil} - -%meson_build - -%install -%meson_install -# Since this is a generated .py file, set it to a known timestamp for -# better reproducibility. -# Also copy the timestamp for other .py files, because meson doesn't -# do this, see https://github.com/mesonbuild/meson/issues/5027. -touch -r gio/gdbus-2.0/codegen/config.py.in %{buildroot}%{_datadir}/glib-2.00/codegen/*.py -chrpath --delete %{buildroot}%{_libdir}/*.so - -# Perform byte compilation manually to avoid issues with -# irreproducibility of the default invalidation mode, see -# https://www.python.org/dev/peps/pep-0552/ and -# https://bugzilla.redhat.com/show_bug.cgi?id=1686078 -export PYTHONHASHSEED=0 -%py_byte_compile %{__python3} %{buildroot}%{_datadir} - -mv %{buildroot}%{_bindir}/gio-querymodules %{buildroot}%{_bindir}/gio-querymodules-%{__isa_bits} -sed -i -e "/^gio_querymodules=/s/gio-querymodules/gio-querymodules-%{__isa_bits}/" %{buildroot}%{_libdir}/pkgconfig/gio-2.00.pc - -mkdir -p %{buildroot}%{_libdir}/gio/modules -touch %{buildroot}%{_libdir}/gio/modules/giomodule.cache - -# remove unneeded -rm -fr %{buildroot}%{_bindir} -rm -fr %{buildroot}%{_datadir}/bash-completion - -%find_lang glib200 - -%transfiletriggerin -- %{_libdir}/gio/modules -gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules &> /dev/null || : - -%transfiletriggerpostun -- %{_libdir}/gio/modules -gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules &> /dev/null || : - -%transfiletriggerin -- %{_datadir}/glib-2.00/schemas -glib-compile-schemas %{_datadir}/glib-2.00/schemas &> /dev/null || : - -%transfiletriggerpostun -- %{_datadir}/glib-2.00/schemas -glib-compile-schemas %{_datadir}/glib-2.00/schemas &> /dev/null || : - -%files -f glib200.lang -%license COPYING -%doc AUTHORS NEWS README -%{_libdir}/libglib-2.00.so.* -%{_libdir}/libgthread-2.00.so.* -%{_libdir}/libgmodule-2.00.so.* -%{_libdir}/libgobject-2.00.so.* -%{_libdir}/libgio-2.00.so.* -%dir %{_datadir}/glib-2.00 -%dir %{_datadir}/glib-2.00/schemas -%dir %{_libdir}/gio -%dir %{_libdir}/gio/modules -%ghost %{_libdir}/gio/modules/giomodule.cache - - -%files devel -%{_libdir}/lib*.so -%{_libdir}/glib-2.00 -%{_includedir}/* -%{_datadir}/aclocal/* -%{_libdir}/pkgconfig/* -%{_datadir}/glib-2.00/gdb -%{_datadir}/glib-2.00/gettext -%{_datadir}/glib-2.00/schemas/gschema.dtd -%{_datadir}/glib-2.00/valgrind/glib.supp -%{_datadir}/glib-2.00/codegen -%{_datadir}/gdb/ -%{_datadir}/gettext/ -%{_datadir}/systemtap/ - - -%files static -%{_libdir}/libgio-2.00.a -%{_libdir}/libglib-2.00.a -%{_libdir}/libgmodule-2.00.a -%{_libdir}/libgobject-2.00.a -%{_libdir}/libgthread-2.00.a - - -%changelog -* Mon May 13 2024 Michael Catanzaro - 2.68.4-15 -- Fix CVE-2024-34397, signal subscription vulnerabilities -- Resolves: RHEL-35775 - -* Wed Feb 21 2024 Michael Catanzaro - 2.68.4-14 -- Rebuild against newer util-linux for libmnt changes -- Resolves: RHEL-23637 - -* Thu Feb 01 2024 Michael Catanzaro - 2.68.4-13 -- Backport GUnixMountMonitor port to libmnt_monitor -- Resolves: RHEL-23637 - -* Fri Nov 03 2023 Michael Catanzaro - 2.68.4-12 -- Fix race with waitpid() and child watcher sources -- Resolves: RHEL-14761 - -* Wed Jul 19 2023 Michael Catanzaro - 2.68.4-11 -- Really fix authentication failures when sd-bus clients connect to GDBus servers -- Resolves: #2217771 - -* Thu Jul 06 2023 Michael Catanzaro - 2.68.4-10 -- Fix authentication failures when sd-bus clients connect to GDBus servers -- Resolves: #2217771 - -* Thu May 25 2023 Michael Catanzaro - 2.68.4-9 -- Resolve s390x crashes introduced by fixes for CVE-2023-24593/CVE-2023-25180 -- Related: #2181196 -- Related: #2181200 - -* Wed May 17 2023 Michael Catanzaro - 2.68.4-8 -- Resolve use after free introduced by fixes for CVE-2023-24593/CVE-2023-25180 -- Related: #2181196 -- Related: #2181200 - -* Fri Mar 24 2023 Michael Catanzaro - 2.68.4-7 -- Fix CVE-2023-24593 and CVE-2023-25180 -- Resolves: #2181196 -- Resolves: #2181200 - -* Fri Dec 02 2022 Michael Catanzaro - 2.68.4-6 -- Drop gdesktopappinfo patchset -- Resolves: #2150307 - -* Fri Jan 21 2022 Michael Catanzaro - 2.68.4-5 -- Add one more upstream patch to gspawn patchset -- Related: #1910092 - -* Fri Jan 21 2022 Michael Catanzaro - 2.68.4-4 -- Add gspawn patchset -- Resolves: #1910092 - -* Wed Dec 01 2021 Michael Catanzaro - 2.68.4-3 -- Fix GNetworkMonitor after NetworkManager D-Bus API changes -- Resolves: #2014624 - -* Wed Sep 15 2021 Michael Catanzaro - 2.68.4-2 -- Fix g_get_user_database_entry() crash when used with nss-systemd -- Resolves: #2004711 - -* Sat Aug 21 2021 Kalev Lember - 2.68.4-1 -- Update to 2.68.4 - -* Wed Aug 18 2021 DJ Delorie - 2.68.3-6 -- Rebuilt for libffi 3.4.2 SONAME transition. - Related: rhbz#1891914 - -* Tue Aug 17 2021 Michael Catanzaro - 2.68.3-5 -- Backport GPowerProfileMonitor -- Resolves: #1994466 - -* Mon Aug 09 2021 Mohan Boddu - 2.68.3-4 -- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags - Related: rhbz#1991688 - -* Tue Jul 27 2021 Michael Catanzaro - 2.68.3-3 -- Fix build with glibc 2.34 -- Resolves: #1984626 - -* Thu Jul 01 2021 Michael Catanzaro - 2.68.3-2 -- Refresh gnutls-hmac patchset to fix leaks in error path -- Related: #1971823 - -* Mon Jun 28 2021 Michael Catanzaro - 2.68.3-1 -- Update to 2.68.3 -- Resolves: #1976713 -- Remove Recommends: shared-mime-info -- Resolves: #1947897 - -* Wed Jun 23 2021 Michael Catanzaro - 2.68.2-2 -- Update GHmac patchset and reenable glib2-static -- Resolves: #1971823 - -* Wed May 19 2021 Michael Catanzaro - 2.68.2-1 -- Update to 2.68.2 -- Resolves: #1961039 - -* Tue May 11 2021 Michael Catanzaro - 2.68.1-4 -- No changes, bump revision to retry gating -- Related: #1951126 - -* Fri May 07 2021 Michael Catanzaro - 2.68.1-3 -- Add missing bundled provides -- Add rpminspect gating configuration -- Consolidate GDesktopAppInfo patchset -- Resolves: #1951126 - -* Wed Apr 28 2021 Michael Catanzaro - 2.68.1-2 -- Refresh GDesktopAppInfo patchset -- Related: #1951126 - -* Thu Apr 22 2021 Kalev Lember - 2.68.1-1 -- Update to 2.68.1 - -* Thu Apr 15 2021 Mohan Boddu - 2.68.0-3 -- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 - -* Fri Mar 26 2021 Kalev Lember - 2.68.0-2 -- Rebuild to fix sysprof-capture symbols leaking into libraries consuming it - -* Thu Mar 18 2021 Kalev Lember - 2.68.0-1 -- Update to 2.68.0 - -* Thu Mar 18 2021 Petr Pisar - 2.67.6-2 -- Disable debugging glib (bug #1936339) - -* Thu Mar 11 2021 Kalev Lember - 2.67.6-1 -- Update to 2.67.6 - -* Tue Mar 02 2021 Kalev Lember - 2.67.5-1 -- Update to 2.67.5 - -* Wed Feb 24 2021 Kalev Lember - 2.67.4-3 -- Enable sysprof capture support - -* Fri Feb 19 2021 Kalev Lember - 2.67.4-2 -- Backport a fix for gsubprocesslauncher regression - -* Tue Feb 16 2021 Kalev Lember - 2.67.4-1 -- Update to 2.67.4 - -* Tue Feb 09 2021 Benjamin Berg - 2.67.3-2 -- Add patches to move applications into systemd scopes - -* Thu Feb 04 2021 Kalev Lember - 2.67.3-1 -- Update to 2.67.3 -- Fix gtk-doc directory ownership - -* Tue Jan 26 2021 Fedora Release Engineering - 2.67.1-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Fri Jan 22 2021 Peter Robinson - 2.67.1-3 -- Drop dependency on gamin - -* Sat Dec 19 2020 Kevin Fenzi - 2.67.1-2 -- Add already upstream patch to fix gdm crasher. - -* Sat Dec 19 2020 Kalev Lember - 2.67.1-1 -- Update to 2.67.1 - -* Fri Dec 04 2020 Ondrej Holy - 2.67.0-7 -- Explicitly create modules dir to fix ELN build - -* Tue Dec 01 2020 Ondrej Holy and Michael Catanzaro - 2.67.0-6 -- Disable glib2-fam in RHEL - -* Tue Nov 24 2020 Kalev Lember - 2.67.0-5 -- Backport upstream patches to fix invalid use of volatile objects - (gcc 11 support) - -* Wed Nov 11 2020 Michael Catanzaro - 2.67.0-4 -- Make GnuTLS patch RHEL-specific, and make glib2-static subpackage Fedora-specific - -* Tue Nov 10 2020 Michael Catanzaro - 2.67.0-3 -- Use GnuTLS to implement GHmac (thanks to Colin Walters) - -* Wed Nov 04 2020 Michael Catanzaro - 2.67.0-2 -- Backport fix for GSocketClient crash - -* Thu Oct 29 2020 Kalev Lember - 2.67.0-1 -- Update to 2.67.0 - -* Mon Oct 19 2020 Kalev Lember - 2.66.2-1 -- Update to 2.66.2 -- Drop gtk-doc patch as we finally have a new enough gtk-doc - -* Wed Oct 14 2020 Michael Catanzaro - 2.66.1-3 -- Fix yet another timezone bug - -* Wed Oct 14 2020 Michael Catanzaro - 2.66.1-2 -- Fix timezone-related bugs in many applications caused by new glib timezone cache - -* Thu Oct 1 2020 Kalev Lember - 2.66.1-1 -- Update to 2.66.1 - -* Thu Sep 10 2020 Kalev Lember - 2.66.0-1 -- Update to 2.66.0 - -* Wed Sep 02 2020 Kalev Lember - 2.65.3-1 -- Update to 2.65.3 - -* Tue Aug 25 2020 Adam Williamson - 2.65.2-3 -- Backport fix for GGO #2189 (error accessing some filesystems) - -* Thu Aug 20 2020 Jeff Law - 2.65.2-2 -- Re-enable LTO - -* Tue Aug 18 2020 Kalev Lember - 2.65.2-1 -- Update to 2.65.2 - -* Mon Aug 17 2020 Kalev Lember - 2.65.1-1 -- Update to 2.65.1 - -* Sat Aug 01 2020 Fedora Release Engineering - 2.65.0-5 -- Second attempt - Rebuilt for - https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Mon Jul 27 2020 Fedora Release Engineering - 2.65.0-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Tue Jun 30 2020 Jeff Law - 2.65.0-3 -Disable LTO - -* Mon Jun 22 2020 Kalev Lember - 2.65.0-2 -- Update gio-2.0.pc with correct gio-querymodules name when renaming it - (#1849441) - -* Mon Jun 22 2020 Kalev Lember - 2.65.0-1 -- Update to 2.65.0 - -* Wed May 20 2020 Kalev Lember - 2.64.3-1 -- Update to 2.64.3 - -* Tue Apr 28 2020 Tomas Popela - 2.64.2-2 -- Backport fix for a race condition in GCancellable (rhbz#1825230) - -* Fri Apr 10 2020 Kalev Lember - 2.64.2-1 -- Update to 2.64.2 - -* Wed Mar 11 2020 Kalev Lember - 2.64.1-1 -- Update to 2.64.1 - -* Mon Mar 02 2020 Kalev Lember - 2.64.0-1 -- Update to 2.64.0 - -* Mon Feb 24 2020 Kalev Lember - 2.63.6-1 -- Update to 2.63.6 - -* Wed Feb 12 2020 Kalev Lember - 2.63.5-3 -- Backport a patch to work around SELinux policies not allowing - SYS_sched_setattr (#1795524) - -* Fri Feb 07 2020 Michael Catanzaro - 2.63.5-2 -- Add patch for CVE-2020-6750 and related issues. - -* Mon Feb 03 2020 Kalev Lember - 2.63.5-1 -- Update to 2.63.5 - -* Wed Jan 29 2020 Stephen Gallagher - 2.63.4-3 -- Fix GThreadPool initialization that is breaking createrepo_c (BZ #1795052) - -* Tue Jan 28 2020 Fedora Release Engineering - 2.63.4-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Fri Jan 24 2020 Kalev Lember - 2.63.4-1 -- Update to 2.63.4 - -* Mon Dec 16 2019 Kalev Lember - 2.63.3-1 -- Update to 2.63.3 - -* Mon Dec 02 2019 Kalev Lember - 2.63.2-1 -- Update to 2.63.2 - -* Fri Oct 04 2019 Kalev Lember - 2.63.0-1 -- Update to 2.63.0 - -* Fri Oct 04 2019 Kalev Lember - 2.62.1-1 -- Update to 2.62.1 - -* Fri Sep 06 2019 Kalev Lember - 2.62.0-1 -- Update to 2.62.0 - -* Tue Sep 03 2019 Kalev Lember - 2.61.3-1 -- Update to 2.61.3 - -* Mon Aug 12 2019 Kalev Lember - 2.61.2-1 -- Update to 2.61.2 - -* Thu Jul 25 2019 Fedora Release Engineering - 2.61.1-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Tue Jun 11 2019 David King - 2.61.1-2 -- Fix CVE-2019-12450 (#1719142) -- Consistently use buildroot macro - -* Fri May 24 2019 Kalev Lember - 2.61.1-1 -- Update to 2.61.1 - -* Tue Apr 16 2019 Adam Williamson - 2.61.0-2 -- Rebuild with Meson fix for #1699099 - -* Mon Apr 15 2019 Kalev Lember - 2.61.0-1 -- Update to 2.61.0 - -* Mon Apr 15 2019 Kalev Lember - 2.60.1-1 -- Update to 2.60.1 - -* Wed Mar 13 2019 Zbigniew Jędrzejewski-Szmek - 2.60.0-3 -- Switch back to timestamp-based pyc invalidation mode - -* Wed Mar 6 2019 Zbigniew Jędrzejewski-Szmek - 2.60.0-2 -- Make sure all .py files have fixed timestamps (fixes issue with - parallel installability of i686 and amd64 -devel packages) -- Switch to explicit byte compilation to override invalidation mode - -* Mon Mar 04 2019 Kalev Lember - 2.60.0-1 -- Update to 2.60.0 - -* Mon Feb 18 2019 Kalev Lember - 2.59.3-1 -- Update to 2.59.3 - -* Mon Feb 04 2019 Kalev Lember - 2.59.2-1 -- Update to 2.59.2 - -* Thu Jan 31 2019 Fedora Release Engineering - 2.59.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Sat Jan 26 2019 Kalev Lember - 2.59.1-1 -- Update to 2.59.1 - -* Thu Jan 03 2019 Kalev Lember - 2.59.0-1 -- Update to 2.59.0 -- Switch to the meson build system - -* Tue Dec 18 2018 Kalev Lember - 2.58.2-1 -- Update to 2.58.2 - -* Fri Oct 05 2018 Kalev Lember - 2.58.1-2 -- Fix multilib -devel installs (#1634778) - -* Fri Sep 21 2018 Kalev Lember - 2.58.1-1 -- Update to 2.58.1 - -* Wed Sep 05 2018 Kalev Lember - 2.58.0-1 -- Update to 2.58.0 - -* Thu Aug 2 2018 Ondrej Holy - 2.57.2-1 -- Update to 2.57.2 - -* Fri Jul 20 2018 Ondrej Holy - 2.57.1-1 -- Update to 2.57.1 - -* Fri Jul 13 2018 Fedora Release Engineering - 2.56.1-6 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Tue Jun 19 2018 Miro Hrončok - 2.56.1-5 -- Rebuilt for Python 3.7 - -* Thu Jun 14 2018 Debarshi Ray - 2.56.1-4 -- Backport patch to fix possible invalid pointer in dbus callback in the FD.o - notification backend (RH #1584916) - -* Sun May 27 2018 Kalev Lember - 2.56.1-3 -- Fix multilib -devel installs (#1581067) - -* Sun May 13 2018 Fabio Valentini - 2.56.1-2 -- Include upstream patch to fix gdbus-codegen with meson 0.46. - -* Sun Apr 08 2018 Kalev Lember - 2.56.1-1 -- Update to 2.56.1 - -* Mon Mar 12 2018 Kalev Lember - 2.56.0-1 -- Update to 2.56.0 - -* Wed Feb 07 2018 Igor Gnatenko - 2.55.2-3 -- Undo disabling mangling - -* Wed Feb 07 2018 Kalev Lember - 2.55.2-2 -- Disable brp-mangle-shebangs shebangs - -* Wed Feb 07 2018 Kalev Lember - 2.55.2-1 -- Update to 2.55.2 -- Drop ldconfig scriptlets - -* Wed Jan 31 2018 Igor Gnatenko - 2.55.1-3 -- Switch to %%ldconfig_scriptlets - -* Thu Jan 18 2018 Kalev Lember - 2.55.1-2 -- gmain: Partial revert of recent wakeup changes - -* Mon Jan 08 2018 Kalev Lember - 2.55.1-1 -- Update to 2.55.1 -- Drop upstreamed systemtap multilib fix - -* Tue Dec 19 2017 Kalev Lember - 2.55.0-1 -- Update to 2.55.0 - -* Wed Nov 01 2017 Kalev Lember - 2.54.2-1 -- Update to 2.54.2 - -* Fri Oct 06 2017 Kalev Lember - 2.54.1-1 -- Update to 2.54.1 - -* Mon Sep 11 2017 Kalev Lember - 2.54.0-1 -- Update to 2.54.0 - -* Tue Sep 05 2017 Kalev Lember - 2.53.7-1 -- Update to 2.53.7 - -* Sat Aug 19 2017 Kalev Lember - 2.53.6-1 -- Update to 2.53.6 - -* Mon Aug 07 2017 Igor Gnatenko - 2.53.5-1 -- Update to 2.53.5 - -* Tue Aug 01 2017 Kalev Lember - 2.53.4-4 -- Backport glib-mkenums flags annotation parsing fixes - -* Wed Jul 26 2017 Fedora Release Engineering - 2.53.4-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Fri Jul 21 2017 Kalev Lember - 2.53.4-2 -- Revert a GKeyFile introspection ABI change - -* Tue Jul 18 2017 Kalev Lember - 2.53.4-1 -- Update to 2.53.4 - -* Thu Jun 22 2017 Kalev Lember - 2.53.3-1 -- Update to 2.53.3 - -* Thu Jun 8 2017 Owen Taylor - 2.53.2-2 -- Make triggers also compile schemas in /app/share/glib-2.0/schemas - -* Wed May 24 2017 Florian Müllner - 2.53.2-1 -- Update to 2.53.2 - -* Mon May 15 2017 Kalev Lember - 2.52.2-2 -- Backport a gmain GWakeup patch to fix timedatex high CPU usage (#1450628) - -* Tue May 09 2017 Kalev Lember - 2.52.2-1 -- Update to 2.52.2 - -* Tue Apr 11 2017 Colin Walters - 2.52.1-3 -- Backport patches for gmain wakeup for qemu - See: https://bugzilla.gnome.org/show_bug.cgi?id=761102 - -* Tue Apr 11 2017 Colin Walters - 2.52.1-2 -- Explictly remove PCRE sources -- Related: https://bugzilla.redhat.com/show_bug.cgi?id=1324770 - -* Tue Apr 11 2017 Kalev Lember - 2.52.1-1 -- Update to 2.52.1 - -* Mon Mar 20 2017 Kalev Lember - 2.52.0-1 -- Update to 2.52.0 - -* Thu Mar 16 2017 Kalev Lember - 2.51.5-1 -- Update to 2.51.5 - -* Thu Mar 02 2017 Kalev Lember - 2.51.4-2 -- Remove the dependency on dbus-launch again (#927212) - -* Wed Mar 01 2017 David King - 2.51.4-1 -- Update to 2.51.4 -- Add a Requires on dbus-launch (#927212) -- Use pkgconfig for BuildRequires - -* Tue Feb 14 2017 Richard Hughes - 2.51.2-1 -- Update to 2.51.2 - -* Mon Feb 13 2017 Richard Hughes - 2.51.1-1 -- Update to 2.51.1 - -* Fri Feb 10 2017 Fedora Release Engineering - 2.51.0-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Mon Dec 19 2016 Miro Hrončok - 2.51.0-2 -- Rebuild for Python 3.6 - -* Sun Oct 30 2016 Kalev Lember - 2.51.0-1 -- Update to 2.51.0 - -* Wed Oct 12 2016 Kalev Lember - 2.50.1-1 -- Update to 2.50.1 - -* Mon Sep 19 2016 Kalev Lember - 2.50.0-1 -- Update to 2.50.0 - -* Tue Sep 13 2016 Kalev Lember - 2.49.7-1 -- Update to 2.49.7 -- Don't set group tags - -* Sun Aug 28 2016 Kalev Lember - 2.49.6-1 -- Update to 2.49.6 - -* Thu Aug 18 2016 Kalev Lember - 2.49.5-1 -- Update to 2.49.5 -- Own /usr/share/gdb and /usr/share/systemtap directories - -* Tue Aug 16 2016 Miro Hrončok - 2.49.4-3 -- Use Python 3 for the RPM Python byte compilation - -* Wed Jul 27 2016 Ville Skyttä - 2.49.4-2 -- Switch to Python 3 (#1286284) - -* Thu Jul 21 2016 Kalev Lember - 2.49.4-1 -- Update to 2.49.4 - -* Sun Jul 17 2016 Kalev Lember - 2.49.3-1 -- Update to 2.49.3 - -* Wed Jun 22 2016 Richard Hughes - 2.49.2-1 -- Update to 2.49.2 - -* Wed Jun 01 2016 Yaakov Selkowitz - 2.49.1-2 -- Soften shared-mime-info dependency (#1266118) - -* Fri May 27 2016 Florian Müllner - 2.49.1-1 -- Update to 2.49.1 - -* Tue May 10 2016 Kalev Lember - 2.48.1-1 -- Update to 2.48.1 - -* Wed Apr 06 2016 Colin Walters - 2.48.0-2 -- Explicitly require system pcre, though we happened to default to this now - anyways due to something else pulling PCRE into the buildroot - Closes rhbz#1287266 - -* Tue Mar 22 2016 Kalev Lember - 2.48.0-1 -- Update to 2.48.0 - -* Thu Mar 17 2016 Richard Hughes - 2.47.92-1 -- Update to 2.47.92 - -* Wed Feb 24 2016 Colin Walters - 2.47.6.19.gad2092b-2 -- git snapshot to work around https://bugzilla.gnome.org/show_bug.cgi?id=762637 -- Add --with-python=/usr/bin/python explicitly to hopefully fix a weird - issue I am seeing where librepo fails to build in epel7 with this due to - us requiring /bin/python. - -* Wed Feb 17 2016 Richard Hughes - 2.47.6-1 -- Update to 2.47.6 - -* Wed Feb 03 2016 Fedora Release Engineering - 2.47.5-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Tue Jan 19 2016 David King - 2.47.5-1 -- Update to 2.47.5 - -* Wed Dec 16 2015 Kalev Lember - 2.47.4-1 -- Update to 2.47.4 - -* Wed Nov 25 2015 Kalev Lember - 2.47.3-1 -- Update to 2.47.3 - -* Wed Nov 25 2015 Kalev Lember - 2.47.2-1 -- Update to 2.47.2 - -* Mon Nov 09 2015 Kevin Fenzi - 2.47.1-2 -- Add full path redirect output to null and || : to triggers. - -* Wed Oct 28 2015 Kalev Lember - 2.47.1-1 -- Update to 2.47.1 - -* Mon Oct 19 2015 Kalev Lember - 2.46.1-2 -- Backport an upstream fix for app launching under wayland (#1273146) - -* Wed Oct 14 2015 Kalev Lember - 2.46.1-1 -- Update to 2.46.1 - -* Mon Sep 21 2015 Kalev Lember - 2.46.0-1 -- Update to 2.46.0 - -* Mon Sep 14 2015 Kalev Lember - 2.45.8-1 -- Update to 2.45.8 - -* Tue Sep 01 2015 Kalev Lember - 2.45.7-1 -- Update to 2.45.7 - -* Wed Aug 19 2015 Kalev Lember - 2.45.6-1 -- Update to 2.45.6 - -* Wed Aug 19 2015 Kalev Lember - 2.45.5-1 -- Update to 2.45.5 - -* Fri Aug 14 2015 Matthias Clasen - 2.45.4-2 -- Add file triggers for gio modules and gsettings schemas - -* Tue Jul 21 2015 David King - 2.45.4-1 -- Update to 2.45.4 - -* Wed Jun 24 2015 Kalev Lember - 2.45.3-2 -- Backport a patch to fix notification withdrawing in gnome-software - -* Wed Jun 24 2015 David King - 2.45.3-1 -- Update to 2.45.3 - -* Wed Jun 17 2015 Fedora Release Engineering - 2.45.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Tue May 26 2015 David King - 2.45.2-1 -- Update to 2.45.2 - -* Thu Apr 30 2015 Kalev Lember - 2.45.1-1 -- Update to 2.45.1 - -* Mon Mar 23 2015 Kalev Lember - 2.44.0-1 -- Update to 2.44.0 - -* Tue Mar 17 2015 Kalev Lember - 2.43.92-1 -- Update to 2.43.92 - -* Mon Mar 02 2015 Kalev Lember - 2.43.91-1 -- Update to 2.43.91 - -* Sat Feb 21 2015 Till Maas - 2.43.90-2 -- Rebuilt for Fedora 23 Change - https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code - -* Wed Feb 18 2015 David King - 2.43.90-1 -- Update to 2.43.90 -- Update man pages glob in files section - -* Tue Feb 10 2015 Matthias Clasen - 2.43.4-1 -- Update to 2.43.4 - -* Tue Jan 20 2015 David King - 2.43.3-1 -- Update to 2.43.3 - -* Wed Dec 17 2014 Kalev Lember - 2.43.2-1 -- Update to 2.43.2 - -* Tue Nov 25 2014 Kalev Lember - 2.43.1-1 -- Update to 2.43.1 - -* Thu Oct 30 2014 Florian Müllner - 2.43.0-1 -- Update to 2.43.0 - -* Mon Sep 22 2014 Kalev Lember - 2.42.0-1 -- Update to 2.42.0 - -* Tue Sep 16 2014 Kalev Lember - 2.41.5-1 -- Update to 2.41.5 - -* Thu Sep 4 2014 Matthias Clasen 2.41.4-3 -- Don't remove rpath from gdbus-peer test - it doesn't work without it - -* Thu Sep 04 2014 Bastien Nocera 2.41.4-2 -- Fix banshee getting selected as the default movie player - -* Tue Sep 02 2014 Kalev Lember - 2.41.4-1 -- Update to 2.41.4 - -* Sat Aug 16 2014 Kalev Lember - 2.41.3-1 -- Update to 2.41.3 - -* Sat Aug 16 2014 Fedora Release Engineering - 2.41.2-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild - -* Wed Jul 23 2014 Stef Walter - 2.41.2-2 -- Fix regression with GDBus array encoding rhbz#1122128 - -* Mon Jul 14 2014 Kalev Lember - 2.41.2-1 -- Update to 2.41.2 - -* Sat Jul 12 2014 Tom Callaway - 2.41.1-2 -- fix license handling - -* Tue Jun 24 2014 Richard Hughes - 2.41.1-1 -- Update to 2.41.1 - -* Sat Jun 07 2014 Fedora Release Engineering - 2.41.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild - -* Tue May 27 2014 Kalev Lember - 2.41.0-1 -- Update to 2.41.0 - -* Mon Mar 24 2014 Richard Hughes - 2.40.0-1 -- Update to 2.40.0 - -* Tue Mar 18 2014 Richard Hughes - 2.39.92-1 -- Update to 2.39.92 - -* Tue Mar 04 2014 Richard Hughes - 2.39.91-1 -- Update to 2.39.91 - -* Tue Feb 18 2014 Richard Hughes - 2.39.90-1 -- Update to 2.39.90 - -* Tue Feb 04 2014 Richard Hughes - 2.39.4-1 -- Update to 2.39.4 - -* Tue Jan 14 2014 Richard Hughes - 2.39.3-1 -- Update to 2.39.3 - -* Sun Dec 22 2013 Richard W.M. Jones - 2.39.2-2 -- Re-add static subpackage so that we can build static qemu as - an AArch64 binfmt. - -* Tue Dec 17 2013 Richard Hughes - 2.39.2-1 -- Update to 2.39.2 - -* Mon Dec 09 2013 Richard Hughes - 2.39.1-2 -- Backport a patch from master to stop gnome-settings-daemon crashing. - -* Thu Nov 14 2013 Richard Hughes - 2.39.1-1 -- Update to 2.39.1 - -* Mon Oct 28 2013 Richard Hughes - 2.39.0-1 -- Update to 2.39.0 - -* Tue Sep 24 2013 Kalev Lember - 2.38.0-1 -- Update to 2.38.0 - -* Tue Sep 17 2013 Kalev Lember - 2.37.93-1 -- Update to 2.37.93 - -* Mon Sep 02 2013 Kalev Lember - 2.37.7-1 -- Update to 2.37.7 - -* Wed Aug 21 2013 Debarshi Ray - 2.37.6-1 -- Update to 2.37.6 - -* Sat Aug 03 2013 Petr Pisar - 2.37.5-2 -- Perl 5.18 rebuild - -* Thu Aug 1 2013 Debarshi Ray - 2.37.5-1 -- Update to 2.37.5 - -* Wed Jul 17 2013 Petr Pisar - 2.37.4-2 -- Perl 5.18 rebuild - -* Tue Jul 9 2013 Matthias Clasen - 2.37.4-1 -- Update to 2.37.4 - -* Thu Jun 20 2013 Debarshi Ray - 2.37.2-1 -- Update to 2.37.2 - -* Tue May 28 2013 Matthias Clasen - 2.37.1-1 -- Update to 2.37.1 -- Add a tests subpackage - -* Sat May 04 2013 Kalev Lember - 2.37.0-1 -- Update to 2.37.0 - -* Sat Apr 27 2013 Thorsten Leemhuis - 2.36.1-2 -- Fix pidgin freezes by applying patch from master (#956872) - -* Mon Apr 15 2013 Kalev Lember - 2.36.1-1 -- Update to 2.36.1 - -* Mon Mar 25 2013 Kalev Lember - 2.36.0-1 -- Update to 2.36.0 - -* Tue Mar 19 2013 Matthias Clasen - 2.35.9-1 -- Update to 2.35.9 - -* Thu Feb 21 2013 Kalev Lember - 2.35.8-1 -- Update to 2.35.8 - -* Tue Feb 05 2013 Kalev Lember - 2.35.7-1 -- Update to 2.35.7 - -* Tue Jan 15 2013 Matthias Clasen - 2.35.4-1 -- Update to 2.35.4 - -* Thu Dec 20 2012 Kalev Lember - 2.35.3-1 -- Update to 2.35.3 - -* Sat Nov 24 2012 Kalev Lember - 2.35.2-1 -- Update to 2.35.2 - -* Thu Nov 08 2012 Kalev Lember - 2.35.1-1 -- Update to 2.35.1 -- Drop upstreamed codegen-in-datadir.patch diff --git a/base/rx-glib2/gnutls-hmac.patch b/base/rx-glib2/gnutls-hmac.patch deleted file mode 100644 index 4b1ba0e..0000000 --- a/base/rx-glib2/gnutls-hmac.patch +++ /dev/null @@ -1,1086 +0,0 @@ -From ff90bb8474b1e724727f4014b446e7c851e609bd 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 49fd272f0..4f181f21f 100644 ---- a/glib/ghmac.c -+++ b/glib/ghmac.c -@@ -329,115 +329,3 @@ g_hmac_get_digest (GHmac *hmac, - g_checksum_update (hmac->digesto, buffer, len); - 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 8c18e6de4..329b8d197 100644 ---- a/glib/meson.build -+++ b/glib/meson.build -@@ -253,6 +253,7 @@ glib_sources = files( - 'ggettext.c', - 'ghash.c', - 'ghmac.c', -+ 'ghmac-utils.c', - 'ghook.c', - 'ghostutils.c', - 'giochannel.c', --- -2.31.1 - -From 5395d36e6685e0b7377794c59c5820970bb472ef 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 | 7 +- - 7 files changed, 260 insertions(+), 7 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 29b479bc6..929958c3a 100644 ---- a/glib/gchecksum.c -+++ b/glib/gchecksum.c -@@ -20,7 +20,7 @@ - - #include - --#include "gchecksum.h" -+#include "gchecksumprivate.h" - - #include "gslice.h" - #include "gmem.h" -@@ -173,9 +173,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; -@@ -194,6 +194,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 4f181f21f..0e39ea40a 100644 ---- a/glib/ghmac.c -+++ b/glib/ghmac.c -@@ -33,6 +33,9 @@ - #include "gtypes.h" - #include "glibintl.h" - -+#ifdef HAVE_GNUTLS -+#error "build configuration error" -+#endif - - /** - * SECTION:hmac -@@ -84,6 +87,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 329b8d197..2417de53d 100644 ---- a/glib/meson.build -+++ b/glib/meson.build -@@ -252,7 +252,6 @@ glib_sources = files( - 'gfileutils.c', - 'ggettext.c', - 'ghash.c', -- 'ghmac.c', - 'ghmac-utils.c', - 'ghook.c', - 'ghostutils.c', -@@ -308,6 +307,7 @@ glib_sources = files( - 'guriprivate.h', - 'gutils.c', - 'gutilsprivate.h', -+ 'gchecksumprivate.h', - 'guuid.c', - 'gvariant.c', - 'gvariant-core.c', -@@ -352,6 +352,12 @@ else - glib_dtrace_hdr = [] - endif - -+if get_option('gnutls') -+ glib_sources += files('ghmac-gnutls.c') -+else -+ glib_sources += files('ghmac.c') -+endif -+ - pcre_static_args = [] - - if use_pcre_static_flag -@@ -378,7 +384,7 @@ libglib = library('glib-2.0', - # intl.lib is not compatible with SAFESEH - link_args : [noseh_link_args, glib_link_flags, win32_ldflags], - include_directories : configinc, -- dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep], -+ dependencies : pcre_deps + [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 e2eba1871..cca15f653 100644 ---- a/meson.build -+++ b/meson.build -@@ -2090,6 +2090,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') - endif -diff --git a/meson_options.txt b/meson_options.txt -index 072765361..c8f26ac02 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -39,6 +39,11 @@ option('internal_pcre', - value : false, - description : 'whether to use internal PCRE') - -+option('gnutls', -+ type : 'boolean', -+ value : false, -+ description : 'build with gnutls support') -+ - option('man', - type : 'boolean', - value : false, --- -2.31.1 - -From 61c175277acb8d1e080305acd444201c5ad1fb81 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 0e39ea40a..2d9be91b8 100644 ---- a/glib/ghmac.c -+++ b/glib/ghmac.c -@@ -33,7 +33,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 2417de53d..ba42951aa 100644 ---- a/glib/meson.build -+++ b/glib/meson.build -@@ -384,7 +384,7 @@ libglib = library('glib-2.0', - # intl.lib is not compatible with SAFESEH - link_args : [noseh_link_args, glib_link_flags, win32_ldflags], - include_directories : configinc, -- dependencies : pcre_deps + [thread_dep, librt] + libgnutls_dep + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep], -+ dependencies : pcre_deps + [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 cca15f653..404ef1790 100644 ---- a/meson.build -+++ b/meson.build -@@ -2090,11 +2090,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.31.1 - -From 7d1d96311b6ecd4f90ebbdd6fc58d28e06a86887 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, "abc123", sizeof ("abc123")); -+ g_assert_null (hmac); -+ -+ /* SHA-256 should be good. */ -+ hmac = g_hmac_new (G_CHECKSUM_SHA256, "abc123", sizeof ("abc123")); -+ g_assert_nonnull (hmac); -+ -+ /* Ensure g_hmac_update() does not crash when called with -1. */ -+ g_hmac_update (hmac, "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.31.1 diff --git a/extras/qemu/0001-sgx-stub-fix.patch b/extras/qemu/0001-sgx-stub-fix.patch deleted file mode 100644 index ff31973..0000000 --- a/extras/qemu/0001-sgx-stub-fix.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 509b6078631ad2437e1a452f749831e401fb8afb Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 1 Feb 2022 20:09:37 +0100 -Subject: [PATCH] target/i386: the sgx_epc_get_section stub is reachable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The sgx_epc_get_section stub is reachable from cpu_x86_cpuid. It -should not assert, instead it should just return true just like -the "real" sgx_epc_get_section does when SGX is disabled. - -Reported-by: Vladimír Beneš -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini - -diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c -index 26833eb233..16b1dfd90b 100644 ---- a/hw/i386/sgx-stub.c -+++ b/hw/i386/sgx-stub.c -@@ -34,5 +34,5 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms) - - bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size) - { -- g_assert_not_reached(); -+ return true; - } diff --git a/extras/qemu/0004-Initial-redhat-build.patch b/extras/qemu/0004-Initial-redhat-build.patch deleted file mode 100644 index 94cf91c..0000000 --- a/extras/qemu/0004-Initial-redhat-build.patch +++ /dev/null @@ -1,313 +0,0 @@ -From fc113ecd7c99646a7ced0b99570b5927ae6d595f Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Wed, 26 May 2021 10:56:02 +0200 -Subject: Initial redhat build - -This patch introduces redhat build structure in redhat subdirectory. In addition, -several issues are fixed in QEMU tree: - -- Change of app name for sasl_server_init in VNC code from qemu to qemu-kvm - - As we use qemu-kvm as name in all places, this is updated to be consistent -- Man page renamed from qemu to qemu-kvm - - man page is installed using make install so we have to fix it in qemu tree - -We disable make check due to issues with some of the tests. - -This rebase is based on qemu-kvm-6.2.0-13.el9 - -Signed-off-by: Miroslav Rezanina --- -Rebase changes (6.1.0): -- Move build to .distro -- Move changes for support file to related commit -- Added dependency for python3-sphinx-rtd_theme -- Removed --disable-sheepdog configure option -- Added new hw-display modules -- SASL initialization moved to ui/vnc-auth-sasl.c -- Add accel-qtest- and accel-tcg-x86_64 libraries -- Added hw-usb-host module -- Disable new configure options (bpf, nvmm, slirp-smbd) -- Use -pie for ksmctl build (annocheck complain fix) - -Rebase changes (6.2.0): -- removed --disable-jemalloc and --disable-tcmalloc configure options -- added audio-oss.so -- added fdt requirement for x86_64 -- tests/acceptance renamed to tests/avocado -- added multiboot_dma.bin -- Add -Wno-string-plus-int to extra flags -- Updated configure options - -Rebase changes (7.0.0): -- Do not use -mlittle CFLAG on ppc64le -- Used upstream handling issue with ui/clipboard.c -- Use -mlittle-endian on ppc64le instead of deleteing it in configure -- Drop --disable-libxml2 option for configure (upstream) -- Remove vof roms -- Disable AVX2 support -- Use internal meson -- Disable new configure options (dbus-display and qga-vss) -- Change permissions on installing tests/Makefile.include -- Remove ssh block driver - -Merged patches (6.0.0): - - 605758c902 Limit build on Power to qemu-img and qemu-ga only - -Merged patches (6.1.0): -- f04f91751f Use cached tarballs -- 6581165c65 Remove message with running VM count -- 03c3cac9fc spec-file: build qemu-kvm without SPICE and QXL -- e0ae6c1f6c spec-file: Obsolete qemu-kvm-ui-spice -- 9d2e9f9ecf spec: Do not build qemu-kvm-block-gluster -- cf470b4234 spec: Do not link pcnet and ne2k_pci roms -- e981284a6b redhat: Install the s390-netboot.img that we've built -- 24ef557f33 spec: Remove usage of Group: tag -- c40d69b4f4 spec: Drop %defattr usage -- f8e98798ce spec: Clean up BuildRequires -- 47246b43ee spec: Remove iasl BuildRequires -- 170dc1cbe0 spec: Remove redundant 0 in conditionals -- 8718f6fa11 spec: Add more have_XXX conditionals -- a001269ce9 spec: Remove binutils versioned Requires -- 34545ee641 spec: Remove diffutils BuildRequires -- c2c82beac9 spec: Remove redundant Requires: -- 9314c231f4 spec: Add XXX_version macros -- c43db0bf0f spec: Add have_block_rbd -- 3ecb0c0319 qga: drop StandardError=syslog -- 018049dc80 Remove iscsi support -- a2edf18777 redhat: Replace the kvm-setup.service with a /etc/modules-load.d config file -- 387b5fbcfe redhat: Move qemu-kvm-docs dependency to qemu-kvm -- 4ead693178 redhat: introducting qemu-kvm-hw-usbredir -- 4dc6fc3035 redhat: use the standard vhost-user JSON path -- 84757178b4 Fix local build -- 8c394227dd spec: Restrict block drivers in tools -- b6aa7c1fae Move tools to separate package -- eafd82e509 Split qemu-pr-helper to separate package -- 2c0182e2aa spec: RPM_BUILD_ROOT -> %{buildroot} -- 91bd55ca13 spec: More use of %{name} instead of 'qemu-kvm' -- 50ba299c61 spec: Use qemu-pr-helper.service from qemu.git (partial) -- ee08d4e0a3 spec: Use %{_sourcedir} for referencing sources -- 039e7f7d02 spec: Add tools_only -- 884ba71617 spec: %build: Add run_configure helper -- 8ebd864d65 spec: %build: Disable more bits with %{disable_everything} (partial) -- f23fdb53f5 spec: %build: Add macros for some 'configure' parameters -- fe951a8bd8 spec: %files: Move qemu-guest-agent and qemu-img earlier -- 353b632e37 spec: %install: Remove redundant bits -- 9d2015b752 spec: %install: Add %{modprobe_kvm_conf} macro -- 6d05134e8c spec: %install: Remove qemu-guest-agent /etc/qemu-kvm usage -- 985b226467 spec: %install: clean up qemu-ga section -- dfaf9c600d spec: %install: Use a single %{tools_only} section -- f6978ddb46 spec: Make tools_only not cross spec sections -- 071c211098 spec: %install: Limit time spent in %{qemu_kvm_build} -- 1b65c674be spec: misc syntactic merges with Fedora -- 4da16294cf spec: Use Fedora's pattern for specifying rc version -- d7ee259a79 spec: %files: don't use fine grained -docs file list -- 64cad0c60f spec: %files: Add licenses to qemu-common too -- c3de4f080a spec: %install: Drop python3 shebang fixup -- 46fc216115 Update local build to work with spec file improvements -- bab9531548 spec: Remove buildldflags -- c8360ab6a9 spec: Use %make_build macro -- f6966c66e9 spec: Drop make install sharedir and datadir usage -- 86982421bc spec: use %make_install macro -- 191c405d22 spec: parallelize `make check` -- 251a1fb958 spec: Drop explicit --build-id -- 44c7dda6c3 spec: use %{build_ldflags} -- 0009a34354 Move virtiofsd to separate package -- 34d1b200b3 Utilize --firmware configure option -- 2800e1dd03 spec: Switch toolchain to Clang/LLVM (except process-patches.sh) -- e8a70f500f spec: Use safe-stack for x86_64 -- e29445d50d spec: Reenable write support for VMDK etc. in tools -- a4fe2a3e16 redhat: Disable LTO on non-x86 architectures - -Merged patches (6.2.0): -- 333452440b remove sgabios dependency -- 7d3633f184 enable pulseaudio -- bd898709b0 spec: disable use of gcrypt for crypto backends in favour of gnutls -- e4f0c6dee6 spec: Remove block-curl and block-ssh dependency -- 4dc13bfe63 spec: Build the VDI block driver -- d2f2ff3c74 spec: Explicitly include compress filter -- a7d047f9c2 Move ksmtuned files to separate package - -Merged patches (7.0.0): -- 098d4d08d0 spec: Rename qemu-kvm-hw-usbredir to qemu-kvm-device-usb-redirect -- c2bd0d6834 spec: Split qemu-kvm-ui-opengl -- 2c9cda805d spec: Introduce packages for virtio-gpu-* modules (changed as rhel device tree not set) -- d0414a3e0b spec: Introduce device-display-virtio-vga* packages -- 3534ec46d4 spec: Move usb-host module to separate package -- ddc14d4737 spec: Move qtest accel module to tests package -- 6f2c4befa6 spec: Extend qemu-kvm-core description -- 6f11866e4e (rhel/rhel-9.0.0) Update to qemu-kvm-6.2.0-6.el9 -- da0a28758f ui/clipboard: fix use-after-free regression -- 895d4d52eb spec: Remove qemu-virtiofsd -- c8c8c8bd84 spec: Fix obsolete for spice subpackages -- d46d2710b2 spec: Obsolete old usb redir subpackage -- 6f52a50b68 spec: Obsolete ssh driver - -Signed-off-by: Miroslav Rezanina ---- - .distro/85-kvm.preset | 5 - - .distro/Makefile | 100 + - .distro/Makefile.common | 40 + - .distro/README.tests | 39 + - .distro/ksm.service | 13 - - .distro/ksm.sysconfig | 4 - - .distro/ksmctl.c | 77 - - .distro/ksmtuned | 139 - - .distro/ksmtuned.conf | 21 - - .distro/ksmtuned.service | 12 - - .distro/kvm-setup | 49 - - .distro/kvm-setup.service | 14 - - .distro/modules-load.conf | 4 + - .distro/qemu-guest-agent.service | 1 - - .distro/qemu-kvm.spec.template | 4034 +++++++++++++++++++++++ - .distro/rpminspect.yaml | 6 +- - .distro/scripts/extract_build_cmd.py | 12 + - .gitignore | 1 + - README.systemtap | 43 + - meson.build | 4 +- - scripts/qemu-guest-agent/fsfreeze-hook | 2 +- - scripts/systemtap/conf.d/qemu_kvm.conf | 4 + - scripts/systemtap/script.d/qemu_kvm.stp | 1 + - tests/check-block.sh | 2 + - ui/vnc-auth-sasl.c | 2 +- - 25 files changed, 4290 insertions(+), 339 deletions(-) - delete mode 100644 .distro/85-kvm.preset - create mode 100644 .distro/Makefile - create mode 100644 .distro/Makefile.common - create mode 100644 .distro/README.tests - delete mode 100644 .distro/ksm.service - delete mode 100644 .distro/ksm.sysconfig - delete mode 100644 .distro/ksmctl.c - delete mode 100644 .distro/ksmtuned - delete mode 100644 .distro/ksmtuned.conf - delete mode 100644 .distro/ksmtuned.service - delete mode 100644 .distro/kvm-setup - delete mode 100644 .distro/kvm-setup.service - create mode 100644 .distro/modules-load.conf - create mode 100644 .distro/qemu-kvm.spec.template - create mode 100644 README.systemtap - create mode 100644 scripts/systemtap/conf.d/qemu_kvm.conf - create mode 100644 scripts/systemtap/script.d/qemu_kvm.stp - -diff --git a/README.systemtap b/README.systemtap -new file mode 100644 -index 0000000000..ad913fc990 ---- /dev/null -+++ b/README.systemtap -@@ -0,0 +1,43 @@ -+QEMU tracing using systemtap-initscript -+--------------------------------------- -+ -+You can capture QEMU trace data all the time using systemtap-initscript. This -+uses SystemTap's flight recorder mode to trace all running guests to a -+fixed-size buffer on the host. Old trace entries are overwritten by new -+entries when the buffer size wraps. -+ -+1. Install the systemtap-initscript package: -+ # yum install systemtap-initscript -+ -+2. Install the systemtap scripts and the conf file: -+ # cp /usr/share/qemu-kvm/systemtap/script.d/qemu_kvm.stp /etc/systemtap/script.d/ -+ # cp /usr/share/qemu-kvm/systemtap/conf.d/qemu_kvm.conf /etc/systemtap/conf.d/ -+ -+The set of trace events to enable is given in qemu_kvm.stp. This SystemTap -+script can be customized to add or remove trace events provided in -+/usr/share/systemtap/tapset/qemu-kvm-simpletrace.stp. -+ -+SystemTap customizations can be made to qemu_kvm.conf to control the flight -+recorder buffer size and whether to store traces in memory only or disk too. -+See stap(1) for option documentation. -+ -+3. Start the systemtap service. -+ # service systemtap start qemu_kvm -+ -+4. Make the service start at boot time. -+ # chkconfig systemtap on -+ -+5. Confirm that the service works. -+ # service systemtap status qemu_kvm -+ qemu_kvm is running... -+ -+When you want to inspect the trace buffer, perform the following steps: -+ -+1. Dump the trace buffer. -+ # staprun -A qemu_kvm >/tmp/trace.log -+ -+2. Start the systemtap service because the preceding step stops the service. -+ # service systemtap start qemu_kvm -+ -+3. Translate the trace record to readable format. -+ # /usr/share/qemu-kvm/simpletrace.py --no-header /usr/share/qemu-kvm/trace-events /tmp/trace.log -diff --git a/meson.build b/meson.build -index 861de93c4f..6f7e430f0f 100644 ---- a/meson.build -+++ b/meson.build -@@ -2394,7 +2394,9 @@ if capstone_opt == 'internal' - # Include all configuration defines via a header file, which will wind up - # as a dependency on the object file, and thus changes here will result - # in a rebuild. -- '-include', 'capstone-defs.h' -+ '-include', 'capstone-defs.h', -+ -+ '-Wp,-D_GLIBCXX_ASSERTIONS', - ] - - libcapstone = static_library('capstone', -diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook -index 13aafd4845..e9b84ec028 100755 ---- a/scripts/qemu-guest-agent/fsfreeze-hook -+++ b/scripts/qemu-guest-agent/fsfreeze-hook -@@ -8,7 +8,7 @@ - # request, it is issued with "thaw" argument after filesystem is thawed. - - LOGFILE=/var/log/qga-fsfreeze-hook.log --FSFREEZE_D=$(dirname -- "$0")/fsfreeze-hook.d -+FSFREEZE_D=$(dirname -- "$(realpath $0)")/fsfreeze-hook.d - - # Check whether file $1 is a backup or rpm-generated file and should be ignored - is_ignored_file() { -diff --git a/scripts/systemtap/conf.d/qemu_kvm.conf b/scripts/systemtap/conf.d/qemu_kvm.conf -new file mode 100644 -index 0000000000..372d8160a4 ---- /dev/null -+++ b/scripts/systemtap/conf.d/qemu_kvm.conf -@@ -0,0 +1,4 @@ -+# Force load uprobes (see BZ#1118352) -+stap -e 'probe process("/usr/libexec/qemu-kvm").function("main") { printf("") }' -c true -+ -+qemu_kvm_OPT="-s4" # per-CPU buffer size, in megabytes -diff --git a/scripts/systemtap/script.d/qemu_kvm.stp b/scripts/systemtap/script.d/qemu_kvm.stp -new file mode 100644 -index 0000000000..c04abf9449 ---- /dev/null -+++ b/scripts/systemtap/script.d/qemu_kvm.stp -@@ -0,0 +1 @@ -+probe qemu.kvm.simpletrace.handle_qmp_command,qemu.kvm.simpletrace.monitor_protocol_*,qemu.kvm.simpletrace.migrate_set_state {} -diff --git a/tests/check-block.sh b/tests/check-block.sh -index f59496396c..d900d8b35e 100755 ---- a/tests/check-block.sh -+++ b/tests/check-block.sh -@@ -48,6 +48,8 @@ if LANG=C bash --version | grep -q 'GNU bash, version [123]' ; then - skip "bash version too old ==> Not running the qemu-iotests." - fi - -+exit 0 -+ - cd tests/qemu-iotests - - # QEMU_CHECK_BLOCK_AUTO is used to disable some unstable sub-tests -diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c -index 47fdae5b21..2a950caa2a 100644 ---- a/ui/vnc-auth-sasl.c -+++ b/ui/vnc-auth-sasl.c -@@ -42,7 +42,7 @@ - - bool vnc_sasl_server_init(Error **errp) - { -- int saslErr = sasl_server_init(NULL, "qemu"); -+ int saslErr = sasl_server_init(NULL, "qemu-kvm"); - - if (saslErr != SASL_OK) { - error_setg(errp, "Failed to initialize SASL auth: %s", --- -2.31.1 - diff --git a/extras/qemu/0005-Enable-disable-devices-for-RHEL.patch b/extras/qemu/0005-Enable-disable-devices-for-RHEL.patch deleted file mode 100644 index 48c25c2..0000000 --- a/extras/qemu/0005-Enable-disable-devices-for-RHEL.patch +++ /dev/null @@ -1,629 +0,0 @@ -From 51ec7495d69fe4b4d0b61642ca6c0e7fd7a1032d Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 15 Jul 2021 03:22:36 -0400 -Subject: Enable/disable devices for RHEL - -This commit adds all changes related to changes in supported devices. - -Signed-off-by: Miroslav Rezanina --- -Rebase notes (6.1.0): -- Added CONFIG_TPM (except s390x) -- default-configs moved to configs -- Use --with-device- configure option to use rhel configs - -Rebase notes (6.2.0): -- Add CONFIG_ISA_FDC -- Do not remove -no-hpet documentation - -Rebase notes (7.0.0): -- Added CONFIG_ARM_GIC_TCG option for aarch64 -- Fixes necessary for layout change fixes -- Renamed CONFIG_ARM_GIC_TCG to CONFIG_ARM_GICV3_TCG -- Removed upstream devices - -Merged patches (6.1.0): -- c51bf45304 Remove SPICE and QXL from x86_64-rh-devices.mak -- 02fc745601 aarch64-rh-devices: add CONFIG_PVPANIC_PCI -- f2fe835153 aarch64-rh-devices: add CONFIG_PXB -- b5431733ad disable CONFIG_USB_STORAGE_BOT -- 478ba0cdf6 Disable TPM passthrough -- 2504d68a7c aarch64: Add USB storage devices -- 51c2a3253c disable ac97 audio - -Merged patches (6.2.0): -- 9f2f9fa2ba disable sga device - -Merged patches (7.0.0): -- fd7c45a5a8 redhat: Enable virtio-mem as tech-preview on x86-64 -- c9e68ea451 Enable SGX -- RH Only ---- - .distro/qemu-kvm.spec.template | 18 +-- - .../aarch64-softmmu/aarch64-rh-devices.mak | 34 ++++++ - .../ppc64-softmmu/ppc64-rh-devices.mak | 35 ++++++ - configs/devices/rh-virtio.mak | 10 ++ - .../s390x-softmmu/s390x-rh-devices.mak | 15 +++ - .../x86_64-softmmu/x86_64-rh-devices.mak | 103 ++++++++++++++++++ - hw/acpi/ich9.c | 4 +- - hw/arm/meson.build | 2 +- - hw/block/fdc.c | 10 ++ - hw/cpu/meson.build | 5 +- - hw/display/cirrus_vga.c | 5 +- - hw/ide/piix.c | 5 +- - hw/input/pckbd.c | 2 + - hw/net/e1000.c | 2 + - hw/ppc/spapr_cpu_core.c | 2 + - hw/usb/meson.build | 2 +- - target/arm/cpu_tcg.c | 10 ++ - target/ppc/cpu-models.c | 9 ++ - target/s390x/cpu_models_sysemu.c | 3 + - target/s390x/kvm/kvm.c | 8 ++ - 20 files changed, 269 insertions(+), 15 deletions(-) - create mode 100644 configs/devices/aarch64-softmmu/aarch64-rh-devices.mak - create mode 100644 configs/devices/ppc64-softmmu/ppc64-rh-devices.mak - create mode 100644 configs/devices/rh-virtio.mak - create mode 100644 configs/devices/s390x-softmmu/s390x-rh-devices.mak - create mode 100644 configs/devices/x86_64-softmmu/x86_64-rh-devices.mak - -diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak -new file mode 100644 -index 0000000000..5f6ee1de5b ---- /dev/null -+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak -@@ -0,0 +1,34 @@ -+include ../rh-virtio.mak -+ -+CONFIG_ARM_GIC_KVM=y -+CONFIG_ARM_GICV3_TCG=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_SMMUV3=y -+CONFIG_ARM_V7M=y -+CONFIG_ARM_VIRT=y -+CONFIG_EDID=y -+CONFIG_PCIE_PORT=y -+CONFIG_PCI_DEVICES=y -+CONFIG_PCI_TESTDEV=y -+CONFIG_PFLASH_CFI01=y -+CONFIG_SCSI=y -+CONFIG_SEMIHOSTING=y -+CONFIG_USB=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_PCI=y -+CONFIG_USB_STORAGE_CORE=y -+CONFIG_USB_STORAGE_CLASSIC=y -+CONFIG_VFIO=y -+CONFIG_VFIO_PCI=y -+CONFIG_VIRTIO_MMIO=y -+CONFIG_VIRTIO_PCI=y -+CONFIG_XIO3130=y -+CONFIG_NVDIMM=y -+CONFIG_ACPI_APEI=y -+CONFIG_TPM=y -+CONFIG_TPM_EMULATOR=y -+CONFIG_TPM_TIS_SYSBUS=y -+CONFIG_PTIMER=y -+CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y -+CONFIG_PVPANIC_PCI=y -+CONFIG_PXB=y -diff --git a/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak -new file mode 100644 -index 0000000000..6a3e3f0227 ---- /dev/null -+++ b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak -@@ -0,0 +1,35 @@ -+include ../rh-virtio.mak -+ -+CONFIG_DIMM=y -+CONFIG_MEM_DEVICE=y -+CONFIG_NVDIMM=y -+CONFIG_PCI=y -+CONFIG_PCI_DEVICES=y -+CONFIG_PCI_TESTDEV=y -+CONFIG_PCI_EXPRESS=y -+CONFIG_PSERIES=y -+CONFIG_SCSI=y -+CONFIG_SPAPR_VSCSI=y -+CONFIG_TEST_DEVICES=y -+CONFIG_USB=y -+CONFIG_USB_OHCI=y -+CONFIG_USB_OHCI_PCI=y -+CONFIG_USB_SMARTCARD=y -+CONFIG_USB_STORAGE_CORE=y -+CONFIG_USB_STORAGE_CLASSIC=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_NEC=y -+CONFIG_USB_XHCI_PCI=y -+CONFIG_VFIO=y -+CONFIG_VFIO_PCI=y -+CONFIG_VGA=y -+CONFIG_VGA_PCI=y -+CONFIG_VHOST_USER=y -+CONFIG_VIRTIO_PCI=y -+CONFIG_VIRTIO_VGA=y -+CONFIG_WDT_IB6300ESB=y -+CONFIG_XICS=y -+CONFIG_XIVE=y -+CONFIG_TPM=y -+CONFIG_TPM_SPAPR=y -+CONFIG_TPM_EMULATOR=y -diff --git a/configs/devices/rh-virtio.mak b/configs/devices/rh-virtio.mak -new file mode 100644 -index 0000000000..94ede1b5f6 ---- /dev/null -+++ b/configs/devices/rh-virtio.mak -@@ -0,0 +1,10 @@ -+CONFIG_VIRTIO=y -+CONFIG_VIRTIO_BALLOON=y -+CONFIG_VIRTIO_BLK=y -+CONFIG_VIRTIO_GPU=y -+CONFIG_VIRTIO_INPUT=y -+CONFIG_VIRTIO_INPUT_HOST=y -+CONFIG_VIRTIO_NET=y -+CONFIG_VIRTIO_RNG=y -+CONFIG_VIRTIO_SCSI=y -+CONFIG_VIRTIO_SERIAL=y -diff --git a/configs/devices/s390x-softmmu/s390x-rh-devices.mak b/configs/devices/s390x-softmmu/s390x-rh-devices.mak -new file mode 100644 -index 0000000000..d3b38312e1 ---- /dev/null -+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak -@@ -0,0 +1,15 @@ -+include ../rh-virtio.mak -+ -+CONFIG_PCI=y -+CONFIG_S390_CCW_VIRTIO=y -+CONFIG_S390_FLIC=y -+CONFIG_S390_FLIC_KVM=y -+CONFIG_SCLPCONSOLE=y -+CONFIG_SCSI=y -+CONFIG_VFIO=y -+CONFIG_VFIO_AP=y -+CONFIG_VFIO_CCW=y -+CONFIG_VFIO_PCI=y -+CONFIG_VHOST_USER=y -+CONFIG_VIRTIO_CCW=y -+CONFIG_WDT_DIAG288=y -diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -new file mode 100644 -index 0000000000..d0c9e66641 ---- /dev/null -+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -@@ -0,0 +1,103 @@ -+include ../rh-virtio.mak -+ -+CONFIG_ACPI=y -+CONFIG_ACPI_PCI=y -+CONFIG_ACPI_CPU_HOTPLUG=y -+CONFIG_ACPI_MEMORY_HOTPLUG=y -+CONFIG_ACPI_NVDIMM=y -+CONFIG_ACPI_SMBUS=y -+CONFIG_ACPI_VMGENID=y -+CONFIG_ACPI_X86=y -+CONFIG_ACPI_X86_ICH=y -+CONFIG_AHCI=y -+CONFIG_APIC=y -+CONFIG_APM=y -+CONFIG_BOCHS_DISPLAY=y -+CONFIG_DIMM=y -+CONFIG_E1000E_PCI_EXPRESS=y -+CONFIG_E1000_PCI=y -+CONFIG_EDU=y -+CONFIG_FDC=y -+CONFIG_FDC_SYSBUS=y -+CONFIG_FDC_ISA=y -+CONFIG_FW_CFG_DMA=y -+CONFIG_HDA=y -+CONFIG_HYPERV=y -+CONFIG_HYPERV_TESTDEV=y -+CONFIG_I2C=y -+CONFIG_I440FX=y -+CONFIG_I8254=y -+CONFIG_I8257=y -+CONFIG_I8259=y -+CONFIG_I82801B11=y -+CONFIG_IDE_CORE=y -+CONFIG_IDE_PCI=y -+CONFIG_IDE_PIIX=y -+CONFIG_IDE_QDEV=y -+CONFIG_IOAPIC=y -+CONFIG_IOH3420=y -+CONFIG_ISA_BUS=y -+CONFIG_ISA_DEBUG=y -+CONFIG_ISA_TESTDEV=y -+CONFIG_LPC_ICH9=y -+CONFIG_MC146818RTC=y -+CONFIG_MEM_DEVICE=y -+CONFIG_NVDIMM=y -+CONFIG_OPENGL=y -+CONFIG_PAM=y -+CONFIG_PC=y -+CONFIG_PCI=y -+CONFIG_PCIE_PORT=y -+CONFIG_PCI_DEVICES=y -+CONFIG_PCI_EXPRESS=y -+CONFIG_PCI_EXPRESS_Q35=y -+CONFIG_PCI_I440FX=y -+CONFIG_PCI_TESTDEV=y -+CONFIG_PCKBD=y -+CONFIG_PCSPK=y -+CONFIG_PC_ACPI=y -+CONFIG_PC_PCI=y -+CONFIG_PFLASH_CFI01=y -+CONFIG_PVPANIC_ISA=y -+CONFIG_PXB=y -+CONFIG_Q35=y -+CONFIG_RTL8139_PCI=y -+CONFIG_SCSI=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_SERIAL_PCI=y -+CONFIG_SEV=y -+CONFIG_SMBIOS=y -+CONFIG_SMBUS_EEPROM=y -+CONFIG_TEST_DEVICES=y -+CONFIG_USB=y -+CONFIG_USB_EHCI=y -+CONFIG_USB_EHCI_PCI=y -+CONFIG_USB_SMARTCARD=y -+CONFIG_USB_STORAGE_CORE=y -+CONFIG_USB_STORAGE_CLASSIC=y -+CONFIG_USB_UHCI=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_NEC=y -+CONFIG_USB_XHCI_PCI=y -+CONFIG_VFIO=y -+CONFIG_VFIO_PCI=y -+CONFIG_VGA=y -+CONFIG_VGA_CIRRUS=y -+CONFIG_VGA_PCI=y -+CONFIG_VHOST_USER=y -+CONFIG_VHOST_USER_BLK=y -+CONFIG_VIRTIO_MEM=y -+CONFIG_VIRTIO_PCI=y -+CONFIG_VIRTIO_VGA=y -+CONFIG_VMMOUSE=y -+CONFIG_VMPORT=y -+CONFIG_VTD=y -+CONFIG_WDT_IB6300ESB=y -+CONFIG_WDT_IB700=y -+CONFIG_XIO3130=y -+CONFIG_TPM=y -+CONFIG_TPM_CRB=y -+CONFIG_TPM_TIS_ISA=y -+CONFIG_TPM_EMULATOR=y -+CONFIG_SGX=y -diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c -index bd9bbade70..de1e401cdf 100644 ---- a/hw/acpi/ich9.c -+++ b/hw/acpi/ich9.c -@@ -435,8 +435,8 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm) - static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN; - pm->acpi_memory_hotplug.is_enabled = true; - pm->cpu_hotplug_legacy = true; -- pm->disable_s3 = 0; -- pm->disable_s4 = 0; -+ pm->disable_s3 = 1; -+ pm->disable_s4 = 1; - pm->s4_val = 2; - pm->use_acpi_hotplug_bridge = true; - pm->keep_pci_slot_hpc = true; -diff --git a/hw/block/fdc.c b/hw/block/fdc.c -index 347875a0cd..ca1776121f 100644 ---- a/hw/block/fdc.c -+++ b/hw/block/fdc.c -@@ -49,6 +49,8 @@ - #include "qom/object.h" - #include "fdc-internal.h" - -+#include "hw/boards.h" -+ - /********************************************************/ - /* debug Floppy devices */ - -@@ -2338,6 +2340,14 @@ void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp) - FDrive *drive; - static int command_tables_inited = 0; - -+ /* Restricted for Red Hat Enterprise Linux: */ -+ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); -+ if (!strstr(mc->name, "-rhel7.")) { -+ error_setg(errp, "Device %s is not supported with machine type %s", -+ object_get_typename(OBJECT(dev)), mc->name); -+ return; -+ } -+ - if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) { - error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'"); - return; -diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build -index 9e52fee9e7..bb71c9f3e7 100644 ---- a/hw/cpu/meson.build -+++ b/hw/cpu/meson.build -@@ -1,6 +1,7 @@ --softmmu_ss.add(files('core.c', 'cluster.c')) -+#softmmu_ss.add(files('core.c', 'cluster.c')) -+softmmu_ss.add(files('core.c')) - - specific_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c')) - specific_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c')) - specific_ss.add(when: 'CONFIG_A9MPCORE', if_true: files('a9mpcore.c')) --specific_ss.add(when: 'CONFIG_A15MPCORE', if_true: files('a15mpcore.c')) -+#specific_ss.add(when: 'CONFIG_A15MPCORE', if_true: files('a15mpcore.c')) -diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c -index 3bb6a58698..6447fdb02e 100644 ---- a/hw/display/cirrus_vga.c -+++ b/hw/display/cirrus_vga.c -@@ -2945,7 +2945,10 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp) - PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); - int16_t device_id = pc->device_id; - -- /* -+ warn_report("'cirrus-vga' is deprecated, " -+ "please use a different VGA card instead"); -+ -+ /* - * Follow real hardware, cirrus card emulated has 4 MB video memory. - * Also accept 8 MB/16 MB for backward compatibility. - */ -diff --git a/hw/ide/piix.c b/hw/ide/piix.c -index ce89fd0aa3..fbcf802b13 100644 ---- a/hw/ide/piix.c -+++ b/hw/ide/piix.c -@@ -232,7 +232,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) - k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1; - k->class_id = PCI_CLASS_STORAGE_IDE; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -- dc->hotpluggable = false; -+ /* Disabled for Red Hat Enterprise Linux: */ -+ dc->user_creatable = false; - } - - static const TypeInfo piix3_ide_info = { -@@ -261,6 +262,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data) - k->class_id = PCI_CLASS_STORAGE_IDE; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->hotpluggable = false; -+ /* Disabled for Red Hat Enterprise Linux: */ -+ dc->user_creatable = false; - } - - static const TypeInfo piix4_ide_info = { -diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c -index 4efdf75620..5143ebaa27 100644 ---- a/hw/input/pckbd.c -+++ b/hw/input/pckbd.c -@@ -814,6 +814,8 @@ static void i8042_class_initfn(ObjectClass *klass, void *data) - dc->vmsd = &vmstate_kbd_isa; - isa->build_aml = i8042_build_aml; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); -+ /* Disabled for Red Hat Enterprise Linux: */ -+ dc->user_creatable = false; - } - - static const TypeInfo i8042_info = { -diff --git a/hw/net/e1000.c b/hw/net/e1000.c -index f5bc81296d..282d01e374 100644 ---- a/hw/net/e1000.c -+++ b/hw/net/e1000.c -@@ -1821,6 +1821,7 @@ static const E1000Info e1000_devices[] = { - .revision = 0x03, - .phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT, - }, -+#if 0 /* Disabled for Red Hat Enterprise Linux 7 */ - { - .name = "e1000-82544gc", - .device_id = E1000_DEV_ID_82544GC_COPPER, -@@ -1833,6 +1834,7 @@ static const E1000Info e1000_devices[] = { - .revision = 0x03, - .phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT, - }, -+#endif - }; - - static void e1000_register_types(void) -diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c -index 8a4861f45a..fcb5dfe792 100644 ---- a/hw/ppc/spapr_cpu_core.c -+++ b/hw/ppc/spapr_cpu_core.c -@@ -379,10 +379,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = { - .instance_size = sizeof(SpaprCpuCore), - .class_size = sizeof(SpaprCpuCoreClass), - }, -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"), - DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"), - DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.1"), - DEFINE_SPAPR_CPU_CORE_TYPE("power5+_v2.1"), -+#endif - DEFINE_SPAPR_CPU_CORE_TYPE("power7_v2.3"), - DEFINE_SPAPR_CPU_CORE_TYPE("power7+_v2.1"), - DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"), -diff --git a/hw/usb/meson.build b/hw/usb/meson.build -index de853d780d..0776ae6a20 100644 ---- a/hw/usb/meson.build -+++ b/hw/usb/meson.build -@@ -52,7 +52,7 @@ softmmu_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reade - if cacard.found() - usbsmartcard_ss = ss.source_set() - usbsmartcard_ss.add(when: 'CONFIG_USB_SMARTCARD', -- if_true: [cacard, files('ccid-card-emulated.c', 'ccid-card-passthru.c')]) -+ if_true: [cacard, files('ccid-card-passthru.c')]) - hw_usb_modules += {'smartcard': usbsmartcard_ss} - endif - -diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c -index 13d0e9b195..3826fa5122 100644 ---- a/target/arm/cpu_tcg.c -+++ b/target/arm/cpu_tcg.c -@@ -22,6 +22,7 @@ - /* CPU models. These are not needed for the AArch64 linux-user build. */ - #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - #if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG) - static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) - { -@@ -375,6 +376,7 @@ static void cortex_a9_initfn(Object *obj) - cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */ - define_arm_cp_regs(cpu, cortexa9_cp_reginfo); - } -+#endif /* disabled for RHEL */ - - #ifndef CONFIG_USER_ONLY - static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) -@@ -400,6 +402,7 @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = { - REGINFO_SENTINEL - }; - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void cortex_a7_initfn(Object *obj) - { - ARMCPU *cpu = ARM_CPU(obj); -@@ -445,6 +448,7 @@ static void cortex_a7_initfn(Object *obj) - cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ - define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */ - } -+#endif /* disabled for RHEL */ - - static void cortex_a15_initfn(Object *obj) - { -@@ -488,6 +492,7 @@ static void cortex_a15_initfn(Object *obj) - define_arm_cp_regs(cpu, cortexa15_cp_reginfo); - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void cortex_m0_initfn(Object *obj) - { - ARMCPU *cpu = ARM_CPU(obj); -@@ -928,6 +933,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) - - cc->gdb_core_xml_file = "arm-m-profile.xml"; - } -+#endif /* disabled for RHEL */ - - #ifndef TARGET_AARCH64 - /* -@@ -1007,6 +1013,7 @@ static void arm_max_initfn(Object *obj) - #endif /* !TARGET_AARCH64 */ - - static const ARMCPUInfo arm_tcg_cpus[] = { -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - { .name = "arm926", .initfn = arm926_initfn }, - { .name = "arm946", .initfn = arm946_initfn }, - { .name = "arm1026", .initfn = arm1026_initfn }, -@@ -1022,7 +1029,9 @@ static const ARMCPUInfo arm_tcg_cpus[] = { - { .name = "cortex-a7", .initfn = cortex_a7_initfn }, - { .name = "cortex-a8", .initfn = cortex_a8_initfn }, - { .name = "cortex-a9", .initfn = cortex_a9_initfn }, -+#endif /* disabled for RHEL */ - { .name = "cortex-a15", .initfn = cortex_a15_initfn }, -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - { .name = "cortex-m0", .initfn = cortex_m0_initfn, - .class_init = arm_v7m_class_init }, - { .name = "cortex-m3", .initfn = cortex_m3_initfn, -@@ -1053,6 +1062,7 @@ static const ARMCPUInfo arm_tcg_cpus[] = { - { .name = "pxa270-b1", .initfn = pxa270b1_initfn }, - { .name = "pxa270-c0", .initfn = pxa270c0_initfn }, - { .name = "pxa270-c5", .initfn = pxa270c5_initfn }, -+#endif /* disabled for RHEL */ - #ifndef TARGET_AARCH64 - { .name = "max", .initfn = arm_max_initfn }, - #endif -diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c -index 976be5e0d1..dd78883410 100644 ---- a/target/ppc/cpu-models.c -+++ b/target/ppc/cpu-models.c -@@ -66,6 +66,7 @@ - #define POWERPC_DEF(_name, _pvr, _type, _desc) \ - POWERPC_DEF_SVR(_name, _desc, _pvr, POWERPC_SVR_NONE, _type) - -+#if 0 /* Embedded and 32-bit CPUs disabled for Red Hat Enterprise Linux */ - /* Embedded PowerPC */ - /* PowerPC 405 family */ - /* PowerPC 405 cores */ -@@ -698,8 +699,10 @@ - "PowerPC 7447A v1.2 (G4)") - POWERPC_DEF("7457a_v1.2", CPU_POWERPC_74x7A_v12, 7455, - "PowerPC 7457A v1.2 (G4)") -+#endif - /* 64 bits PowerPC */ - #if defined(TARGET_PPC64) -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - POWERPC_DEF("970_v2.2", CPU_POWERPC_970_v22, 970, - "PowerPC 970 v2.2") - POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970, -@@ -718,6 +721,7 @@ - "PowerPC 970MP v1.1") - POWERPC_DEF("power5+_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P, - "POWER5+ v2.1") -+#endif - POWERPC_DEF("power7_v2.3", CPU_POWERPC_POWER7_v23, POWER7, - "POWER7 v2.3") - POWERPC_DEF("power7+_v2.1", CPU_POWERPC_POWER7P_v21, POWER7, -@@ -897,12 +901,15 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { - { "7447a", "7447a_v1.2" }, - { "7457a", "7457a_v1.2" }, - { "apollo7pm", "7457a_v1.0" }, -+//#endif - #if defined(TARGET_PPC64) -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - { "970", "970_v2.2" }, - { "970fx", "970fx_v3.1" }, - { "970mp", "970mp_v1.1" }, - { "power5+", "power5+_v2.1" }, - { "power5gs", "power5+_v2.1" }, -+#endif - { "power7", "power7_v2.3" }, - { "power7+", "power7+_v2.1" }, - { "power8e", "power8e_v2.1" }, -@@ -912,6 +919,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { - { "power10", "power10_v2.0" }, - #endif - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - /* Generic PowerPCs */ - #if defined(TARGET_PPC64) - { "ppc64", "970fx_v3.1" }, -@@ -919,5 +927,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { - { "ppc32", "604" }, - { "ppc", "604" }, - { "default", "604" }, -+#endif - { NULL, NULL } - }; -diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c -index 05c3ccaaff..6a04ccab1b 100644 ---- a/target/s390x/cpu_models_sysemu.c -+++ b/target/s390x/cpu_models_sysemu.c -@@ -36,6 +36,9 @@ static void check_unavailable_features(const S390CPUModel *max_model, - (max_model->def->gen == model->def->gen && - max_model->def->ec_ga < model->def->ec_ga)) { - list_add_feat("type", unavailable); -+ } else if (model->def->gen < 11 && kvm_enabled()) { -+ /* Older CPU models are not supported on Red Hat Enterprise Linux */ -+ list_add_feat("type", unavailable); - } - - /* detect missing features if any to properly report them */ -diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c -index 6acf14d5ec..74f089d87f 100644 ---- a/target/s390x/kvm/kvm.c -+++ b/target/s390x/kvm/kvm.c -@@ -2512,6 +2512,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp) - error_setg(errp, "KVM doesn't support CPU models"); - return; - } -+ -+ /* Older CPU models are not supported on Red Hat Enterprise Linux */ -+ if (model->def->gen < 11) { -+ error_setg(errp, "KVM: Unsupported CPU type specified: %s", -+ MACHINE(qdev_get_machine())->cpu_type); -+ return; -+ } -+ - prop.cpuid = s390_cpuid_from_cpu_model(model); - prop.ibc = s390_ibc_from_cpu_model(model); - /* configure cpu features indicated via STFL(e) */ --- -2.31.1 - diff --git a/extras/qemu/0006-Machine-type-related-general-changes.patch b/extras/qemu/0006-Machine-type-related-general-changes.patch deleted file mode 100644 index c3b08a4..0000000 --- a/extras/qemu/0006-Machine-type-related-general-changes.patch +++ /dev/null @@ -1,619 +0,0 @@ -From a525db3951dc68c469d1f51bdc69ab6e75e72c37 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 11 Jan 2019 09:54:45 +0100 -Subject: Machine type related general changes - -This patch is first part of original "Add RHEL machine types" patch we -split to allow easier review. It contains changes not related to any -architecture. - -Signed-off-by: Miroslav Rezanina --- -Rebase notes (6.2.0): -- Do not duplicate minimal_version_id for piix4_pm -- Remove empty line chunks in serial.c -- Remove migration.h include in serial.c -- Update hw_compat_rhel_8_5 (from MR 66) - -Rebase notes (7.0.0): -- Remove downstream changes leftovers in hw/rtc/mc146818rtc.c -- Remove unnecessary change in hw/usb/hcd-uhci.c - -Merged patches (6.1.0): -- f2fb42a3c6 redhat: add missing entries in hw_compat_rhel_8_4 -- 1949ec258e hw/arm/virt: Disable PL011 clock migration through hw_compat_rhel_8_3 -- a3995e2eff Remove RHEL 7.0.0 machine type (only generic changes) -- ad3190a79b Remove RHEL 7.1.0 machine type (only generic changes) -- 84bbe15d4e Remove RHEL 7.2.0 machine type (only generic changes) -- 0215eb3356 Remove RHEL 7.3.0 machine types (only generic changes) -- af69d1ca6e Remove RHEL 7.4.0 machine types (only generic changes) -- 8f7a74ab78 Remove RHEL 7.5.0 machine types (only generic changes) - -Merged patches (6.2.0): -- d687ac13d2 redhat: Define hw_compat_rhel_8_5 - -Merged patches (7.0.0): -- ef5afcc86d Fix virtio-net-pci* "vectors" compat -- 168f0d56e3 compat: Update hw_compat_rhel_8_5 with 6.2.0 RC2 changes ---- - hw/acpi/piix4.c | 6 +- - hw/arm/virt.c | 2 +- - hw/core/machine.c | 186 +++++++++++++++++++++++++++++++++++ - hw/display/vga-isa.c | 2 +- - hw/i386/pc_piix.c | 2 + - hw/i386/pc_q35.c | 2 + - hw/net/rtl8139.c | 4 +- - hw/smbios/smbios.c | 46 ++++++++- - hw/timer/i8254_common.c | 2 +- - hw/usb/hcd-xhci-pci.c | 59 ++++++++--- - hw/usb/hcd-xhci-pci.h | 1 + - include/hw/boards.h | 21 ++++ - include/hw/firmware/smbios.h | 5 +- - include/hw/i386/pc.h | 3 + - 14 files changed, 316 insertions(+), 25 deletions(-) - -diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c -index fe5625d07a..28544e78c3 100644 ---- a/hw/acpi/piix4.c -+++ b/hw/acpi/piix4.c -@@ -287,7 +287,7 @@ static bool vmstate_test_migrate_acpi_index(void *opaque, int version_id) - static const VMStateDescription vmstate_acpi = { - .name = "piix4_pm", - .version_id = 3, -- .minimum_version_id = 3, -+ .minimum_version_id = 2, - .post_load = vmstate_acpi_post_load, - .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState), -@@ -653,8 +653,8 @@ static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) - - static Property piix4_pm_properties[] = { - DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), -- DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), -- DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), -+ DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 1), -+ DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 1), - DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), - DEFINE_PROP_BOOL(ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, PIIX4PMState, - use_acpi_hotplug_bridge, true), -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index d2e5ecd234..6a84031fd7 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -1596,7 +1596,7 @@ static void virt_build_smbios(VirtMachineState *vms) - - smbios_set_defaults("QEMU", product, - vmc->smbios_old_sys_ver ? "1.0" : mc->name, false, -- true, SMBIOS_ENTRY_POINT_TYPE_64); -+ true, NULL, NULL, SMBIOS_ENTRY_POINT_TYPE_64); - - smbios_get_tables(MACHINE(vms), NULL, 0, - &smbios_tables, &smbios_tables_len, -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 1e23fdc14b..ea430d844e 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -37,6 +37,192 @@ - #include "hw/virtio/virtio.h" - #include "hw/virtio/virtio-pci.h" - -+/* -+ * Mostly the same as hw_compat_6_0 and hw_compat_6_1 -+ */ -+GlobalProperty hw_compat_rhel_8_5[] = { -+ /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -+ { "gpex-pcihost", "allow-unmapped-accesses", "false" }, -+ /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -+ { "i8042", "extended-state", "false"}, -+ /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -+ { "nvme-ns", "eui64-default", "off"}, -+ /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -+ { "e1000", "init-vet", "off" }, -+ /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -+ { "e1000e", "init-vet", "off" }, -+ /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -+ { "vhost-vsock-device", "seqpacket", "off" }, -+ /* hw_compat_rhel_8_5 from hw_compat_6_1 */ -+ { "vhost-user-vsock-device", "seqpacket", "off" }, -+ /* hw_compat_rhel_8_5 from hw_compat_6_1 */ -+ { "nvme-ns", "shared", "off" }, -+}; -+const size_t hw_compat_rhel_8_5_len = G_N_ELEMENTS(hw_compat_rhel_8_5); -+ -+/* -+ * Mostly the same as hw_compat_5_2 -+ */ -+GlobalProperty hw_compat_rhel_8_4[] = { -+ /* hw_compat_rhel_8_4 from hw_compat_5_2 */ -+ { "ICH9-LPC", "smm-compat", "on"}, -+ /* hw_compat_rhel_8_4 from hw_compat_5_2 */ -+ { "PIIX4_PM", "smm-compat", "on"}, -+ /* hw_compat_rhel_8_4 from hw_compat_5_2 */ -+ { "virtio-blk-device", "report-discard-granularity", "off" }, -+ /* hw_compat_rhel_8_4 from hw_compat_5_2 */ -+ /* -+ * Upstream incorrectly had "virtio-net-pci" instead of "virtio-net-pci-base", -+ * (https://bugzilla.redhat.com/show_bug.cgi?id=1999141) -+ */ -+ { "virtio-net-pci-base", "vectors", "3"}, -+}; -+const size_t hw_compat_rhel_8_4_len = G_N_ELEMENTS(hw_compat_rhel_8_4); -+ -+/* -+ * Mostly the same as hw_compat_5_1 -+ */ -+GlobalProperty hw_compat_rhel_8_3[] = { -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "vhost-scsi", "num_queues", "1"}, -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "vhost-user-blk", "num-queues", "1"}, -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "vhost-user-scsi", "num_queues", "1"}, -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "virtio-blk-device", "num-queues", "1"}, -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "virtio-scsi-device", "num_queues", "1"}, -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "nvme", "use-intel-id", "on"}, -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */ -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "pl011", "migrate-clk", "off" }, -+ /* hw_compat_rhel_8_3 bz 1912846 */ -+ { "pci-xhci", "x-rh-late-msi-cap", "off" }, -+ /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -+ { "virtio-pci", "x-ats-page-aligned", "off"}, -+}; -+const size_t hw_compat_rhel_8_3_len = G_N_ELEMENTS(hw_compat_rhel_8_3); -+ -+/* -+ * The same as hw_compat_4_2 + hw_compat_5_0 -+ */ -+GlobalProperty hw_compat_rhel_8_2[] = { -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "virtio-blk-device", "queue-size", "128"}, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "virtio-scsi-device", "virtqueue_size", "128"}, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "virtio-blk-device", "x-enable-wce-if-config-wce", "off" }, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "virtio-blk-device", "seg-max-adjust", "off"}, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "virtio-scsi-device", "seg_max_adjust", "off"}, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "vhost-blk-device", "seg_max_adjust", "off"}, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "usb-host", "suppress-remote-wake", "off" }, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "usb-redir", "suppress-remote-wake", "off" }, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "qxl", "revision", "4" }, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "qxl-vga", "revision", "4" }, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "fw_cfg", "acpi-mr-restore", "false" }, -+ /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -+ { "virtio-device", "use-disabled-flag", "false" }, -+ /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -+ { "pci-host-bridge", "x-config-reg-migration-enabled", "off" }, -+ /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -+ { "virtio-balloon-device", "page-poison", "false" }, -+ /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -+ { "vmport", "x-read-set-eax", "off" }, -+ /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -+ { "vmport", "x-signal-unsupported-cmd", "off" }, -+ /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -+ { "vmport", "x-report-vmx-type", "off" }, -+ /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -+ { "vmport", "x-cmds-v2", "off" }, -+ /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -+ { "virtio-device", "x-disable-legacy-check", "true" }, -+}; -+const size_t hw_compat_rhel_8_2_len = G_N_ELEMENTS(hw_compat_rhel_8_2); -+ -+/* -+ * The same as hw_compat_4_1 -+ */ -+GlobalProperty hw_compat_rhel_8_1[] = { -+ /* hw_compat_rhel_8_1 from hw_compat_4_1 */ -+ { "virtio-pci", "x-pcie-flr-init", "off" }, -+}; -+const size_t hw_compat_rhel_8_1_len = G_N_ELEMENTS(hw_compat_rhel_8_1); -+ -+/* The same as hw_compat_3_1 -+ * format of array has been changed by: -+ * 6c36bddf5340 ("machine: Use shorter format for GlobalProperty arrays") -+ */ -+GlobalProperty hw_compat_rhel_8_0[] = { -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "pcie-root-port", "x-speed", "2_5" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "pcie-root-port", "x-width", "1" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "tpm-crb", "ppi", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "tpm-tis", "ppi", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "usb-kbd", "serial", "42" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "usb-mouse", "serial", "42" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "usb-tablet", "serial", "42" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "virtio-blk-device", "discard", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -+ { "virtio-blk-device", "write-zeroes", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -+ { "VGA", "edid", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -+ { "secondary-vga", "edid", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -+ { "bochs-display", "edid", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -+ { "virtio-vga", "edid", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -+ { "virtio-gpu-device", "edid", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -+ { "virtio-device", "use-started", "false" }, -+ /* hw_compat_rhel_8_0 from hw_compat_3_1 - that was added in 4.1 */ -+ { "pcie-root-port-base", "disable-acs", "true" }, -+}; -+const size_t hw_compat_rhel_8_0_len = G_N_ELEMENTS(hw_compat_rhel_8_0); -+ -+/* The same as hw_compat_3_0 + hw_compat_2_12 -+ * except that -+ * there's nothing in 3_0 -+ * migration.decompress-error-check=off was in 7.5 from bz 1584139 -+ */ -+GlobalProperty hw_compat_rhel_7_6[] = { -+ /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -+ { "hda-audio", "use-timer", "false" }, -+ /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -+ { "cirrus-vga", "global-vmstate", "true" }, -+ /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -+ { "VGA", "global-vmstate", "true" }, -+ /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -+ { "vmware-svga", "global-vmstate", "true" }, -+ /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -+ { "qxl-vga", "global-vmstate", "true" }, -+}; -+const size_t hw_compat_rhel_7_6_len = G_N_ELEMENTS(hw_compat_rhel_7_6); -+ - GlobalProperty hw_compat_6_2[] = { - { "PIIX4_PM", "x-not-migrate-acpi-index", "on"}, - }; -diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c -index 46abbc5653..505467059b 100644 ---- a/hw/display/vga-isa.c -+++ b/hw/display/vga-isa.c -@@ -88,7 +88,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp) - } - - static Property vga_isa_properties[] = { -- DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 8), -+ DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 16), - DEFINE_PROP_END_OF_LIST(), - }; - -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index b72c03d0a6..c797e98312 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -177,6 +177,8 @@ static void pc_init1(MachineState *machine, - smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)", - mc->name, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, -+ pcmc->smbios_stream_product, -+ pcmc->smbios_stream_version, - pcms->smbios_entry_point_type); - } - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 1780f79bc1..b695f88c45 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -200,6 +200,8 @@ static void pc_q35_init(MachineState *machine) - smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)", - mc->name, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, -+ pcmc->smbios_stream_product, -+ pcmc->smbios_stream_version, - pcms->smbios_entry_point_type); - } - -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index 6b65823b4b..75dacabc43 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -3179,7 +3179,7 @@ static int rtl8139_pre_save(void *opaque) - - static const VMStateDescription vmstate_rtl8139 = { - .name = "rtl8139", -- .version_id = 5, -+ .version_id = 4, - .minimum_version_id = 3, - .post_load = rtl8139_post_load, - .pre_save = rtl8139_pre_save, -@@ -3260,7 +3260,9 @@ static const VMStateDescription vmstate_rtl8139 = { - VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State), - VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State), - VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State), -+#if 0 /* Disabled for Red Hat Enterprise Linux bz 1420195 */ - VMSTATE_UINT32_V(tally_counters.RxOkMul, RTL8139State, 5), -+#endif - VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State), - VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State), - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 60349ee402..0edcc98434 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -57,6 +57,9 @@ static bool smbios_legacy = true; - static bool smbios_uuid_encoded = true; - /* end: legacy structures & constants for <= 2.0 machines */ - -+/* Set to true for modern Windows 10 HardwareID-6 compat */ -+static bool smbios_type2_required; -+ - - uint8_t *smbios_tables; - size_t smbios_tables_len; -@@ -639,7 +642,7 @@ static void smbios_build_type_1_table(void) - - static void smbios_build_type_2_table(void) - { -- SMBIOS_BUILD_TABLE_PRE(2, T2_BASE, false); /* optional */ -+ SMBIOS_BUILD_TABLE_PRE(2, T2_BASE, smbios_type2_required); - - SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer); - SMBIOS_TABLE_SET_STR(2, product_str, type2.product); -@@ -914,7 +917,10 @@ void smbios_set_cpuid(uint32_t version, uint32_t features) - - void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, bool legacy_mode, -- bool uuid_encoded, SmbiosEntryPointType ep_type) -+ bool uuid_encoded, -+ const char *stream_product, -+ const char *stream_version, -+ SmbiosEntryPointType ep_type) - { - smbios_have_defaults = true; - smbios_legacy = legacy_mode; -@@ -935,11 +941,45 @@ void smbios_set_defaults(const char *manufacturer, const char *product, - g_free(smbios_entries); - } - -+ /* -+ * If @stream_product & @stream_version are non-NULL, then -+ * we're following rules for new Windows driver support. -+ * The data we have to report is defined in this doc: -+ * -+ * https://docs.microsoft.com/en-us/windows-hardware/drivers/install/specifying-hardware-ids-for-a-computer -+ * -+ * The Windows drivers are written to expect use of the -+ * scheme documented as "HardwareID-6" against Windows 10, -+ * which uses SMBIOS System (Type 1) and Base Board (Type 2) -+ * tables and will match on -+ * -+ * System Manufacturer = Red Hat (@manufacturer) -+ * System SKU Number = 8.2.0 (@stream_version) -+ * Baseboard Manufacturer = Red Hat (@manufacturer) -+ * Baseboard Product = RHEL-AV (@stream_product) -+ * -+ * NB, SKU must be changed with each RHEL-AV release -+ * -+ * Other fields can be freely used by applications using -+ * QEMU. For example apps can use the "System product" -+ * and "System version" to identify themselves. -+ * -+ * We get 'System Manufacturer' and 'Baseboard Manufacturer' -+ */ - SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer); - SMBIOS_SET_DEFAULT(type1.product, product); - SMBIOS_SET_DEFAULT(type1.version, version); -+ SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux"); -+ if (stream_version != NULL) { -+ SMBIOS_SET_DEFAULT(type1.sku, stream_version); -+ } - SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer); -- SMBIOS_SET_DEFAULT(type2.product, product); -+ if (stream_product != NULL) { -+ SMBIOS_SET_DEFAULT(type2.product, stream_product); -+ smbios_type2_required = true; -+ } else { -+ SMBIOS_SET_DEFAULT(type2.product, product); -+ } - SMBIOS_SET_DEFAULT(type2.version, version); - SMBIOS_SET_DEFAULT(type3.manufacturer, manufacturer); - SMBIOS_SET_DEFAULT(type3.version, version); -diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c -index 050875b497..32935da46c 100644 ---- a/hw/timer/i8254_common.c -+++ b/hw/timer/i8254_common.c -@@ -231,7 +231,7 @@ static const VMStateDescription vmstate_pit_common = { - .pre_save = pit_dispatch_pre_save, - .post_load = pit_dispatch_post_load, - .fields = (VMStateField[]) { -- VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), -+ VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), /* qemu-kvm's v2 had 'flags' here */ - VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2, - vmstate_pit_channel, PITChannelState), - VMSTATE_INT64(channels[0].next_transition_time, -diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c -index e934b1a5b1..e18b05e528 100644 ---- a/hw/usb/hcd-xhci-pci.c -+++ b/hw/usb/hcd-xhci-pci.c -@@ -104,6 +104,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id) - return 0; - } - -+/* RH bz 1912846 */ -+static bool usb_xhci_pci_add_msi(struct PCIDevice *dev, Error **errp) -+{ -+ int ret; -+ Error *err = NULL; -+ XHCIPciState *s = XHCI_PCI(dev); -+ -+ ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err); -+ /* -+ * Any error other than -ENOTSUP(board's MSI support is broken) -+ * is a programming error -+ */ -+ assert(!ret || ret == -ENOTSUP); -+ if (ret && s->msi == ON_OFF_AUTO_ON) { -+ /* Can't satisfy user's explicit msi=on request, fail */ -+ error_append_hint(&err, "You have to use msi=auto (default) or " -+ "msi=off with this machine type.\n"); -+ error_propagate(errp, err); -+ return true; -+ } -+ assert(!err || s->msi == ON_OFF_AUTO_AUTO); -+ /* With msi=auto, we fall back to MSI off silently */ -+ error_free(err); -+ -+ return false; -+} -+ - static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) - { - int ret; -@@ -125,23 +152,12 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) - s->xhci.nec_quirks = true; - } - -- if (s->msi != ON_OFF_AUTO_OFF) { -- ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err); -- /* -- * Any error other than -ENOTSUP(board's MSI support is broken) -- * is a programming error -- */ -- assert(!ret || ret == -ENOTSUP); -- if (ret && s->msi == ON_OFF_AUTO_ON) { -- /* Can't satisfy user's explicit msi=on request, fail */ -- error_append_hint(&err, "You have to use msi=auto (default) or " -- "msi=off with this machine type.\n"); -+ if (s->msi != ON_OFF_AUTO_OFF && s->rh_late_msi_cap) { -+ /* This gives the behaviour from 5.2.0 onwards, lspci shows 90,a0,70 */ -+ if (usb_xhci_pci_add_msi(dev, &err)) { - error_propagate(errp, err); - return; - } -- assert(!err || s->msi == ON_OFF_AUTO_AUTO); -- /* With msi=auto, we fall back to MSI off silently */ -- error_free(err); - } - pci_register_bar(dev, 0, - PCI_BASE_ADDRESS_SPACE_MEMORY | -@@ -154,6 +170,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) - assert(ret > 0); - } - -+ /* RH bz 1912846 */ -+ if (s->msi != ON_OFF_AUTO_OFF && !s->rh_late_msi_cap) { -+ /* This gives the older RH machine behaviour, lspci shows 90,70,a0 */ -+ if (usb_xhci_pci_add_msi(dev, &err)) { -+ error_propagate(errp, err); -+ return; -+ } -+ } - if (s->msix != ON_OFF_AUTO_OFF) { - /* TODO check for errors, and should fail when msix=on */ - msix_init(dev, s->xhci.numintrs, -@@ -198,11 +222,18 @@ static void xhci_instance_init(Object *obj) - qdev_alias_all_properties(DEVICE(&s->xhci), obj); - } - -+static Property xhci_pci_properties[] = { -+ /* RH bz 1912846 */ -+ DEFINE_PROP_BOOL("x-rh-late-msi-cap", XHCIPciState, rh_late_msi_cap, true), -+ DEFINE_PROP_END_OF_LIST() -+}; -+ - static void xhci_class_init(ObjectClass *klass, void *data) - { - PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - DeviceClass *dc = DEVICE_CLASS(klass); - -+ device_class_set_props(dc, xhci_pci_properties); - dc->reset = xhci_pci_reset; - dc->vmsd = &vmstate_xhci_pci; - set_bit(DEVICE_CATEGORY_USB, dc->categories); -diff --git a/hw/usb/hcd-xhci-pci.h b/hw/usb/hcd-xhci-pci.h -index c193f79443..086a1feb1e 100644 ---- a/hw/usb/hcd-xhci-pci.h -+++ b/hw/usb/hcd-xhci-pci.h -@@ -39,6 +39,7 @@ typedef struct XHCIPciState { - XHCIState xhci; - OnOffAuto msi; - OnOffAuto msix; -+ bool rh_late_msi_cap; /* bz 1912846 */ - } XHCIPciState; - - #endif -diff --git a/include/hw/boards.h b/include/hw/boards.h -index c92ac8815c..c90a19b4d1 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -449,4 +449,25 @@ extern const size_t hw_compat_2_2_len; - extern GlobalProperty hw_compat_2_1[]; - extern const size_t hw_compat_2_1_len; - -+extern GlobalProperty hw_compat_rhel_8_5[]; -+extern const size_t hw_compat_rhel_8_5_len; -+ -+extern GlobalProperty hw_compat_rhel_8_4[]; -+extern const size_t hw_compat_rhel_8_4_len; -+ -+extern GlobalProperty hw_compat_rhel_8_3[]; -+extern const size_t hw_compat_rhel_8_3_len; -+ -+extern GlobalProperty hw_compat_rhel_8_2[]; -+extern const size_t hw_compat_rhel_8_2_len; -+ -+extern GlobalProperty hw_compat_rhel_8_1[]; -+extern const size_t hw_compat_rhel_8_1_len; -+ -+extern GlobalProperty hw_compat_rhel_8_0[]; -+extern const size_t hw_compat_rhel_8_0_len; -+ -+extern GlobalProperty hw_compat_rhel_7_6[]; -+extern const size_t hw_compat_rhel_7_6_len; -+ - #endif -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 4b7ad77a44..9acff96a86 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -272,7 +272,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp); - void smbios_set_cpuid(uint32_t version, uint32_t features); - void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, bool legacy_mode, -- bool uuid_encoded, SmbiosEntryPointType ep_type); -+ bool uuid_encoded, -+ const char *stream_product, -+ const char *stream_version, -+ SmbiosEntryPointType ep_type); - uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length); - void smbios_get_tables(MachineState *ms, - const struct smbios_phys_mem_area *mem_array, -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 1a27de9c8b..91331059d9 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -113,6 +113,9 @@ struct PCMachineClass { - bool smbios_defaults; - bool smbios_legacy_mode; - bool smbios_uuid_encoded; -+ /* New fields needed for Windows HardwareID-6 matching */ -+ const char *smbios_stream_product; -+ const char *smbios_stream_version; - - /* RAM / address space compat: */ - bool gigabyte_align; --- -2.31.1 - diff --git a/extras/qemu/0007-Add-aarch64-machine-types.patch b/extras/qemu/0007-Add-aarch64-machine-types.patch deleted file mode 100644 index 3c44b11..0000000 --- a/extras/qemu/0007-Add-aarch64-machine-types.patch +++ /dev/null @@ -1,352 +0,0 @@ -From 697aaa43e3c0f20fc312f06be6c1093f1ba907e1 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 19 Oct 2018 12:53:31 +0200 -Subject: Add aarch64 machine types - -Adding changes to add RHEL machine types for aarch64 architecture. - -Signed-off-by: Miroslav Rezanina ---- -Rebase notes (6.1.0): -- Use CONFIG_TPM check when using TPM structures -- Add support for default_bus_bypass_iommu -- ea4c0b32d9 arm/virt: Register highmem and gic-version as class properties -- 895e1fa86a hw/arm/virt: Add 8.5 and 9.0 machine types and remove older ones - -Rebase notes (7.0.0): -- Added dtb-kaslr-seed option -- Set no_tcg_lpa2 to true - -Merged patches (6.2.0): -- 9a3d4fde0e hw/arm/virt: Remove 9.0 machine type -- f7d04d6695 hw: arm: virt: Add hw_compat_rhel_8_5 to 8.5 machine type - -Merged patches (7.0.0): -- 3b82be3dd3 redhat: virt-rhel8.5.0: Update machine type compatibility for QEMU 6.2.0 update -- c354a86c9b hw/arm/virt: Register "iommu" as a class property -- c1a2630dc9 hw/arm/virt: Register "its" as a class property -- 9d8c61dc93 hw/arm/virt: Rename default_bus_bypass_iommu -- a1d1b6eeb6 hw/arm/virt: Expose the 'RAS' option -- 47f8fe1b82 hw/arm/virt: Add 9.0 machine type and remove 8.5 one -- ed2346788f hw/arm/virt: Check no_tcg_its and minor style changes ---- - hw/arm/virt.c | 234 +++++++++++++++++++++++++++++++++++++++++- - include/hw/arm/virt.h | 8 ++ - 2 files changed, 241 insertions(+), 1 deletion(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 6a84031fd7..e06862d22a 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -80,6 +80,7 @@ - #include "hw/char/pl011.h" - #include "qemu/guest-random.h" - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ - static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ - void *data) \ -@@ -106,7 +107,48 @@ - DEFINE_VIRT_MACHINE_LATEST(major, minor, true) - #define DEFINE_VIRT_MACHINE(major, minor) \ - DEFINE_VIRT_MACHINE_LATEST(major, minor, false) -- -+#endif /* disabled for RHEL */ -+ -+#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \ -+ static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \ -+ void *data) \ -+ { \ -+ MachineClass *mc = MACHINE_CLASS(oc); \ -+ rhel##m##n##s##_virt_options(mc); \ -+ mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \ -+ if (latest) { \ -+ mc->alias = "virt"; \ -+ mc->is_default = 1; \ -+ } \ -+ } \ -+ static const TypeInfo rhel##m##n##s##_machvirt_info = { \ -+ .name = MACHINE_TYPE_NAME("virt-rhel" # m "." # n "." # s), \ -+ .parent = TYPE_RHEL_MACHINE, \ -+ .class_init = rhel##m##n##s##_virt_class_init, \ -+ }; \ -+ static void rhel##m##n##s##_machvirt_init(void) \ -+ { \ -+ type_register_static(&rhel##m##n##s##_machvirt_info); \ -+ } \ -+ type_init(rhel##m##n##s##_machvirt_init); -+ -+#define DEFINE_RHEL_MACHINE_AS_LATEST(major, minor, subminor) \ -+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true) -+#define DEFINE_RHEL_MACHINE(major, minor, subminor) \ -+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false) -+ -+/* This variable is for changes to properties that are RHEL specific, -+ * different to the current upstream and to be applied to the latest -+ * machine type. -+ */ -+GlobalProperty arm_rhel_compat[] = { -+ { -+ .driver = "virtio-net-pci", -+ .property = "romfile", -+ .value = "", -+ }, -+}; -+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); - - /* Number of external interrupt lines to configure the GIC with */ - #define NUM_IRQS 256 -@@ -2250,6 +2292,7 @@ static void machvirt_init(MachineState *machine) - qemu_add_machine_init_done_notifier(&vms->machine_done); - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static bool virt_get_secure(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2277,6 +2320,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) - - vms->virt = value; - } -+#endif /* disabled for RHEL */ - - static bool virt_get_highmem(Object *obj, Error **errp) - { -@@ -2402,6 +2446,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp) - vms->ras = value; - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static bool virt_get_mte(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2415,6 +2460,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp) - - vms->mte = value; - } -+#endif /* disabled for RHEL */ - - static char *virt_get_gic_version(Object *obj, Error **errp) - { -@@ -2818,6 +2864,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str) - return fixed_ipa ? 0 : requested_pa_size; - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void virt_machine_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); -@@ -3206,3 +3253,188 @@ static void virt_machine_2_6_options(MachineClass *mc) - vmc->no_pmu = true; - } - DEFINE_VIRT_MACHINE(2, 6) -+#endif /* disabled for RHEL */ -+ -+static void rhel_machine_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); -+ -+ mc->family = "virt-rhel-Z"; -+ mc->init = machvirt_init; -+ /* Maximum supported VCPU count for all virt-rhel* machines */ -+ mc->max_cpus = 384; -+#ifdef CONFIG_TPM -+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); -+#endif -+ mc->block_default_type = IF_VIRTIO; -+ mc->no_cdrom = 1; -+ mc->pci_allow_0_address = true; -+ /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */ -+ mc->minimum_page_bits = 12; -+ mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids; -+ mc->cpu_index_to_instance_props = virt_cpu_index_to_props; -+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57"); -+ mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; -+ mc->kvm_type = virt_kvm_type; -+ assert(!mc->get_hotplug_handler); -+ mc->get_hotplug_handler = virt_machine_get_hotplug_handler; -+ hc->pre_plug = virt_machine_device_pre_plug_cb; -+ hc->plug = virt_machine_device_plug_cb; -+ hc->unplug_request = virt_machine_device_unplug_request_cb; -+ hc->unplug = virt_machine_device_unplug_cb; -+ mc->nvdimm_supported = true; -+ mc->auto_enable_numa_with_memhp = true; -+ mc->auto_enable_numa_with_memdev = true; -+ mc->default_ram_id = "mach-virt.ram"; -+ -+ object_class_property_add(oc, "acpi", "OnOffAuto", -+ virt_get_acpi, virt_set_acpi, -+ NULL, NULL); -+ object_class_property_set_description(oc, "acpi", -+ "Enable ACPI"); -+ -+ object_class_property_add_bool(oc, "highmem", virt_get_highmem, -+ virt_set_highmem); -+ object_class_property_set_description(oc, "highmem", -+ "Set on/off to enable/disable using " -+ "physical address space above 32 bits"); -+ -+ object_class_property_add_str(oc, "gic-version", virt_get_gic_version, -+ virt_set_gic_version); -+ object_class_property_set_description(oc, "gic-version", -+ "Set GIC version. " -+ "Valid values are 2, 3, host and max"); -+ -+ object_class_property_add_str(oc, "iommu", virt_get_iommu, virt_set_iommu); -+ object_class_property_set_description(oc, "iommu", -+ "Set the IOMMU type. " -+ "Valid values are none and smmuv3"); -+ -+ object_class_property_add_bool(oc, "default-bus-bypass-iommu", -+ virt_get_default_bus_bypass_iommu, -+ virt_set_default_bus_bypass_iommu); -+ object_class_property_set_description(oc, "default-bus-bypass-iommu", -+ "Set on/off to enable/disable " -+ "bypass_iommu for default root bus"); -+ -+ object_class_property_add_bool(oc, "ras", virt_get_ras, -+ virt_set_ras); -+ object_class_property_set_description(oc, "ras", -+ "Set on/off to enable/disable reporting host memory errors " -+ "to a KVM guest using ACPI and guest external abort exceptions"); -+ -+ object_class_property_add_bool(oc, "its", virt_get_its, -+ virt_set_its); -+ object_class_property_set_description(oc, "its", -+ "Set on/off to enable/disable " -+ "ITS instantiation"); -+ -+ object_class_property_add_str(oc, "x-oem-id", -+ virt_get_oem_id, -+ virt_set_oem_id); -+ object_class_property_set_description(oc, "x-oem-id", -+ "Override the default value of field OEMID " -+ "in ACPI table header." -+ "The string may be up to 6 bytes in size"); -+ -+ -+ object_class_property_add_str(oc, "x-oem-table-id", -+ virt_get_oem_table_id, -+ virt_set_oem_table_id); -+ object_class_property_set_description(oc, "x-oem-table-id", -+ "Override the default value of field OEM Table ID " -+ "in ACPI table header." -+ "The string may be up to 8 bytes in size"); -+ -+ object_class_property_add_bool(oc, "dtb-kaslr-seed", -+ virt_get_dtb_kaslr_seed, -+ virt_set_dtb_kaslr_seed); -+ object_class_property_set_description(oc, "dtb-kaslr-seed", -+ "Set off to disable passing of kaslr-seed " -+ "dtb node to guest"); -+} -+ -+static void rhel_virt_instance_init(Object *obj) -+{ -+ VirtMachineState *vms = VIRT_MACHINE(obj); -+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); -+ -+ /* EL3 is disabled by default and non-configurable for RHEL */ -+ vms->secure = false; -+ -+ /* EL2 is disabled by default and non-configurable for RHEL */ -+ vms->virt = false; -+ -+ /* High memory is enabled by default */ -+ vms->highmem = true; -+ vms->gic_version = VIRT_GIC_VERSION_NOSEL; -+ -+ vms->highmem_ecam = !vmc->no_highmem_ecam; -+ -+ if (vmc->no_its) { -+ vms->its = false; -+ } else { -+ /* Default allows ITS instantiation */ -+ vms->its = true; -+ -+ if (vmc->no_tcg_its) { -+ vms->tcg_its = false; -+ } else { -+ vms->tcg_its = true; -+ } -+ } -+ -+ /* Default disallows iommu instantiation */ -+ vms->iommu = VIRT_IOMMU_NONE; -+ -+ /* The default root bus is attached to iommu by default */ -+ vms->default_bus_bypass_iommu = false; -+ -+ /* Default disallows RAS instantiation and is non-configurable for RHEL */ -+ vms->ras = false; -+ -+ /* MTE is disabled by default and non-configurable for RHEL */ -+ vms->mte = false; -+ -+ /* Supply a kaslr-seed by default */ -+ vms->dtb_kaslr_seed = true; -+ -+ vms->irqmap = a15irqmap; -+ -+ virt_flash_create(vms); -+ -+ vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); -+ vms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); -+} -+ -+static const TypeInfo rhel_machine_info = { -+ .name = TYPE_RHEL_MACHINE, -+ .parent = TYPE_MACHINE, -+ .abstract = true, -+ .instance_size = sizeof(VirtMachineState), -+ .class_size = sizeof(VirtMachineClass), -+ .class_init = rhel_machine_class_init, -+ .instance_init = rhel_virt_instance_init, -+ .interfaces = (InterfaceInfo[]) { -+ { TYPE_HOTPLUG_HANDLER }, -+ { } -+ }, -+}; -+ -+static void rhel_machine_init(void) -+{ -+ type_register_static(&rhel_machine_info); -+} -+type_init(rhel_machine_init); -+ -+static void rhel900_virt_options(MachineClass *mc) -+{ -+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); -+ -+ compat_props_add(mc->compat_props, arm_rhel_compat, arm_rhel_compat_len); -+ -+ /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */ -+ vmc->no_tcg_lpa2 = true; -+} -+DEFINE_RHEL_MACHINE_AS_LATEST(9, 0, 0) -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index 7e76ee2619..9b1efe8f0e 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -179,9 +179,17 @@ struct VirtMachineState { - - #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM) - -+#if 0 /* disabled for Red Hat Enterprise Linux */ - #define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") - OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE) - -+#else -+#define TYPE_RHEL_MACHINE MACHINE_TYPE_NAME("virt-rhel") -+typedef struct VirtMachineClass VirtMachineClass; -+typedef struct VirtMachineState VirtMachineState; -+DECLARE_OBJ_CHECKERS(VirtMachineState, VirtMachineClass, VIRT_MACHINE, TYPE_RHEL_MACHINE) -+#endif -+ - void virt_acpi_setup(VirtMachineState *vms); - bool virt_is_acpi_enabled(VirtMachineState *vms); - --- -2.31.1 - diff --git a/extras/qemu/0008-Add-ppc64-machine-types.patch b/extras/qemu/0008-Add-ppc64-machine-types.patch deleted file mode 100644 index 103e944..0000000 --- a/extras/qemu/0008-Add-ppc64-machine-types.patch +++ /dev/null @@ -1,380 +0,0 @@ -From f61b3d7dc000886e23943457ee9baf1d4cae43b4 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 19 Oct 2018 13:27:13 +0200 -Subject: Add ppc64 machine types - -Adding changes to add RHEL machine types for ppc64 architecture. - -Signed-off-by: Miroslav Rezanina - -Rebase notes (6.2.0): -- Fixed rebase conflict relicts -- Update machine type compat for 6.2 (from MR 66) - -Merged patches (6.1.0): -- c438c25ac3 redhat: Define pseries-rhel8.5.0 machine type -- a3995e2eff Remove RHEL 7.0.0 machine type (only ppc64 changes) -- ad3190a79b Remove RHEL 7.1.0 machine type (only ppc64 changes) -- 84bbe15d4e Remove RHEL 7.2.0 machine type (only ppc64 changes) -- 0215eb3356 Remove RHEL 7.3.0 machine types (only ppc64 changes) -- af69d1ca6e Remove RHEL 7.4.0 machine types (only ppc64 changes) -- 8f7a74ab78 Remove RHEL 7.5.0 machine types (only ppc64 changes) ---- - hw/ppc/spapr.c | 243 ++++++++++++++++++++++++++++++++++++++++ - hw/ppc/spapr_cpu_core.c | 13 +++ - include/hw/ppc/spapr.h | 4 + - target/ppc/compat.c | 13 ++- - target/ppc/cpu.h | 1 + - target/ppc/kvm.c | 27 +++++ - target/ppc/kvm_ppc.h | 13 +++ - 7 files changed, 313 insertions(+), 1 deletion(-) - -diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c -index a4372ba189..5fdf8b506d 100644 ---- a/hw/ppc/spapr.c -+++ b/hw/ppc/spapr.c -@@ -4652,6 +4675,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) - vmc->client_architecture_support = spapr_vof_client_architecture_support; - vmc->quiesce = spapr_vof_quiesce; - vmc->setprop = spapr_vof_setprop; -+ smc->has_power9_support = true; - } - - static const TypeInfo spapr_machine_info = { -@@ -4703,6 +4727,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc) - } \ - type_init(spapr_machine_register_##suffix) - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - /* - * pseries-7.0 - */ -@@ -4830,6 +4855,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc) - } - - DEFINE_SPAPR_MACHINE(4_1, "4.1", false); -+#endif - - /* - * pseries-4.0 -@@ -4849,6 +4875,8 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index, - *nv2atsd = 0; - return true; - } -+ -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void spapr_machine_4_0_class_options(MachineClass *mc) - { - SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -@@ -5176,6 +5204,221 @@ static void spapr_machine_2_1_class_options(MachineClass *mc) - compat_props_add(mc->compat_props, hw_compat_2_1, hw_compat_2_1_len); - } - DEFINE_SPAPR_MACHINE(2_1, "2.1", false); -+#endif -+ -+static void spapr_machine_rhel_default_class_options(MachineClass *mc) -+{ -+ /* -+ * Defaults for the latest behaviour inherited from the base class -+ * can be overriden here for all pseries-rhel* machines. -+ */ -+ -+ /* Maximum supported VCPU count */ -+ mc->max_cpus = 384; -+} -+ -+/* -+ * pseries-rhel8.5.0 -+ * like pseries-6.0 -+ */ -+ -+static void spapr_machine_rhel850_class_options(MachineClass *mc) -+{ -+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ /* The default machine type must apply the RHEL specific defaults */ -+ spapr_machine_rhel_default_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_5, -+ hw_compat_rhel_8_5_len); -+ smc->pre_6_2_numa_affinity = true; -+ mc->smp_props.prefer_sockets = true; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel850, "rhel8.5.0", true); -+ -+/* -+ * pseries-rhel8.4.0 -+ * like pseries-5.2 -+ */ -+ -+static void spapr_machine_rhel840_class_options(MachineClass *mc) -+{ -+ spapr_machine_rhel850_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_4, -+ hw_compat_rhel_8_4_len); -+} -+ -+DEFINE_SPAPR_MACHINE(rhel840, "rhel8.4.0", false); -+ -+/* -+ * pseries-rhel8.3.0 -+ * like pseries-5.1 -+ */ -+ -+static void spapr_machine_rhel830_class_options(MachineClass *mc) -+{ -+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel840_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_3, -+ hw_compat_rhel_8_3_len); -+ -+ /* from pseries-5.1 */ -+ smc->pre_5_2_numa_associativity = true; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel830, "rhel8.3.0", false); -+ -+/* -+ * pseries-rhel8.2.0 -+ * like pseries-4.2 + pseries-5.0 -+ * except SPAPR_CAP_CCF_ASSIST that has been backported to pseries-rhel8.1.0 -+ */ -+ -+static void spapr_machine_rhel820_class_options(MachineClass *mc) -+{ -+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ /* from pseries-5.0 */ -+ static GlobalProperty compat[] = { -+ { TYPE_SPAPR_PCI_HOST_BRIDGE, "pre-5.1-associativity", "on" }, -+ }; -+ -+ spapr_machine_rhel830_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_2, -+ hw_compat_rhel_8_2_len); -+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); -+ -+ /* from pseries-4.2 */ -+ smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_OFF; -+ smc->rma_limit = 16 * GiB; -+ mc->nvdimm_supported = false; -+ -+ /* from pseries-5.0 */ -+ mc->numa_mem_supported = true; -+ smc->pre_5_1_assoc_refpoints = true; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel820, "rhel8.2.0", false); -+ -+/* -+ * pseries-rhel8.1.0 -+ * like pseries-4.1 -+ */ -+ -+static void spapr_machine_rhel810_class_options(MachineClass *mc) -+{ -+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ static GlobalProperty compat[] = { -+ /* Only allow 4kiB and 64kiB IOMMU pagesizes */ -+ { TYPE_SPAPR_PCI_HOST_BRIDGE, "pgsz", "0x11000" }, -+ }; -+ -+ spapr_machine_rhel820_class_options(mc); -+ -+ /* from pseries-4.1 */ -+ smc->linux_pci_probe = false; -+ smc->smp_threads_vsmt = false; -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_1, -+ hw_compat_rhel_8_1_len); -+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); -+ -+ /* from pseries-4.2 */ -+ smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel810, "rhel8.1.0", false); -+ -+/* -+ * pseries-rhel8.0.0 -+ * like pseries-3.1 and pseries-4.0 -+ * except SPAPR_CAP_CFPC, SPAPR_CAP_SBBC and SPAPR_CAP_IBS -+ * that have been backported to pseries-rhel8.0.0 -+ */ -+ -+static void spapr_machine_rhel800_class_options(MachineClass *mc) -+{ -+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel810_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_0, -+ hw_compat_rhel_8_0_len); -+ -+ /* pseries-4.0 */ -+ smc->phb_placement = phb_placement_4_0; -+ smc->irq = &spapr_irq_xics; -+ smc->pre_4_1_migration = true; -+ -+ /* pseries-3.1 */ -+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0"); -+ smc->update_dt_enabled = false; -+ smc->dr_phb_enabled = false; -+ smc->broken_host_serial_model = true; -+ smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel800, "rhel8.0.0", false); -+ -+/* -+ * pseries-rhel7.6.0 -+ * like spapr_compat_2_12 and spapr_compat_3_0 -+ * spapr_compat_0 is empty -+ */ -+GlobalProperty spapr_compat_rhel7_6[] = { -+ { TYPE_POWERPC_CPU, "pre-3.0-migration", "on" }, -+ { TYPE_SPAPR_CPU_CORE, "pre-3.0-migration", "on" }, -+}; -+const size_t spapr_compat_rhel7_6_len = G_N_ELEMENTS(spapr_compat_rhel7_6); -+ -+ -+static void spapr_machine_rhel760_class_options(MachineClass *mc) -+{ -+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel800_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len); -+ compat_props_add(mc->compat_props, spapr_compat_rhel7_6, spapr_compat_rhel7_6_len); -+ -+ /* from spapr_machine_3_0_class_options() */ -+ smc->legacy_irq_allocation = true; -+ smc->nr_xirqs = 0x400; -+ smc->irq = &spapr_irq_xics_legacy; -+ -+ /* from spapr_machine_2_12_class_options() */ -+ /* We depend on kvm_enabled() to choose a default value for the -+ * hpt-max-page-size capability. Of course we can't do it here -+ * because this is too early and the HW accelerator isn't initialzed -+ * yet. Postpone this to machine init (see default_caps_with_cpu()). -+ */ -+ smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 0; -+ -+ /* SPAPR_CAP_WORKAROUND enabled in pseries-rhel800 by -+ * f21757edc554 -+ * "Enable mitigations by default for pseries-4.0 machine type") -+ */ -+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; -+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; -+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel760, "rhel7.6.0", false); -+ -+/* -+ * pseries-rhel7.6.0-sxxm -+ * -+ * pseries-rhel7.6.0 with speculative execution exploit mitigations enabled by default -+ */ -+ -+static void spapr_machine_rhel760sxxm_class_options(MachineClass *mc) -+{ -+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel760_class_options(mc); -+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel760sxxm, "rhel7.6.0-sxxm", false); - - static void spapr_machine_register_types(void) - { -diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c -index fcb5dfe792..ab8fb5bf62 100644 ---- a/hw/ppc/spapr_cpu_core.c -+++ b/hw/ppc/spapr_cpu_core.c -@@ -25,6 +25,7 @@ - #include "sysemu/reset.h" - #include "sysemu/hw_accel.h" - #include "qemu/error-report.h" -+#include "cpu-models.h" - - static void spapr_reset_vcpu(PowerPCCPU *cpu) - { -@@ -259,6 +260,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, - { - CPUPPCState *env = &cpu->env; - CPUState *cs = CPU(cpu); -+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); - - if (!qdev_realize(DEVICE(cpu), NULL, errp)) { - return false; -@@ -270,6 +272,17 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, - /* Set time-base frequency to 512 MHz. vhyp must be set first. */ - cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ); - -+ if (!smc->has_power9_support && -+ (((spapr->max_compat_pvr && -+ ppc_compat_cmp(spapr->max_compat_pvr, -+ CPU_POWERPC_LOGICAL_3_00) >= 0)) || -+ (!spapr->max_compat_pvr && -+ ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, 0)))) { -+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, -+ "POWER9 CPU is not supported by this machine class"); -+ return false; -+ } -+ - if (spapr_irq_cpu_intc_create(spapr, cpu, errp) < 0) { - qdev_unrealize(DEVICE(cpu)); - return false; -diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h -index f5c33dcc86..4a68e0a901 100644 ---- a/include/hw/ppc/spapr.h -+++ b/include/hw/ppc/spapr.h -@@ -154,6 +154,7 @@ struct SpaprMachineClass { - bool pre_5_2_numa_associativity; - bool pre_6_2_numa_affinity; - -+ bool has_power9_support; - bool (*phb_placement)(SpaprMachineState *spapr, uint32_t index, - uint64_t *buid, hwaddr *pio, - hwaddr *mmio32, hwaddr *mmio64, -diff --git a/target/ppc/compat.c b/target/ppc/compat.c -index 7949a24f5a..f207a9ba01 100644 ---- a/target/ppc/compat.c -+++ b/target/ppc/compat.c -@@ -114,8 +114,19 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr) - return NULL; - } - -+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2) -+{ -+ const CompatInfo *compat1 = compat_by_pvr(pvr1); -+ const CompatInfo *compat2 = compat_by_pvr(pvr2); -+ -+ g_assert(compat1); -+ g_assert(compat2); -+ -+ return compat1 - compat2; -+} -+ - static bool pcc_compat(PowerPCCPUClass *pcc, uint32_t compat_pvr, -- uint32_t min_compat_pvr, uint32_t max_compat_pvr) -+ uint32_t min_compat_pvr, uint32_t max_compat_pvr) - { - const CompatInfo *compat = compat_by_pvr(compat_pvr); - const CompatInfo *min = compat_by_pvr(min_compat_pvr); -diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h -index 047b24ba50..79c5ac50b9 100644 ---- a/target/ppc/cpu.h -+++ b/target/ppc/cpu.h -@@ -1462,6 +1462,7 @@ static inline int cpu_mmu_index(CPUPPCState *env, bool ifetch) - - /* Compatibility modes */ - #if defined(TARGET_PPC64) -+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2); - bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, - uint32_t min_compat_pvr, uint32_t max_compat_pvr); - bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr, --- -2.31.1 - diff --git a/extras/qemu/0009-Add-s390x-machine-types.patch b/extras/qemu/0009-Add-s390x-machine-types.patch deleted file mode 100644 index 2d8b554..0000000 --- a/extras/qemu/0009-Add-s390x-machine-types.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 680f343e58a50a99d17bc7dedd3ee90980912023 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 19 Oct 2018 13:47:32 +0200 -Subject: Add s390x machine types - -Adding changes to add RHEL machine types for s390x architecture. - -Signed-off-by: Miroslav Rezanina --- -Merged patches (6.1.0): -- 64a9a5c971 hw/s390x: Remove the RHEL7-only machine type -- 395516d62b redhat: s390x: add rhel-8.5.0 compat machine - -Merged patches (6.2.0): -- 3bf66f4520 redhat: Add s390x machine type compatibility update for 6.1 rebase - -Merged patches (7.0.0): -- e6ff4de4f7 redhat: Add s390x machine type compatibility handling for the rebase to v6.2 -- 4b0efa7e21 redhat: Add rhel8.6.0 and rhel9.0.0 machine types for s390x -- dcc64971bf RHEL: mark old machine types as deprecated (partialy) ---- - hw/core/machine.c | 6 +++ - hw/s390x/s390-virtio-ccw.c | 104 ++++++++++++++++++++++++++++++++++++- - include/hw/boards.h | 2 + - 3 files changed, 111 insertions(+), 1 deletion(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index ea430d844e..77202a3570 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -37,6 +37,12 @@ - #include "hw/virtio/virtio.h" - #include "hw/virtio/virtio-pci.h" - -+/* -+ * RHEL only: machine types for previous major releases are deprecated -+ */ -+const char *rhel_old_machine_deprecation = -+ "machine types for previous major releases are deprecated"; -+ - /* - * Mostly the same as hw_compat_6_0 and hw_compat_6_1 - */ -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 90480e7cf9..ec4176a1e0 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -767,7 +767,7 @@ bool css_migration_enabled(void) - { \ - MachineClass *mc = MACHINE_CLASS(oc); \ - ccw_machine_##suffix##_class_options(mc); \ -- mc->desc = "VirtIO-ccw based S390 machine v" verstr; \ -+ mc->desc = "VirtIO-ccw based S390 machine " verstr; \ - if (latest) { \ - mc->alias = "s390-ccw-virtio"; \ - mc->is_default = true; \ -@@ -791,6 +791,7 @@ bool css_migration_enabled(void) - } \ - type_init(ccw_machine_register_##suffix) - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void ccw_machine_7_0_instance_options(MachineState *machine) - { - } -@@ -1115,6 +1116,107 @@ static void ccw_machine_2_4_class_options(MachineClass *mc) - compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); - } - DEFINE_CCW_MACHINE(2_4, "2.4", false); -+#endif -+ -+static void ccw_machine_rhel900_instance_options(MachineState *machine) -+{ -+} -+ -+static void ccw_machine_rhel900_class_options(MachineClass *mc) -+{ -+} -+DEFINE_CCW_MACHINE(rhel900, "rhel9.0.0", true); -+ -+static void ccw_machine_rhel860_instance_options(MachineState *machine) -+{ -+ /* Note: The -rhel8.6.0 and -rhel9.0.0 machines are technically identical */ -+ ccw_machine_rhel900_instance_options(machine); -+} -+ -+static void ccw_machine_rhel860_class_options(MachineClass *mc) -+{ -+ ccw_machine_rhel900_class_options(mc); -+ -+ /* All RHEL machines for prior major releases are deprecated */ -+ mc->deprecation_reason = rhel_old_machine_deprecation; -+} -+DEFINE_CCW_MACHINE(rhel860, "rhel8.6.0", false); -+ -+static void ccw_machine_rhel850_instance_options(MachineState *machine) -+{ -+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 }; -+ -+ ccw_machine_rhel860_instance_options(machine); -+ -+ s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat); -+ -+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_NNPA); -+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2); -+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_BEAR_ENH); -+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_RDP); -+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAI); -+} -+ -+static void ccw_machine_rhel850_class_options(MachineClass *mc) -+{ -+ ccw_machine_rhel860_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_5, hw_compat_rhel_8_5_len); -+ mc->smp_props.prefer_sockets = true; -+} -+DEFINE_CCW_MACHINE(rhel850, "rhel8.5.0", false); -+ -+static void ccw_machine_rhel840_instance_options(MachineState *machine) -+{ -+ ccw_machine_rhel850_instance_options(machine); -+} -+ -+static void ccw_machine_rhel840_class_options(MachineClass *mc) -+{ -+ ccw_machine_rhel850_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_4, hw_compat_rhel_8_4_len); -+} -+DEFINE_CCW_MACHINE(rhel840, "rhel8.4.0", false); -+ -+static void ccw_machine_rhel820_instance_options(MachineState *machine) -+{ -+ ccw_machine_rhel840_instance_options(machine); -+} -+ -+static void ccw_machine_rhel820_class_options(MachineClass *mc) -+{ -+ ccw_machine_rhel840_class_options(mc); -+ mc->fixup_ram_size = s390_fixup_ram_size; -+ /* we did not publish a rhel8.3.0 machine */ -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_3, hw_compat_rhel_8_3_len); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_2, hw_compat_rhel_8_2_len); -+} -+DEFINE_CCW_MACHINE(rhel820, "rhel8.2.0", false); -+ -+static void ccw_machine_rhel760_instance_options(MachineState *machine) -+{ -+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 }; -+ -+ ccw_machine_rhel820_instance_options(machine); -+ -+ s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat); -+ -+ /* The multiple-epoch facility was not available with rhel7.6.0 on z14GA1 */ -+ s390_cpudef_featoff(14, 1, S390_FEAT_MULTIPLE_EPOCH); -+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_QSIE); -+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_QTOUE); -+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOE); -+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOUE); -+} -+ -+static void ccw_machine_rhel760_class_options(MachineClass *mc) -+{ -+ ccw_machine_rhel820_class_options(mc); -+ /* We never published the s390x version of RHEL-AV 8.0 and 8.1, so add this here */ -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len); -+ compat_props_add(mc->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len); -+} -+DEFINE_CCW_MACHINE(rhel760, "rhel7.6.0", false); - - static void ccw_machine_register_types(void) - { -diff --git a/include/hw/boards.h b/include/hw/boards.h -index c90a19b4d1..bf59275f18 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -470,4 +470,6 @@ extern const size_t hw_compat_rhel_8_0_len; - extern GlobalProperty hw_compat_rhel_7_6[]; - extern const size_t hw_compat_rhel_7_6_len; - -+extern const char *rhel_old_machine_deprecation; -+ - #endif --- -2.31.1 - diff --git a/extras/qemu/0010-Add-x86_64-machine-types.patch b/extras/qemu/0010-Add-x86_64-machine-types.patch deleted file mode 100644 index 7c48967..0000000 --- a/extras/qemu/0010-Add-x86_64-machine-types.patch +++ /dev/null @@ -1,714 +0,0 @@ -From 427a575ca57966bc72e1ebf218081da530d435d7 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 19 Oct 2018 13:10:31 +0200 -Subject: Add x86_64 machine types - -Adding changes to add RHEL machine types for x86_64 architecture. - -Signed-off-by: Miroslav Rezanina - -Rebase notes (6.1.0): -- Update qemu64 cpu spec - -Rebase notes (7.0.0): -- Reset alias for all machine-types except latest one - -Merged patches (6.1.0): -- 59c284ad3b x86: Add x86 rhel8.5 machine types -- a8868b42fe redhat: x86: Enable 'kvm-asyncpf-int' by default -- a3995e2eff Remove RHEL 7.0.0 machine type (only x86_64 changes) -- ad3190a79b Remove RHEL 7.1.0 machine type (only x86_64 changes) -- 84bbe15d4e Remove RHEL 7.2.0 machine type (only x86_64 changes) -- 0215eb3356 Remove RHEL 7.3.0 machine types (only x86_64 changes) -- af69d1ca6e Remove RHEL 7.4.0 machine types (only x86_64 changes) -- 8f7a74ab78 Remove RHEL 7.5.0 machine types (only x86_64 changes) - -Merged patches (7.0.0): -- eae7d8dd3c x86/rhel machine types: Add pc_rhel_8_5_compat -- 6762f56469 x86/rhel machine types: Wire compat into q35 and i440fx -- 5762101438 rhel machine types/x86: set prefer_sockets -- 9ba9ddc632 x86: Add q35 RHEL 8.6.0 machine type -- 6110d865e5 x86: Add q35 RHEL 9.0.0 machine type -- dcc64971bf RHEL: mark old machine types as deprecated (partialy) -- 6b396f182b RHEL: disable "seqpacket" for "vhost-vsock-device" in rhel8.6.0 ---- - hw/core/machine.c | 10 ++ - hw/i386/pc.c | 135 +++++++++++++++++++++- - hw/i386/pc_piix.c | 79 ++++++++++++- - hw/i386/pc_q35.c | 227 ++++++++++++++++++++++++++++++++++++- - hw/s390x/s390-virtio-ccw.c | 1 + - include/hw/boards.h | 5 + - include/hw/i386/pc.h | 24 ++++ - target/i386/kvm/kvm-cpu.c | 1 + - target/i386/kvm/kvm.c | 4 + - tests/qtest/pvpanic-test.c | 5 +- - 10 files changed, 484 insertions(+), 7 deletions(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 77202a3570..28989b6e7b 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -43,6 +43,16 @@ - const char *rhel_old_machine_deprecation = - "machine types for previous major releases are deprecated"; - -+GlobalProperty hw_compat_rhel_8_6[] = { -+ /* hw_compat_rhel_8_6 bz 2065589 */ -+ /* -+ * vhost-vsock device in RHEL 8 kernels doesn't support seqpacket, so -+ * we need do disable it downstream on the latest hw_compat_rhel_8. -+ */ -+ { "vhost-vsock-device", "seqpacket", "off" }, -+}; -+const size_t hw_compat_rhel_8_6_len = G_N_ELEMENTS(hw_compat_rhel_8_6); -+ - /* - * Mostly the same as hw_compat_6_0 and hw_compat_6_1 - */ -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index fd55fc725c..263d882af6 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -375,6 +375,137 @@ GlobalProperty pc_compat_1_4[] = { - }; - const size_t pc_compat_1_4_len = G_N_ELEMENTS(pc_compat_1_4); - -+/* This macro is for changes to properties that are RHEL specific, -+ * different to the current upstream and to be applied to the latest -+ * machine type. -+ */ -+GlobalProperty pc_rhel_compat[] = { -+ { TYPE_X86_CPU, "host-phys-bits", "on" }, -+ { TYPE_X86_CPU, "host-phys-bits-limit", "48" }, -+ { TYPE_X86_CPU, "vmx-entry-load-perf-global-ctrl", "off" }, -+ { TYPE_X86_CPU, "vmx-exit-load-perf-global-ctrl", "off" }, -+ /* bz 1508330 */ -+ { "vfio-pci", "x-no-geforce-quirks", "on" }, -+ /* bz 1941397 */ -+ { TYPE_X86_CPU, "kvm-asyncpf-int", "on" }, -+}; -+const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat); -+ -+GlobalProperty pc_rhel_8_5_compat[] = { -+ /* pc_rhel_8_5_compat from pc_compat_6_0 */ -+ { "qemu64" "-" TYPE_X86_CPU, "family", "6" }, -+ /* pc_rhel_8_5_compat from pc_compat_6_0 */ -+ { "qemu64" "-" TYPE_X86_CPU, "model", "6" }, -+ /* pc_rhel_8_5_compat from pc_compat_6_0 */ -+ { "qemu64" "-" TYPE_X86_CPU, "stepping", "3" }, -+ /* pc_rhel_8_5_compat from pc_compat_6_0 */ -+ { TYPE_X86_CPU, "x-vendor-cpuid-only", "off" }, -+ /* pc_rhel_8_5_compat from pc_compat_6_0 */ -+ { "ICH9-LPC", ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, "off" }, -+ -+ /* pc_rhel_8_5_compat from pc_compat_6_1 */ -+ { TYPE_X86_CPU, "hv-version-id-build", "0x1bbc" }, -+ /* pc_rhel_8_5_compat from pc_compat_6_1 */ -+ { TYPE_X86_CPU, "hv-version-id-major", "0x0006" }, -+ /* pc_rhel_8_5_compat from pc_compat_6_1 */ -+ { TYPE_X86_CPU, "hv-version-id-minor", "0x0001" }, -+}; -+const size_t pc_rhel_8_5_compat_len = G_N_ELEMENTS(pc_rhel_8_5_compat); -+ -+GlobalProperty pc_rhel_8_4_compat[] = { -+ /* pc_rhel_8_4_compat from pc_compat_5_2 */ -+ { "ICH9-LPC", "x-smi-cpu-hotunplug", "off" }, -+ { TYPE_X86_CPU, "kvm-asyncpf-int", "off" }, -+}; -+const size_t pc_rhel_8_4_compat_len = G_N_ELEMENTS(pc_rhel_8_4_compat); -+ -+GlobalProperty pc_rhel_8_3_compat[] = { -+ /* pc_rhel_8_3_compat from pc_compat_5_1 */ -+ { "ICH9-LPC", "x-smi-cpu-hotplug", "off" }, -+}; -+const size_t pc_rhel_8_3_compat_len = G_N_ELEMENTS(pc_rhel_8_3_compat); -+ -+GlobalProperty pc_rhel_8_2_compat[] = { -+ /* pc_rhel_8_2_compat from pc_compat_4_2 */ -+ { "mch", "smbase-smram", "off" }, -+}; -+const size_t pc_rhel_8_2_compat_len = G_N_ELEMENTS(pc_rhel_8_2_compat); -+ -+/* pc_rhel_8_1_compat is empty since pc_4_1_compat is */ -+GlobalProperty pc_rhel_8_1_compat[] = { }; -+const size_t pc_rhel_8_1_compat_len = G_N_ELEMENTS(pc_rhel_8_1_compat); -+ -+GlobalProperty pc_rhel_8_0_compat[] = { -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "intel-iommu", "dma-drain", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "Opteron_G4" "-" TYPE_X86_CPU, "rdtscp", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "Opteron_G4" "-" TYPE_X86_CPU, "npt", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "Opteron_G4" "-" TYPE_X86_CPU, "nrip-save", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "Opteron_G5" "-" TYPE_X86_CPU, "rdtscp", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "Opteron_G5" "-" TYPE_X86_CPU, "npt", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "Opteron_G5" "-" TYPE_X86_CPU, "nrip-save", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "EPYC" "-" TYPE_X86_CPU, "npt", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "EPYC" "-" TYPE_X86_CPU, "nrip-save", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "EPYC-IBPB" "-" TYPE_X86_CPU, "npt", "off" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "EPYC-IBPB" "-" TYPE_X86_CPU, "nrip-save", "off" }, -+ /** The mpx=on entries from pc_compat_3_1 are in pc_rhel_7_6_compat **/ -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { "Cascadelake-Server" "-" TYPE_X86_CPU, "stepping", "5" }, -+ /* pc_rhel_8_0_compat from pc_compat_3_1 */ -+ { TYPE_X86_CPU, "x-intel-pt-auto-level", "off" }, -+}; -+const size_t pc_rhel_8_0_compat_len = G_N_ELEMENTS(pc_rhel_8_0_compat); -+ -+/* Similar to PC_COMPAT_3_0 + PC_COMPAT_2_12, but: -+ * all of the 2_12 stuff was already in 7.6 from bz 1481253 -+ * x-migrate-smi-count comes from PC_COMPAT_2_11 but -+ * is really tied to kernel version so keep it off on 7.x -+ * machine types irrespective of host. -+ */ -+GlobalProperty pc_rhel_7_6_compat[] = { -+ /* pc_rhel_7_6_compat from pc_compat_3_0 */ -+ { TYPE_X86_CPU, "x-hv-synic-kvm-only", "on" }, -+ /* pc_rhel_7_6_compat from pc_compat_3_0 */ -+ { "Skylake-Server" "-" TYPE_X86_CPU, "pku", "off" }, -+ /* pc_rhel_7_6_compat from pc_compat_3_0 */ -+ { "Skylake-Server-IBRS" "-" TYPE_X86_CPU, "pku", "off" }, -+ /* pc_rhel_7_6_compat from pc_compat_2_11 */ -+ { TYPE_X86_CPU, "x-migrate-smi-count", "off" }, -+ /* pc_rhel_7_6_compat from pc_compat_2_11 */ -+ { "Skylake-Client" "-" TYPE_X86_CPU, "mpx", "on" }, -+ /* pc_rhel_7_6_compat from pc_compat_2_11 */ -+ { "Skylake-Client-IBRS" "-" TYPE_X86_CPU, "mpx", "on" }, -+ /* pc_rhel_7_6_compat from pc_compat_2_11 */ -+ { "Skylake-Server" "-" TYPE_X86_CPU, "mpx", "on" }, -+ /* pc_rhel_7_6_compat from pc_compat_2_11 */ -+ { "Skylake-Server-IBRS" "-" TYPE_X86_CPU, "mpx", "on" }, -+ /* pc_rhel_7_6_compat from pc_compat_2_11 */ -+ { "Cascadelake-Server" "-" TYPE_X86_CPU, "mpx", "on" }, -+ /* pc_rhel_7_6_compat from pc_compat_2_11 */ -+ { "Icelake-Client" "-" TYPE_X86_CPU, "mpx", "on" }, -+ /* pc_rhel_7_6_compat from pc_compat_2_11 */ -+ { "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" }, -+}; -+const size_t pc_rhel_7_6_compat_len = G_N_ELEMENTS(pc_rhel_7_6_compat); -+ -+/* -+ * The PC_RHEL_*_COMPAT serve the same purpose for RHEL-7 machine -+ * types as the PC_COMPAT_* do for upstream types. -+ * PC_RHEL_7_*_COMPAT apply both to i440fx and q35 types. -+ */ -+ - GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled) - { - GSIState *s; -@@ -1738,6 +1869,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - pcmc->pvh_enabled = true; - pcmc->kvmclock_create_always = true; - assert(!mc->get_hotplug_handler); -+ mc->async_pf_vmexit_disable = false; - mc->get_hotplug_handler = pc_get_hotplug_handler; - mc->hotplug_allowed = pc_hotplug_allowed; - mc->cpu_index_to_instance_props = x86_cpu_index_to_props; -@@ -1748,7 +1880,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - mc->has_hotpluggable_cpus = true; - mc->default_boot_order = "cad"; - mc->block_default_type = IF_IDE; -- mc->max_cpus = 255; -+ /* 240: max CPU count for RHEL */ -+ mc->max_cpus = 240; - mc->reset = pc_machine_reset; - mc->wakeup = pc_machine_wakeup; - hc->pre_plug = pc_machine_device_pre_plug_cb; -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index c797e98312..0cacc0d623 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -50,6 +50,7 @@ - #include "qapi/error.h" - #include "qemu/error-report.h" - #include "sysemu/xen.h" -+#include "migration/migration.h" - #ifdef CONFIG_XEN - #include - #include "hw/xen/xen_pt.h" -@@ -174,8 +175,8 @@ static void pc_init1(MachineState *machine, - if (pcmc->smbios_defaults) { - MachineClass *mc = MACHINE_GET_CLASS(machine); - /* These values are guest ABI, do not change */ -- smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)", -- mc->name, pcmc->smbios_legacy_mode, -+ smbios_set_defaults("Red Hat", "KVM", -+ mc->desc, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, - pcmc->smbios_stream_product, - pcmc->smbios_stream_version, -@@ -314,6 +315,7 @@ static void pc_init1(MachineState *machine, - * hw_compat_*, pc_compat_*, or * pc_*_machine_options(). - */ - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void pc_compat_2_3_fn(MachineState *machine) - { - X86MachineState *x86ms = X86_MACHINE(machine); -@@ -967,3 +969,76 @@ static void xenfv_3_1_machine_options(MachineClass *m) - DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init, - xenfv_3_1_machine_options); - #endif -+#endif /* Disabled for Red Hat Enterprise Linux */ -+ -+/* Red Hat Enterprise Linux machine types */ -+ -+/* Options for the latest rhel7 machine type */ -+static void pc_machine_rhel7_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ m->family = "pc_piix_Y"; -+ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off"; -+ pcmc->default_nic_model = "e1000"; -+ pcmc->pci_root_uid = 0; -+ m->default_display = "std"; -+ m->no_parallel = 1; -+ m->numa_mem_supported = true; -+ m->auto_enable_numa_with_memdev = false; -+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); -+ compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len); -+ m->alias = "pc"; -+ m->is_default = 1; -+ m->smp_props.prefer_sockets = true; -+} -+ -+static void pc_init_rhel760(MachineState *machine) -+{ -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel760_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_machine_rhel7_options(m); -+ m->desc = "RHEL 7.6.0 PC (i440FX + PIIX, 1996)"; -+ m->async_pf_vmexit_disable = true; -+ m->smbus_no_migration_support = true; -+ -+ /* All RHEL machines for prior major releases are deprecated */ -+ m->deprecation_reason = rhel_old_machine_deprecation; -+ -+ pcmc->pvh_enabled = false; -+ pcmc->default_cpu_version = CPU_VERSION_LEGACY; -+ pcmc->kvmclock_create_always = false; -+ /* From pc_i440fx_5_1_machine_options() */ -+ pcmc->pci_root_uid = 1; -+ compat_props_add(m->compat_props, hw_compat_rhel_8_6, -+ hw_compat_rhel_8_6_len); -+ compat_props_add(m->compat_props, hw_compat_rhel_8_5, -+ hw_compat_rhel_8_5_len); -+ compat_props_add(m->compat_props, pc_rhel_8_5_compat, -+ pc_rhel_8_5_compat_len); -+ compat_props_add(m->compat_props, hw_compat_rhel_8_4, -+ hw_compat_rhel_8_4_len); -+ compat_props_add(m->compat_props, pc_rhel_8_4_compat, -+ pc_rhel_8_4_compat_len); -+ compat_props_add(m->compat_props, hw_compat_rhel_8_3, -+ hw_compat_rhel_8_3_len); -+ compat_props_add(m->compat_props, pc_rhel_8_3_compat, -+ pc_rhel_8_3_compat_len); -+ compat_props_add(m->compat_props, hw_compat_rhel_8_2, -+ hw_compat_rhel_8_2_len); -+ compat_props_add(m->compat_props, pc_rhel_8_2_compat, -+ pc_rhel_8_2_compat_len); -+ compat_props_add(m->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len); -+ compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len); -+ compat_props_add(m->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len); -+ compat_props_add(m->compat_props, pc_rhel_8_0_compat, pc_rhel_8_0_compat_len); -+ compat_props_add(m->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len); -+ compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len); -+} -+ -+DEFINE_PC_MACHINE(rhel760, "pc-i440fx-rhel7.6.0", pc_init_rhel760, -+ pc_machine_rhel760_options); -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index b695f88c45..157160e069 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -197,8 +197,8 @@ static void pc_q35_init(MachineState *machine) - - if (pcmc->smbios_defaults) { - /* These values are guest ABI, do not change */ -- smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)", -- mc->name, pcmc->smbios_legacy_mode, -+ smbios_set_defaults("Red Hat", "KVM", -+ mc->desc, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, - pcmc->smbios_stream_product, - pcmc->smbios_stream_version, -@@ -342,6 +342,7 @@ static void pc_q35_init(MachineState *machine) - DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn) - - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void pc_q35_machine_options(MachineClass *m) - { - PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -@@ -631,3 +632,225 @@ static void pc_q35_2_4_machine_options(MachineClass *m) - - DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL, - pc_q35_2_4_machine_options); -+#endif /* Disabled for Red Hat Enterprise Linux */ -+ -+/* Red Hat Enterprise Linux machine types */ -+ -+/* Options for the latest rhel q35 machine type */ -+static void pc_q35_machine_rhel_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pcmc->default_nic_model = "e1000e"; -+ pcmc->pci_root_uid = 0; -+ m->family = "pc_q35_Z"; -+ m->units_per_default_bus = 1; -+ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off"; -+ m->default_display = "std"; -+ m->no_floppy = 1; -+ m->no_parallel = 1; -+ pcmc->default_cpu_version = 1; -+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE); -+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE); -+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); -+ m->alias = "q35"; -+ m->max_cpus = 710; -+ compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len); -+} -+ -+static void pc_q35_init_rhel900(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel900_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel_options(m); -+ m->desc = "RHEL-9.0.0 PC (Q35 + ICH9, 2009)"; -+ pcmc->smbios_stream_product = "RHEL"; -+ pcmc->smbios_stream_version = "9.0.0"; -+} -+ -+DEFINE_PC_MACHINE(q35_rhel900, "pc-q35-rhel9.0.0", pc_q35_init_rhel900, -+ pc_q35_machine_rhel900_options); -+ -+static void pc_q35_init_rhel860(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel860_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel900_options(m); -+ m->desc = "RHEL-8.6.0 PC (Q35 + ICH9, 2009)"; -+ m->alias = NULL; -+ -+ /* All RHEL machines for prior major releases are deprecated */ -+ m->deprecation_reason = rhel_old_machine_deprecation; -+ -+ pcmc->smbios_stream_product = "RHEL-AV"; -+ pcmc->smbios_stream_version = "8.6.0"; -+ compat_props_add(m->compat_props, hw_compat_rhel_8_6, -+ hw_compat_rhel_8_6_len); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel860, "pc-q35-rhel8.6.0", pc_q35_init_rhel860, -+ pc_q35_machine_rhel860_options); -+ -+ -+static void pc_q35_init_rhel850(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel850_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel860_options(m); -+ m->desc = "RHEL-8.5.0 PC (Q35 + ICH9, 2009)"; -+ m->alias = NULL; -+ pcmc->smbios_stream_product = "RHEL-AV"; -+ pcmc->smbios_stream_version = "8.5.0"; -+ compat_props_add(m->compat_props, hw_compat_rhel_8_5, -+ hw_compat_rhel_8_5_len); -+ compat_props_add(m->compat_props, pc_rhel_8_5_compat, -+ pc_rhel_8_5_compat_len); -+ m->smp_props.prefer_sockets = true; -+} -+ -+DEFINE_PC_MACHINE(q35_rhel850, "pc-q35-rhel8.5.0", pc_q35_init_rhel850, -+ pc_q35_machine_rhel850_options); -+ -+ -+static void pc_q35_init_rhel840(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel840_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel850_options(m); -+ m->desc = "RHEL-8.4.0 PC (Q35 + ICH9, 2009)"; -+ m->alias = NULL; -+ pcmc->smbios_stream_product = "RHEL-AV"; -+ pcmc->smbios_stream_version = "8.4.0"; -+ compat_props_add(m->compat_props, hw_compat_rhel_8_4, -+ hw_compat_rhel_8_4_len); -+ compat_props_add(m->compat_props, pc_rhel_8_4_compat, -+ pc_rhel_8_4_compat_len); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel840, "pc-q35-rhel8.4.0", pc_q35_init_rhel840, -+ pc_q35_machine_rhel840_options); -+ -+ -+static void pc_q35_init_rhel830(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel830_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel840_options(m); -+ m->desc = "RHEL-8.3.0 PC (Q35 + ICH9, 2009)"; -+ m->alias = NULL; -+ pcmc->smbios_stream_product = "RHEL-AV"; -+ pcmc->smbios_stream_version = "8.3.0"; -+ compat_props_add(m->compat_props, hw_compat_rhel_8_3, -+ hw_compat_rhel_8_3_len); -+ compat_props_add(m->compat_props, pc_rhel_8_3_compat, -+ pc_rhel_8_3_compat_len); -+ /* From pc_q35_5_1_machine_options() */ -+ pcmc->kvmclock_create_always = false; -+ /* From pc_q35_5_1_machine_options() */ -+ pcmc->pci_root_uid = 1; -+} -+ -+DEFINE_PC_MACHINE(q35_rhel830, "pc-q35-rhel8.3.0", pc_q35_init_rhel830, -+ pc_q35_machine_rhel830_options); -+ -+static void pc_q35_init_rhel820(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel820_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel830_options(m); -+ m->desc = "RHEL-8.2.0 PC (Q35 + ICH9, 2009)"; -+ m->alias = NULL; -+ m->numa_mem_supported = true; -+ m->auto_enable_numa_with_memdev = false; -+ pcmc->smbios_stream_product = "RHEL-AV"; -+ pcmc->smbios_stream_version = "8.2.0"; -+ compat_props_add(m->compat_props, hw_compat_rhel_8_2, -+ hw_compat_rhel_8_2_len); -+ compat_props_add(m->compat_props, pc_rhel_8_2_compat, -+ pc_rhel_8_2_compat_len); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel820, "pc-q35-rhel8.2.0", pc_q35_init_rhel820, -+ pc_q35_machine_rhel820_options); -+ -+static void pc_q35_init_rhel810(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel810_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel820_options(m); -+ m->desc = "RHEL-8.1.0 PC (Q35 + ICH9, 2009)"; -+ m->alias = NULL; -+ pcmc->smbios_stream_product = NULL; -+ pcmc->smbios_stream_version = NULL; -+ compat_props_add(m->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len); -+ compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel810, "pc-q35-rhel8.1.0", pc_q35_init_rhel810, -+ pc_q35_machine_rhel810_options); -+ -+static void pc_q35_init_rhel800(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel800_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel810_options(m); -+ m->desc = "RHEL-8.0.0 PC (Q35 + ICH9, 2009)"; -+ m->smbus_no_migration_support = true; -+ m->alias = NULL; -+ pcmc->pvh_enabled = false; -+ pcmc->default_cpu_version = CPU_VERSION_LEGACY; -+ compat_props_add(m->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len); -+ compat_props_add(m->compat_props, pc_rhel_8_0_compat, pc_rhel_8_0_compat_len); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel800, "pc-q35-rhel8.0.0", pc_q35_init_rhel800, -+ pc_q35_machine_rhel800_options); -+ -+static void pc_q35_init_rhel760(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel760_options(MachineClass *m) -+{ -+ pc_q35_machine_rhel800_options(m); -+ m->alias = NULL; -+ m->desc = "RHEL-7.6.0 PC (Q35 + ICH9, 2009)"; -+ m->async_pf_vmexit_disable = true; -+ compat_props_add(m->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len); -+ compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel760, "pc-q35-rhel7.6.0", pc_q35_init_rhel760, -+ pc_q35_machine_rhel760_options); -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index ec4176a1e0..465a2a09d2 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -1136,6 +1136,7 @@ static void ccw_machine_rhel860_instance_options(MachineState *machine) - static void ccw_machine_rhel860_class_options(MachineClass *mc) - { - ccw_machine_rhel900_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_rhel_8_6, hw_compat_rhel_8_6_len); - - /* All RHEL machines for prior major releases are deprecated */ - mc->deprecation_reason = rhel_old_machine_deprecation; -diff --git a/include/hw/boards.h b/include/hw/boards.h -index bf59275f18..d1555665df 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -266,6 +266,8 @@ struct MachineClass { - strList *allowed_dynamic_sysbus_devices; - bool auto_enable_numa_with_memhp; - bool auto_enable_numa_with_memdev; -+ /* RHEL only */ -+ bool async_pf_vmexit_disable; - bool ignore_boot_device_suffixes; - bool smbus_no_migration_support; - bool nvdimm_supported; -@@ -449,6 +451,9 @@ extern const size_t hw_compat_2_2_len; - extern GlobalProperty hw_compat_2_1[]; - extern const size_t hw_compat_2_1_len; - -+extern GlobalProperty hw_compat_rhel_8_6[]; -+extern const size_t hw_compat_rhel_8_6_len; -+ - extern GlobalProperty hw_compat_rhel_8_5[]; - extern const size_t hw_compat_rhel_8_5_len; - -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 91331059d9..419a6ec24b 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -289,6 +289,30 @@ extern const size_t pc_compat_1_5_len; - extern GlobalProperty pc_compat_1_4[]; - extern const size_t pc_compat_1_4_len; - -+extern GlobalProperty pc_rhel_compat[]; -+extern const size_t pc_rhel_compat_len; -+ -+extern GlobalProperty pc_rhel_8_5_compat[]; -+extern const size_t pc_rhel_8_5_compat_len; -+ -+extern GlobalProperty pc_rhel_8_4_compat[]; -+extern const size_t pc_rhel_8_4_compat_len; -+ -+extern GlobalProperty pc_rhel_8_3_compat[]; -+extern const size_t pc_rhel_8_3_compat_len; -+ -+extern GlobalProperty pc_rhel_8_2_compat[]; -+extern const size_t pc_rhel_8_2_compat_len; -+ -+extern GlobalProperty pc_rhel_8_1_compat[]; -+extern const size_t pc_rhel_8_1_compat_len; -+ -+extern GlobalProperty pc_rhel_8_0_compat[]; -+extern const size_t pc_rhel_8_0_compat_len; -+ -+extern GlobalProperty pc_rhel_7_6_compat[]; -+extern const size_t pc_rhel_7_6_compat_len; -+ - /* Helper for setting model-id for CPU models that changed model-id - * depending on QEMU versions up to QEMU 2.4. - */ -diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c -index 5eb955ce9a..74c1396a93 100644 ---- a/target/i386/kvm/kvm-cpu.c -+++ b/target/i386/kvm/kvm-cpu.c -@@ -137,6 +137,7 @@ static PropValue kvm_default_props[] = { - { "acpi", "off" }, - { "monitor", "off" }, - { "svm", "off" }, -+ { "kvm-pv-unhalt", "on" }, - { NULL, NULL }, - }; - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 9cf8e03669..6d1e009443 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -3488,6 +3488,7 @@ static int kvm_get_msrs(X86CPU *cpu) - struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries; - int ret, i; - uint64_t mtrr_top_bits; -+ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); - - kvm_msr_buf_reset(cpu); - -@@ -3822,6 +3823,9 @@ static int kvm_get_msrs(X86CPU *cpu) - break; - case MSR_KVM_ASYNC_PF_EN: - env->async_pf_en_msr = msrs[i].data; -+ if (mc->async_pf_vmexit_disable) { -+ env->async_pf_en_msr &= ~(1ULL << 2); -+ } - break; - case MSR_KVM_ASYNC_PF_INT: - env->async_pf_int_msr = msrs[i].data; -diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c -index 6dcad2db49..580c2c43d2 100644 ---- a/tests/qtest/pvpanic-test.c -+++ b/tests/qtest/pvpanic-test.c -@@ -17,7 +17,7 @@ static void test_panic_nopause(void) - QDict *response, *data; - QTestState *qts; - -- qts = qtest_init("-device pvpanic -action panic=none"); -+ qts = qtest_init("-M q35 -device pvpanic -action panic=none"); - - val = qtest_inb(qts, 0x505); - g_assert_cmpuint(val, ==, 3); -@@ -40,7 +40,8 @@ static void test_panic(void) - QDict *response, *data; - QTestState *qts; - -- qts = qtest_init("-device pvpanic -action panic=pause"); -+ /* RHEL: Use q35 */ -+ qts = qtest_init("-M q35 -device pvpanic -action panic=pause"); - - val = qtest_inb(qts, 0x505); - g_assert_cmpuint(val, ==, 3); --- -2.31.1 - diff --git a/extras/qemu/0011-Enable-make-check.patch b/extras/qemu/0011-Enable-make-check.patch deleted file mode 100644 index 832b38d..0000000 --- a/extras/qemu/0011-Enable-make-check.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 5e419e5e0a721bdbbfa6d9b82c8be5c5b3d26a01 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Wed, 2 Sep 2020 09:39:41 +0200 -Subject: Enable make check - -Fixing tests after device disabling and machine types changes and enabling -make check run during build. - -Signed-off-by: Miroslav Rezanina ---- -Rebase changes (6.1.0): -- removed unnecessary test changes - -Rebase changes (6.2.0): -- new way of disabling bios-table-test - -Rebase changes (7.0.0): -- Disable testing virtio-iommu-pci -- Rename default_bus_bypass_iommu property to default-bus-bypass-iommu -- Disable qtest-bios-table for aarch64 -- Removed redhat chunks for boot-serial-test.c, cdrom-test.c and cpu-plug-test.c qtests -- Do not disable boot-order-test, prom-env-test and boot-serial-test qtests -- Use rhel machine type for new intel hda qtest -- Remove unnecessary changes in iotest 051 -- Remove changes in bios-tables-test.c and prom-env-test.c qtests - -Merged patches (6.1.0): -- 2f129df7d3 redhat: Enable the 'test-block-iothread' test again ---- - .distro/qemu-kvm.spec.template | 5 ++--- - tests/qtest/fuzz-e1000e-test.c | 2 +- - tests/qtest/fuzz-virtio-scsi-test.c | 2 +- - tests/qtest/intel-hda-test.c | 2 +- - tests/qtest/libqos/meson.build | 2 +- - tests/qtest/lpc-ich9-test.c | 2 +- - tests/qtest/meson.build | 4 ---- - tests/qtest/usb-hcd-xhci-test.c | 4 ++++ - tests/qtest/virtio-net-failover.c | 1 + - 9 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/tests/qtest/fuzz-e1000e-test.c b/tests/qtest/fuzz-e1000e-test.c -index 66229e6096..947fba73b7 100644 ---- a/tests/qtest/fuzz-e1000e-test.c -+++ b/tests/qtest/fuzz-e1000e-test.c -@@ -17,7 +17,7 @@ static void test_lp1879531_eth_get_rss_ex_dst_addr(void) - { - QTestState *s; - -- s = qtest_init("-nographic -monitor none -serial none -M pc-q35-5.0"); -+ s = qtest_init("-nographic -monitor none -serial none -M pc-q35-rhel8.4.0"); - - qtest_outl(s, 0xcf8, 0x80001010); - qtest_outl(s, 0xcfc, 0xe1020000); -diff --git a/tests/qtest/fuzz-virtio-scsi-test.c b/tests/qtest/fuzz-virtio-scsi-test.c -index aaf6d10e18..43727d62ac 100644 ---- a/tests/qtest/fuzz-virtio-scsi-test.c -+++ b/tests/qtest/fuzz-virtio-scsi-test.c -@@ -19,7 +19,7 @@ static void test_mmio_oob_from_memory_region_cache(void) - { - QTestState *s; - -- s = qtest_init("-M pc-q35-5.2 -display none -m 512M " -+ s = qtest_init("-M pc-q35-rhel8.4.0 -display none -m 512M " - "-device virtio-scsi,num_queues=8,addr=03.0 "); - - qtest_outl(s, 0xcf8, 0x80001811); -diff --git a/tests/qtest/intel-hda-test.c b/tests/qtest/intel-hda-test.c -index a58c98e4d1..c8387e39ce 100644 ---- a/tests/qtest/intel-hda-test.c -+++ b/tests/qtest/intel-hda-test.c -@@ -38,7 +38,7 @@ static void test_issue542_ich6(void) - { - QTestState *s; - -- s = qtest_init("-nographic -nodefaults -M pc-q35-6.2 " -+ s = qtest_init("-nographic -nodefaults -M pc-q35-rhel9.0.0 " - "-device intel-hda,id=" HDA_ID CODEC_DEVICES); - - qtest_outl(s, 0xcf8, 0x80000804); -diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build -index e988d15791..46f7dcb81a 100644 ---- a/tests/qtest/libqos/meson.build -+++ b/tests/qtest/libqos/meson.build -@@ -41,7 +41,7 @@ libqos_srcs = files('../libqtest.c', - 'virtio-rng.c', - 'virtio-scsi.c', - 'virtio-serial.c', -- 'virtio-iommu.c', -+# 'virtio-iommu.c', - - # qgraph machines: - 'aarch64-xlnx-zcu102-machine.c', -diff --git a/tests/qtest/lpc-ich9-test.c b/tests/qtest/lpc-ich9-test.c -index fe0bef9980..7a9d51579b 100644 ---- a/tests/qtest/lpc-ich9-test.c -+++ b/tests/qtest/lpc-ich9-test.c -@@ -15,7 +15,7 @@ static void test_lp1878642_pci_bus_get_irq_level_assert(void) - { - QTestState *s; - -- s = qtest_init("-M pc-q35-5.0 " -+ s = qtest_init("-M pc-q35-rhel8.4.0 " - "-nographic -monitor none -serial none"); - - qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */ -diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build -index d25f82bb5a..67cd32def1 100644 ---- a/tests/qtest/meson.build -+++ b/tests/qtest/meson.build -@@ -73,7 +73,6 @@ qtests_i386 = \ - config_all_devices.has_key('CONFIG_Q35') and \ - config_all_devices.has_key('CONFIG_VIRTIO_PCI') and \ - slirp.found() ? ['virtio-net-failover'] : []) + \ -- (unpack_edk2_blobs ? ['bios-tables-test'] : []) + \ - qtests_pci + \ - ['fdc-test', - 'ide-test', -@@ -86,7 +85,6 @@ qtests_i386 = \ - 'drive_del-test', - 'tco-test', - 'cpu-plug-test', -- 'q35-test', - 'vmgenid-test', - 'migration-test', - 'test-x86-cpuid-compat', -@@ -216,7 +214,6 @@ qtests_arm = \ - - # TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional - qtests_aarch64 = \ -- (cpu != 'arm' and unpack_edk2_blobs ? ['bios-tables-test'] : []) + \ - (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-test'] : []) + \ - (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-swtpm-test'] : []) + \ - (config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \ -@@ -231,7 +228,6 @@ qtests_s390x = \ - (config_host.has_key('CONFIG_POSIX') ? ['test-filter-redirector'] : []) + \ - ['boot-serial-test', - 'drive_del-test', -- 'device-plug-test', - 'virtio-ccw-test', - 'cpu-plug-test', - 'migration-test'] -diff --git a/tests/qtest/usb-hcd-xhci-test.c b/tests/qtest/usb-hcd-xhci-test.c -index 10ef9d2a91..3855873050 100644 ---- a/tests/qtest/usb-hcd-xhci-test.c -+++ b/tests/qtest/usb-hcd-xhci-test.c -@@ -21,6 +21,7 @@ static void test_xhci_hotplug(void) - usb_test_hotplug(global_qtest, "xhci", "1", NULL); - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void test_usb_uas_hotplug(void) - { - QTestState *qts = global_qtest; -@@ -36,6 +37,7 @@ static void test_usb_uas_hotplug(void) - qtest_qmp_device_del(qts, "scsihd"); - qtest_qmp_device_del(qts, "uas"); - } -+#endif - - static void test_usb_ccid_hotplug(void) - { -@@ -56,7 +58,9 @@ int main(int argc, char **argv) - - qtest_add_func("/xhci/pci/init", test_xhci_init); - qtest_add_func("/xhci/pci/hotplug", test_xhci_hotplug); -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug); -+#endif - qtest_add_func("/xhci/pci/hotplug/usb-ccid", test_usb_ccid_hotplug); - - qtest_start("-device nec-usb-xhci,id=xhci" -diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c -index 78811f1c92..44de8af00c 100644 ---- a/tests/qtest/virtio-net-failover.c -+++ b/tests/qtest/virtio-net-failover.c -@@ -25,6 +25,7 @@ - #define PCI_SEL_BASE 0x0010 - - #define BASE_MACHINE "-M q35 -nodefaults " \ -+ "-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=on " \ - "-device pcie-root-port,id=root0,addr=0x1,bus=pcie.0,chassis=1 " \ - "-device pcie-root-port,id=root1,addr=0x2,bus=pcie.0,chassis=2 " - --- -2.31.1 - diff --git a/extras/qemu/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch b/extras/qemu/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch deleted file mode 100644 index c9e42b2..0000000 --- a/extras/qemu/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch +++ /dev/null @@ -1,104 +0,0 @@ -From c358fd4c224a9c3f64b4a8fff34cc6b1dc201fa0 Mon Sep 17 00:00:00 2001 -From: Bandan Das -Date: Tue, 3 Dec 2013 20:05:13 +0100 -Subject: vfio: cap number of devices that can be assigned - -RH-Author: Bandan Das -Message-id: <1386101113-31560-3-git-send-email-bsd@redhat.com> -Patchwork-id: 55984 -O-Subject: [PATCH RHEL7 qemu-kvm v2 2/2] vfio: cap number of devices that can be assigned -Bugzilla: 678368 -RH-Acked-by: Alex Williamson -RH-Acked-by: Marcelo Tosatti -RH-Acked-by: Michael S. Tsirkin - -Go through all groups to get count of total number of devices -active to enforce limit - -Reasoning from Alex for the limit(32) - Assuming 3 slots per -device, with 125 slots (number of memory slots for RHEL 7), -we can support almost 40 devices and still have few slots left -for other uses. Stepping down a bit, the number 32 arbitrarily -matches the number of slots on a PCI bus and is also a nice power -of two. - -Count of slots increased to 509 later so we could increase limit -to 64 as some usecases require more than 32 devices. - -Signed-off-by: Bandan Das ---- - hw/vfio/pci.c | 29 ++++++++++++++++++++++++++++- - hw/vfio/pci.h | 1 + - 2 files changed, 29 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 67a183f17b..1e20f9fd59 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -45,6 +45,9 @@ - - #define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug" - -+/* RHEL only: Set once for the first assigned dev */ -+static uint16_t device_limit; -+ - static void vfio_disable_interrupts(VFIOPCIDevice *vdev); - static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); - -@@ -2810,9 +2813,30 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - ssize_t len; - struct stat st; - int groupid; -- int i, ret; -+ int ret, i = 0; - bool is_mdev; - -+ if (device_limit && device_limit != vdev->assigned_device_limit) { -+ error_setg(errp, "Assigned device limit has been redefined. " -+ "Old:%d, New:%d", -+ device_limit, vdev->assigned_device_limit); -+ return; -+ } else { -+ device_limit = vdev->assigned_device_limit; -+ } -+ -+ QLIST_FOREACH(group, &vfio_group_list, next) { -+ QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { -+ i++; -+ } -+ } -+ -+ if (i >= vdev->assigned_device_limit) { -+ error_setg(errp, "Maximum supported vfio devices (%d) " -+ "already attached", vdev->assigned_device_limit); -+ return; -+ } -+ - if (!vdev->vbasedev.sysfsdev) { - if (!(~vdev->host.domain || ~vdev->host.bus || - ~vdev->host.slot || ~vdev->host.function)) { -@@ -3249,6 +3273,9 @@ static Property vfio_pci_dev_properties[] = { - DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false), - DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice, - no_geforce_quirks, false), -+ /* RHEL only */ -+ DEFINE_PROP_UINT16("x-assigned-device-limit", VFIOPCIDevice, -+ assigned_device_limit, 64), - DEFINE_PROP_BOOL("x-no-kvm-ioeventfd", VFIOPCIDevice, no_kvm_ioeventfd, - false), - DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd, -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index 64777516d1..e0fe6ca97e 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -139,6 +139,7 @@ struct VFIOPCIDevice { - EventNotifier err_notifier; - EventNotifier req_notifier; - int (*resetfn)(struct VFIOPCIDevice *); -+ uint16_t assigned_device_limit; - uint32_t vendor_id; - uint32_t device_id; - uint32_t sub_vendor_id; --- -2.31.1 - diff --git a/extras/qemu/0013-Add-support-statement-to-help-output.patch b/extras/qemu/0013-Add-support-statement-to-help-output.patch deleted file mode 100644 index 4826ea4..0000000 --- a/extras/qemu/0013-Add-support-statement-to-help-output.patch +++ /dev/null @@ -1,55 +0,0 @@ -From ba0c7a5f6b9a1f75666db6b3b795ddf03695dc26 Mon Sep 17 00:00:00 2001 -From: Eduardo Habkost -Date: Wed, 4 Dec 2013 18:53:17 +0100 -Subject: Add support statement to -help output - -RH-Author: Eduardo Habkost -Message-id: <1386183197-27761-1-git-send-email-ehabkost@redhat.com> -Patchwork-id: 55994 -O-Subject: [qemu-kvm RHEL7 PATCH] Add support statement to -help output -Bugzilla: 972773 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: knoel@redhat.com -RH-Acked-by: Paolo Bonzini - -Add support statement to -help output, reporting direct qemu-kvm usage -as unsupported by Red Hat, and advising users to use libvirt instead. - -Signed-off-by: Eduardo Habkost ---- - softmmu/vl.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/softmmu/vl.c b/softmmu/vl.c -index 6f646531a0..9d5dab43d2 100644 ---- a/softmmu/vl.c -+++ b/softmmu/vl.c -@@ -831,9 +831,17 @@ static void version(void) - QEMU_COPYRIGHT "\n"); - } - -+static void print_rh_warning(void) -+{ -+ printf("\nWARNING: Direct use of qemu-kvm from the command line is not supported by Red Hat.\n" -+ "WARNING: Use libvirt as the stable management interface.\n" -+ "WARNING: Some command line options listed here may not be available in future releases.\n\n"); -+} -+ - static void help(int exitcode) - { - version(); -+ print_rh_warning(); - printf("usage: %s [options] [disk_image]\n\n" - "'disk_image' is a raw hard disk image for IDE hard disk 0\n\n", - g_get_prgname()); -@@ -859,6 +867,7 @@ static void help(int exitcode) - "\n" - QEMU_HELP_BOTTOM "\n"); - -+ print_rh_warning(); - exit(exitcode); - } - --- -2.31.1 - diff --git a/extras/qemu/0014-globally-limit-the-maximum-number-of-CPUs.patch b/extras/qemu/0014-globally-limit-the-maximum-number-of-CPUs.patch deleted file mode 100644 index 6764a84..0000000 --- a/extras/qemu/0014-globally-limit-the-maximum-number-of-CPUs.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 9ebfd2f6cfa8e79c92e58fd169f90cc768fb865a Mon Sep 17 00:00:00 2001 -From: Andrew Jones -Date: Tue, 21 Jan 2014 10:46:52 +0100 -Subject: globally limit the maximum number of CPUs - -We now globally limit the number of VCPUs. -Especially, there is no way one can specify more than -max_cpus VCPUs for a VM. - -This allows us the restore the ppc max_cpus limitation to the upstream -default and minimize the ppc hack in kvm-all.c. - -Signed-off-by: David Hildenbrand -Signed-off-by: Miroslav Rezanina -Signed-off-by: Danilo Cesar Lemes de Paula ---- - accel/kvm/kvm-all.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 5f1377ca04..fdf0e4d429 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2430,6 +2430,18 @@ static int kvm_init(MachineState *ms) - soft_vcpus_limit = kvm_recommended_vcpus(s); - hard_vcpus_limit = kvm_max_vcpus(s); - -+#ifdef HOST_PPC64 -+ /* -+ * On POWER, the kernel advertises a soft limit based on the -+ * number of CPU threads on the host. We want to allow exceeding -+ * this for testing purposes, so we don't want to set hard limit -+ * to soft limit as on x86. -+ */ -+#else -+ /* RHEL doesn't support nr_vcpus > soft_vcpus_limit */ -+ hard_vcpus_limit = soft_vcpus_limit; -+#endif -+ - while (nc->name) { - if (nc->num > soft_vcpus_limit) { - warn_report("Number of %s cpus requested (%d) exceeds " --- -2.31.1 - diff --git a/extras/qemu/0015-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch b/extras/qemu/0015-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch deleted file mode 100644 index 722484d..0000000 --- a/extras/qemu/0015-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 4b6c8cdc52fdf94d4098d278defb3833dce1d189 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Wed, 8 Jul 2020 08:35:50 +0200 -Subject: Use qemu-kvm in documentation instead of qemu-system- - -Patchwork-id: 62380 -O-Subject: [RHEV-7.1 qemu-kvm-rhev PATCHv4] Use qemu-kvm in documentation instead of qemu-system-i386 -Bugzilla: 1140620 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Markus Armbruster -RH-Acked-by: Stefan Hajnoczi - -From: Miroslav Rezanina - -We change the name and location of qemu-kvm binaries. Update documentation -to reflect this change. Only architectures available in RHEL are updated. - -Signed-off-by: Miroslav Rezanina ---- - docs/defs.rst.inc | 4 ++-- - qemu-options.hx | 10 +++++----- - 2 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/docs/defs.rst.inc b/docs/defs.rst.inc -index 52d6454b93..d74dbdeca9 100644 ---- a/docs/defs.rst.inc -+++ b/docs/defs.rst.inc -@@ -9,7 +9,7 @@ - but the manpages will end up misrendered with following normal text - incorrectly in boldface. - --.. |qemu_system| replace:: qemu-system-x86_64 --.. |qemu_system_x86| replace:: qemu-system-x86_64 -+.. |qemu_system| replace:: qemu-kvm -+.. |qemu_system_x86| replace:: qemu-kvm - .. |I2C| replace:: I\ :sup:`2`\ C - .. |I2S| replace:: I\ :sup:`2`\ S -diff --git a/qemu-options.hx b/qemu-options.hx -index 34e9b32a5c..924f61ab6d 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -3233,11 +3233,11 @@ SRST - - :: - -- qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \ -- -numa node,memdev=mem \ -- -chardev socket,id=chr0,path=/path/to/socket \ -- -netdev type=vhost-user,id=net0,chardev=chr0 \ -- -device virtio-net-pci,netdev=net0 -+ qemu-kvm -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \ -+ -numa node,memdev=mem \ -+ -chardev socket,id=chr0,path=/path/to/socket \ -+ -netdev type=vhost-user,id=net0,chardev=chr0 \ -+ -device virtio-net-pci,netdev=net0 - - ``-netdev vhost-vdpa,vhostdev=/path/to/dev`` - Establish a vhost-vdpa netdev. --- -2.31.1 - diff --git a/extras/qemu/0016-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch b/extras/qemu/0016-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch deleted file mode 100644 index 9f08024..0000000 --- a/extras/qemu/0016-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch +++ /dev/null @@ -1,66 +0,0 @@ -From b72e04cb7e417d9e1c973223747ab3a27abda8b4 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -Date: Wed, 14 Jun 2017 15:37:01 +0200 -Subject: virtio-scsi: Reject scsi-cd if data plane enabled [RHEL only] - -RH-Author: Fam Zheng -Message-id: <20170614153701.14757-1-famz@redhat.com> -Patchwork-id: 75613 -O-Subject: [RHV-7.4 qemu-kvm-rhev PATCH v3] virtio-scsi: Reject scsi-cd if data plane enabled [RHEL only] -Bugzilla: 1378816 -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Max Reitz - -We need a fix for RHEL 7.4 and 7.3.z, but unfortunately upstream isn't -ready. If it were, the changes will be too invasive. To have an idea: - -https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg05400.html - -is an incomplete attempt to fix part of the issue, and the remaining -work unfortunately involve even more complex changes. - -As a band-aid, this partially reverts the effect of ef8875b -(virtio-scsi: Remove op blocker for dataplane, since v2.7). We cannot -simply revert that commit as a whole because we already shipped it in -qemu-kvm-rhev 7.3, since when, block jobs has been possible. We should -only block what has been broken. Also, faithfully reverting the above -commit means adding back the removed op blocker, but that is not enough, -because it still crashes when inserting media into an initially empty -scsi-cd. - -All in all, scsi-cd on virtio-scsi-dataplane has basically been unusable -unless the scsi-cd never enters an empty state, so, disable it -altogether. Otherwise it would be much more difficult to avoid -crashing. - -Signed-off-by: Fam Zheng -Signed-off-by: Miroslav Rezanina -Signed-off-by: Danilo C. L. de Paula ---- - hw/scsi/virtio-scsi.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c -index 34a968ecfb..7f6da33a8a 100644 ---- a/hw/scsi/virtio-scsi.c -+++ b/hw/scsi/virtio-scsi.c -@@ -896,6 +896,15 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, - AioContext *old_context; - int ret; - -+ /* XXX: Remove this check once block backend is capable of handling -+ * AioContext change upon eject/insert. -+ * s->ctx is NULL if ioeventfd is off, s->ctx is qemu_get_aio_context() if -+ * data plane is not used, both cases are safe for scsi-cd. */ -+ if (s->ctx && s->ctx != qemu_get_aio_context() && -+ object_dynamic_cast(OBJECT(dev), "scsi-cd")) { -+ error_setg(errp, "scsi-cd is not supported by data plane"); -+ return; -+ } - if (s->ctx && !s->dataplane_fenced) { - if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { - return; --- -2.31.1 - diff --git a/extras/qemu/0017-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch b/extras/qemu/0017-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch deleted file mode 100644 index 2bc687c..0000000 --- a/extras/qemu/0017-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 64a06662cdea0ff62efb122be4eab506b2a842d9 Mon Sep 17 00:00:00 2001 -From: David Gibson -Date: Wed, 6 Feb 2019 03:58:56 +0000 -Subject: BZ1653590: Require at least 64kiB pages for downstream guests & hosts - -RH-Author: David Gibson -Message-id: <20190206035856.19058-1-dgibson@redhat.com> -Patchwork-id: 84246 -O-Subject: [RHELAV-8.0/rhel qemu-kvm PATCH] BZ1653590: Require at least 64kiB pages for downstream guests & hosts -Bugzilla: 1653590 -RH-Acked-by: Laurent Vivier -RH-Acked-by: Serhii Popovych -RH-Acked-by: Thomas Huth - -Most current POWER guests require 64kiB page support, so that's the default -for the cap-hpt-max-pagesize option in qemu which limits available guest -page sizes. We warn if the value is set smaller than that, but don't -outright fail upstream, because we need to allow for the possibility of -guest (and/or host) kernels configured for 4kiB page sizes. - -Downstream, however, we simply don't support 4kiB pagesize configured -kernels in guest or host, so we can have qemu simply error out in this -situation. - -Testing: Attempted to start a guest with cap-hpt-max-page-size=4k and verified - it failed immediately with a qemu error - -Signed-off-by: David Gibson -Signed-off-by: Danilo C. L. de Paula ---- - hw/ppc/spapr_caps.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c -index 655ab856a0..6aa7f93df9 100644 ---- a/hw/ppc/spapr_caps.c -+++ b/hw/ppc/spapr_caps.c -@@ -329,12 +329,19 @@ bool spapr_check_pagesize(SpaprMachineState *spapr, hwaddr pagesize, - static void cap_hpt_maxpagesize_apply(SpaprMachineState *spapr, - uint8_t val, Error **errp) - { -+#if 0 /* disabled for RHEL */ - if (val < 12) { - error_setg(errp, "Require at least 4kiB hpt-max-page-size"); - return; - } else if (val < 16) { - warn_report("Many guests require at least 64kiB hpt-max-page-size"); - } -+#else /* Only page sizes >=64kiB supported for RHEL */ -+ if (val < 16) { -+ error_setg(errp, "Require at least 64kiB hpt-max-page-size"); -+ return; -+ } -+#endif - - spapr_check_pagesize(spapr, qemu_minrampagesize(), errp); - } --- -2.31.1 - diff --git a/extras/qemu/0018-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch b/extras/qemu/0018-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch deleted file mode 100644 index d7401d5..0000000 --- a/extras/qemu/0018-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 54f9157a918e1404f2f17ce89a9c8b9088c1bc06 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Fri, 20 Aug 2021 18:25:12 +0200 -Subject: qcow2: Deprecation warning when opening v2 images rw -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Kevin Wolf -RH-MergeRequest: 37: qcow2: Deprecation warning when opening v2 images rw -RH-Commit: [1/1] f450d0ae32d35063b28c72c4f2d2ebb9e6d8db3e (kmwolf/centos-qemu-kvm) -RH-Bugzilla: 1951814 -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Hanna Reitz -RH-Acked-by: Thomas Huth -RH-Acked-by: Philippe Mathieu-Daudé - -qcow2 v3 has been around for a long time (since QEMU 1.1/RHEL 7), so -there is no real reason any more to use it. People still using it might -do so unintentionally. Warn about it and suggest upgrading during the -RHEL 9 timeframe so that the code can possibly be disabled in RHEL 10. - -The warning is restricted to read-write mode and the system emulator. -The primary motivation for not having it in qemu-img is that 'qemu-img -amend' for upgrades would warn otherwise. It also avoids having to make -too many changes to the test suite. - -bdrv_uses_whitelist() is used as a proxy for deciding whether we are -running in a tool or the system emulator. This is not entirely clean, -but it's what is available and the same function qcow2_do_open() already -uses it this way for another warning. - -Signed-off-by: Kevin Wolf - -patch_name: kvm-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch -present_in_specfile: true -location_in_specfile: 116 ---- -Rebase notes (6.1.0): -- Replace bs->read_only with bdrv_is_read_only ---- - block/qcow2.c | 6 ++++++ - tests/qemu-iotests/common.filter | 1 + - 2 files changed, 7 insertions(+) - -diff --git a/block/qcow2.c b/block/qcow2.c -index b5c47931ef..a795e457ac 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -1337,6 +1337,12 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, - ret = -ENOTSUP; - goto fail; - } -+ if (header.version < 3 && !bdrv_is_read_only(bs) && bdrv_uses_whitelist()) { -+ warn_report_once("qcow2 v2 images are deprecated and may not be " -+ "supported in future versions. Please consider " -+ "upgrading the image with 'qemu-img amend " -+ "-o compat=v3'."); -+ } - - s->qcow_version = header.version; - -diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter -index cc9f1a5891..6a13757177 100644 ---- a/tests/qemu-iotests/common.filter -+++ b/tests/qemu-iotests/common.filter -@@ -83,6 +83,7 @@ _filter_qemu() - { - gsed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \ - -e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#' \ -+ -e "/qcow2 v2 images are deprecated/d" \ - -e $'s#\r##' # QEMU monitor uses \r\n line endings - } - --- -2.31.1 - diff --git a/extras/qemu/0019-WRB-Introduce-RHEL-9.0.0-hw-compat-structure.patch b/extras/qemu/0019-WRB-Introduce-RHEL-9.0.0-hw-compat-structure.patch deleted file mode 100644 index 285cd6b..0000000 --- a/extras/qemu/0019-WRB-Introduce-RHEL-9.0.0-hw-compat-structure.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 1d6439527aa6ccabb58208c94417778ccc19de39 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Wed, 9 Feb 2022 04:16:25 -0500 -Subject: WRB: Introduce RHEL 9.0.0 hw compat structure - -General compatibility structure for post RHEL 9.0.0 rebase. - -Signed-off-by: Miroslav Rezanina ---- - hw/core/machine.c | 9 +++++++++ - hw/i386/pc.c | 6 ++++++ - hw/i386/pc_piix.c | 4 ++++ - hw/i386/pc_q35.c | 4 ++++ - hw/s390x/s390-virtio-ccw.c | 2 ++ - include/hw/boards.h | 3 +++ - include/hw/i386/pc.h | 3 +++ - 7 files changed, 31 insertions(+) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 28989b6e7b..dffc3ef4ab 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -53,6 +53,15 @@ GlobalProperty hw_compat_rhel_8_6[] = { - }; - const size_t hw_compat_rhel_8_6_len = G_N_ELEMENTS(hw_compat_rhel_8_6); - -+/* -+ * Mostly the same as hw_compat_6_2 -+ */ -+GlobalProperty hw_compat_rhel_9_0[] = { -+ /* hw_compat_rhel_9_0 from hw_compat_6_2 */ -+ { "PIIX4_PM", "x-not-migrate-acpi-index", "on"}, -+}; -+const size_t hw_compat_rhel_9_0_len = G_N_ELEMENTS(hw_compat_rhel_9_0); -+ - /* - * Mostly the same as hw_compat_6_0 and hw_compat_6_1 - */ -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 263d882af6..0886cfe3fe 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -391,6 +391,12 @@ GlobalProperty pc_rhel_compat[] = { - }; - const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat); - -+GlobalProperty pc_rhel_9_0_compat[] = { -+ /* pc_rhel_9_0_compat from pc_compat_6_2 */ -+ { "virtio-mem", "unplugged-inaccessible", "off" }, -+}; -+const size_t pc_rhel_9_0_compat_len = G_N_ELEMENTS(pc_rhel_9_0_compat); -+ - GlobalProperty pc_rhel_8_5_compat[] = { - /* pc_rhel_8_5_compat from pc_compat_6_0 */ - { "qemu64" "-" TYPE_X86_CPU, "family", "6" }, -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 0cacc0d623..dc987fe93b 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -1014,6 +1014,10 @@ static void pc_machine_rhel760_options(MachineClass *m) - pcmc->kvmclock_create_always = false; - /* From pc_i440fx_5_1_machine_options() */ - pcmc->pci_root_uid = 1; -+ compat_props_add(m->compat_props, hw_compat_rhel_9_0, -+ hw_compat_rhel_9_0_len); -+ compat_props_add(m->compat_props, pc_rhel_9_0_compat, -+ pc_rhel_9_0_compat_len); - compat_props_add(m->compat_props, hw_compat_rhel_8_6, - hw_compat_rhel_8_6_len); - compat_props_add(m->compat_props, hw_compat_rhel_8_5, -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 157160e069..52c253c570 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -669,6 +669,10 @@ static void pc_q35_machine_rhel900_options(MachineClass *m) - m->desc = "RHEL-9.0.0 PC (Q35 + ICH9, 2009)"; - pcmc->smbios_stream_product = "RHEL"; - pcmc->smbios_stream_version = "9.0.0"; -+ compat_props_add(m->compat_props, hw_compat_rhel_9_0, -+ hw_compat_rhel_9_0_len); -+ compat_props_add(m->compat_props, pc_rhel_9_0_compat, -+ pc_rhel_9_0_compat_len); - } - - DEFINE_PC_MACHINE(q35_rhel900, "pc-q35-rhel9.0.0", pc_q35_init_rhel900, -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 465a2a09d2..08e0f6a79b 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -1118,12 +1118,14 @@ static void ccw_machine_2_4_class_options(MachineClass *mc) - DEFINE_CCW_MACHINE(2_4, "2.4", false); - #endif - -+ - static void ccw_machine_rhel900_instance_options(MachineState *machine) - { - } - - static void ccw_machine_rhel900_class_options(MachineClass *mc) - { -+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len); - } - DEFINE_CCW_MACHINE(rhel900, "rhel9.0.0", true); - -diff --git a/include/hw/boards.h b/include/hw/boards.h -index d1555665df..635e45dd71 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -451,6 +451,9 @@ extern const size_t hw_compat_2_2_len; - extern GlobalProperty hw_compat_2_1[]; - extern const size_t hw_compat_2_1_len; - -+extern GlobalProperty hw_compat_rhel_9_0[]; -+extern const size_t hw_compat_rhel_9_0_len; -+ - extern GlobalProperty hw_compat_rhel_8_6[]; - extern const size_t hw_compat_rhel_8_6_len; - -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 419a6ec24b..a492c420b5 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -292,6 +292,9 @@ extern const size_t pc_compat_1_4_len; - extern GlobalProperty pc_rhel_compat[]; - extern const size_t pc_rhel_compat_len; - -+extern GlobalProperty pc_rhel_9_0_compat[]; -+extern const size_t pc_rhel_9_0_compat_len; -+ - extern GlobalProperty pc_rhel_8_5_compat[]; - extern const size_t pc_rhel_8_5_compat_len; - --- -2.31.1 - diff --git a/extras/qemu/0020-redhat-Update-s390x-machine-type-compatibility-for-r.patch b/extras/qemu/0020-redhat-Update-s390x-machine-type-compatibility-for-r.patch deleted file mode 100644 index d3b91d0..0000000 --- a/extras/qemu/0020-redhat-Update-s390x-machine-type-compatibility-for-r.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c8ad21ca31892f8798cf82508c2b2c61bf3b9895 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Mon, 4 Apr 2022 12:15:50 +0200 -Subject: redhat: Update s390x machine type compatibility for rebase to QEMU - 7.0.0 - -RH-Author: Thomas Huth -RH-MergeRequest: 143: Update machine type compatibility for QEMU 7.0.0 update [s390x] -RH-Commit: [23/23] 0ecf97d7bdddc50565b5779c64744b353f715cbd -RH-Bugzilla: 2064782 -RH-Acked-by: Cornelia Huck -RH-Acked-by: David Hildenbrand - -No s390x-specific machine class property updates required this time, -only an update to the default qemu cpu model. - -Signed-off-by: Thomas Huth ---- - hw/s390x/s390-virtio-ccw.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 08e0f6a79b..4a491d4988 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -1121,6 +1121,9 @@ DEFINE_CCW_MACHINE(2_4, "2.4", false); - - static void ccw_machine_rhel900_instance_options(MachineState *machine) - { -+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 }; -+ -+ s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat); - } - - static void ccw_machine_rhel900_class_options(MachineClass *mc) --- -2.31.1 - diff --git a/extras/qemu/0021-pc-Move-s3-s4-suspend-disabling-to-compat.patch b/extras/qemu/0021-pc-Move-s3-s4-suspend-disabling-to-compat.patch deleted file mode 100644 index f9535a8..0000000 --- a/extras/qemu/0021-pc-Move-s3-s4-suspend-disabling-to-compat.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 38b89dc24551258b630f09d1c654b6c72b265c79 Mon Sep 17 00:00:00 2001 -From: "Dr. David Alan Gilbert" -Date: Thu, 14 Apr 2022 14:58:43 +0100 -Subject: pc: Move s3/s4 suspend disabling to compat - -RH-Author: Dr. David Alan Gilbert -RH-MergeRequest: 155: 7.0 machine type fixes (x86) -RH-Commit: [26/26] 7d666032d5f5dab1444ebba085f92f2de4e86699 -RH-Bugzilla: 2064771 - -Our downstream patches currently have tweaks in the C code to disable -s3/s4; Thomas pointed out we can just set the property. - -Signed-off-by: Dr. David Alan Gilbert ---- - hw/acpi/ich9.c | 4 ++-- - hw/acpi/piix4.c | 4 ++-- - hw/i386/pc.c | 6 ++++++ - 3 files changed, 10 insertions(+), 4 deletions(-) - -diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c -index de1e401cdf..bd9bbade70 100644 ---- a/hw/acpi/ich9.c -+++ b/hw/acpi/ich9.c -@@ -435,8 +435,8 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm) - static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN; - pm->acpi_memory_hotplug.is_enabled = true; - pm->cpu_hotplug_legacy = true; -- pm->disable_s3 = 1; -- pm->disable_s4 = 1; -+ pm->disable_s3 = 0; -+ pm->disable_s4 = 0; - pm->s4_val = 2; - pm->use_acpi_hotplug_bridge = true; - pm->keep_pci_slot_hpc = true; -diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c -index 28544e78c3..2fb2b43248 100644 ---- a/hw/acpi/piix4.c -+++ b/hw/acpi/piix4.c -@@ -653,8 +653,8 @@ static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) - - static Property piix4_pm_properties[] = { - DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), -- DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 1), -- DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 1), -+ DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), -+ DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), - DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), - DEFINE_PROP_BOOL(ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, PIIX4PMState, - use_acpi_hotplug_bridge, true), -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 0886cfe3fe..f98f842f80 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -380,6 +380,12 @@ const size_t pc_compat_1_4_len = G_N_ELEMENTS(pc_compat_1_4); - * machine type. - */ - GlobalProperty pc_rhel_compat[] = { -+ /* we don't support s3/s4 suspend */ -+ { "PIIX4_PM", "disable_s3", "1" }, -+ { "PIIX4_PM", "disable_s4", "1" }, -+ { "ICH9-LPC", "disable_s3", "1" }, -+ { "ICH9-LPC", "disable_s4", "1" }, -+ - { TYPE_X86_CPU, "host-phys-bits", "on" }, - { TYPE_X86_CPU, "host-phys-bits-limit", "48" }, - { TYPE_X86_CPU, "vmx-entry-load-perf-global-ctrl", "off" }, --- -2.31.1 - diff --git a/extras/qemu/95-kvm-memlock.conf b/extras/qemu/95-kvm-memlock.conf deleted file mode 100644 index 31d6d2a..0000000 --- a/extras/qemu/95-kvm-memlock.conf +++ /dev/null @@ -1,12 +0,0 @@ -# The KVM HV implementation on Power can require a significant amount -# of unswappable memory (about half of which also needs to be host -# physically contiguous) to hold the guest's Hash Page Table (HPT) - -# roughly 1/64th of the guest's RAM size, minimum 16MiB. -# -# These limits allow unprivileged users to start smallish VMs, such as -# those used by libguestfs. -# -# https://bugzilla.redhat.com/show_bug.cgi?id=1293024 -# -* hard memlock 65536 -* soft memlock 65536 diff --git a/extras/qemu/99-qemu-guest-agent.rules b/extras/qemu/99-qemu-guest-agent.rules deleted file mode 100644 index 8a290ab..0000000 --- a/extras/qemu/99-qemu-guest-agent.rules +++ /dev/null @@ -1,2 +0,0 @@ -SUBSYSTEM=="virtio-ports", ATTR{name}=="org.qemu.guest_agent.0", \ - TAG+="systemd" ENV{SYSTEMD_WANTS}="qemu-guest-agent.service" diff --git a/extras/qemu/README.tests b/extras/qemu/README.tests deleted file mode 100644 index 9932773..0000000 --- a/extras/qemu/README.tests +++ /dev/null @@ -1,39 +0,0 @@ -qemu-kvm-tests README -===================== - -The qemu-kvm-tests rpm contains tests that can be used to verify the -functionality of the installed qemu-kvm package - -When installed, the files from this rpm will be arranged in the following -directory structure - -tests-src/ -├── README -├── scripts -│   ├── qemu.py -│   └── qmp -└── tests - ├── acceptance - ├── Makefile.include - └── qemu-iotests - -The tests/ directory within the tests-src/ directory is setup to remain a copy -of a subset of the tests/ directory from the QEMU source tree - -The avocado_qemu tests and qemu-iotests, along with files required for the -execution of the avocado_qemu tests (scripts/qemu.py and scripts/qmp/) will be -installed in a new location - /usr/lib64/qemu-kvm/tests-src/ - -avocado_qemu tests: -The avocado_qemu tests can be executed by running the following avocado command: -avocado run -p qemu_bin=/usr/libexec/qemu-kvm /usr/lib64/qemu-kvm/tests/acceptance/ -Avocado needs to be installed separately using either pip or from source as -Avocado is not being packaged for RHEL-8. - -qemu-iotests: -symlinks to corresponding binaries need to be created for QEMU_PROG, -QEMU_IO_PROG, QEMU_IMG_PROG, and QEMU_NBD_PROG before the iotests can be -executed. - -The primary purpose of this package is to make these tests available to be -executed as gating tests for the virt module in the RHEL-8 OSCI environment. diff --git a/extras/qemu/bridge.conf b/extras/qemu/bridge.conf deleted file mode 100644 index a573665..0000000 --- a/extras/qemu/bridge.conf +++ /dev/null @@ -1 +0,0 @@ -allow virbr0 diff --git a/extras/qemu/kvm-s390x.conf b/extras/qemu/kvm-s390x.conf deleted file mode 100644 index d82b818..0000000 --- a/extras/qemu/kvm-s390x.conf +++ /dev/null @@ -1,19 +0,0 @@ -# User changes in this file are preserved across upgrades. -# -# Setting "modprobe kvm nested=1" only enables Nested Virtualization until -# the next reboot or module reload. Uncomment the option below to enable -# the feature permanently. -# -#options kvm nested=1 -# -# -# Setting "modprobe kvm hpage=1" only enables Huge Page Backing (1MB) -# support until the next reboot or module reload. Uncomment the option -# below to enable the feature permanently. -# -# Note: - Incompatible with "nested=1". Loading the module will fail. -# - Dirty page logging will be performed on a 1MB (not 4KB) basis, -# which can result in a lot of data having to be transferred during -# migration, and therefore taking very long to converge. -# -#options kvm hpage=1 diff --git a/extras/qemu/kvm-x86.conf b/extras/qemu/kvm-x86.conf deleted file mode 100644 index 3f7842a..0000000 --- a/extras/qemu/kvm-x86.conf +++ /dev/null @@ -1,12 +0,0 @@ -# Setting modprobe kvm_intel/kvm_amd nested = 1 -# only enables Nested Virtualization until the next reboot or -# module reload. Uncomment the option applicable -# to your system below to enable the feature permanently. -# -# User changes in this file are preserved across upgrades. -# -# For Intel -#options kvm_intel nested=1 -# -# For AMD -#options kvm_amd nested=1 diff --git a/extras/qemu/kvm.conf b/extras/qemu/kvm.conf deleted file mode 100644 index 24e60e9..0000000 --- a/extras/qemu/kvm.conf +++ /dev/null @@ -1,3 +0,0 @@ -# -# User changes in this file are preserved across upgrades. -# diff --git a/extras/qemu/qemu-ga.sysconfig b/extras/qemu/qemu-ga.sysconfig deleted file mode 100644 index 42a818a..0000000 --- a/extras/qemu/qemu-ga.sysconfig +++ /dev/null @@ -1,19 +0,0 @@ -# This is a systemd environment file, not a shell script. -# It provides settings for "/lib/systemd/system/qemu-guest-agent.service". - -# Comma-separated blacklist of RPCs to disable, or empty list to enable all. -# -# You can get the list of RPC commands using "qemu-ga --blacklist='?'". -# There should be no spaces between commas and commands in the blacklist. -#BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status - -# Fsfreeze hook script specification. -# -# FSFREEZE_HOOK_PATHNAME=/dev/null : disables the feature. -# -# FSFREEZE_HOOK_PATHNAME=/path/to/executable : enables the feature with the -# specified binary or shell script. -# -# FSFREEZE_HOOK_PATHNAME= : enables the feature with the -# default value (invoke "qemu-ga --help" to interrogate). -FSFREEZE_HOOK_PATHNAME=/etc/qemu-ga/fsfreeze-hook diff --git a/extras/qemu/qemu-guest-agent.service b/extras/qemu/qemu-guest-agent.service deleted file mode 100644 index b3157d5..0000000 --- a/extras/qemu/qemu-guest-agent.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=QEMU Guest Agent -BindsTo=dev-virtio\x2dports-org.qemu.guest_agent.0.device -After=dev-virtio\x2dports-org.qemu.guest_agent.0.device -IgnoreOnIsolate=True - -[Service] -UMask=0077 -EnvironmentFile=/etc/sysconfig/qemu-ga -ExecStart=/usr/bin/qemu-ga \ - --method=virtio-serial \ - --path=/dev/virtio-ports/org.qemu.guest_agent.0 \ - --blacklist=${BLACKLIST_RPC} \ - -F${FSFREEZE_HOOK_PATHNAME} -Restart=always -RestartSec=0 - -[Install] -WantedBy=dev-virtio\x2dports-org.qemu.guest_agent.0.device diff --git a/extras/qemu/qemu.spec b/extras/qemu/qemu.spec deleted file mode 100644 index d1e7e77..0000000 --- a/extras/qemu/qemu.spec +++ /dev/null @@ -1,2608 +0,0 @@ -# Provide a way to skip tests via rpmbuild `--without` -# This makes it easier to skip tests in copr repos, where -# the qemu test suite is historically flakey -%bcond_with check - -%global libfdt_version 1.6.0 -%global libseccomp_version 2.4.0 -%global libusbx_version 1.0.23 -%global meson_version 0.58.2 -%global usbredir_version 0.7.1 -%global ipxe_version 20200823-5.git4bd064de - -%global have_memlock_limits 0 -%global need_qemu_kvm 0 -%ifarch %{ix86} -%global kvm_package system-x86 -# need_qemu_kvm should only ever be used by x86 -%global need_qemu_kvm 1 -%endif -%ifarch x86_64 -%global kvm_package system-x86 -# need_qemu_kvm should only ever be used by x86 -%global need_qemu_kvm 1 -%endif -%ifarch %{power64} -%global have_memlock_limits 1 -%global kvm_package system-ppc -%endif -%ifarch s390x -%global kvm_package system-s390x -%endif -%ifarch armv7hl -%global kvm_package system-arm -%endif -%ifarch aarch64 -%global kvm_package system-aarch64 -%endif -%ifarch %{mips} -%global kvm_package system-mips -%endif -%ifarch riscv64 -%global kvm_package system-riscv -%endif - -%global modprobe_kvm_conf %{_sourcedir}/kvm.conf -%ifarch s390x - %global modprobe_kvm_conf %{_sourcedir}/kvm-s390x.conf -%endif -%ifarch %{ix86} x86_64 - %global modprobe_kvm_conf %{_sourcedir}/kvm-x86.conf -%endif - -%global tools_only 0 - -%global user_static 1 -%if 0%{?rhel} -# EPEL/RHEL do not have required -static builddeps -%global user_static 0 -%endif - -%global have_kvm 0 -%if 0%{?kvm_package:1} -%global have_kvm 1 -%endif - -# Matches numactl ExcludeArch -%global have_numactl 1 -%ifarch %{arm} -%global have_numactl 0 -%endif - -# Matches spice ExclusiveArch -%global have_spice 1 -%ifnarch %{ix86} x86_64 %{arm} aarch64 -%global have_spice 0 -%endif -%if 0%{?rhel} >= 9 -%global have_spice 0 -%endif - -# Matches xen ExclusiveArch -%global have_xen 0 -%if 0%{?fedora} -%ifarch %{ix86} x86_64 armv7hl aarch64 -%global have_xen 1 -%endif -%endif - -%global have_liburing 0 -%if 0%{?fedora} || %{rhel} > 7 -%ifnarch %{arm} -%global have_liburing 1 -%endif -%endif - -%global have_virgl 0 -%if 0%{?fedora} -%global have_virgl 1 -%endif - -%global have_pmem 0 -%ifarch x86_64 %{power64} -%global have_pmem 1 -%endif - -%global have_jack 1 -%if 0%{?rhel} <= 7 -%global have_jack 0 -%endif - -%global have_sdl_image %{defined fedora} -%global have_fdt 1 -%global have_opengl 1 -%global have_usbredir 1 -%global enable_werror 0 - - -# Matches edk2.spec ExclusiveArch -%global have_edk2 0 -%ifarch %{ix86} x86_64 %{arm} aarch64 -%global have_edk2 1 -%endif - -# All modules should be listed here. -%define have_block_rbd 1 -%ifarch %{ix86} %{arm} -%define have_block_rbd 0 -%endif - - -%global have_block_gluster 1 -%if 0%{?rhel} >= 9 -%global have_block_gluster 0 -%endif - -%define have_block_nfs 0 -%if 0%{?fedora} -%define have_block_nfs 1 -%endif - -%define have_capstone_devel 0 -%if 0%{?fedora} -# capstone-devel is only on Fedora. Use it if it's available, but -# if not, use the internal qemu submodule copy -%define have_capstone_devel 1 -%endif - -%define have_librdma 1 -%ifarch %{arm} -%define have_librdma 0 -%endif - -%define have_libcacard 1 -%if 0%{?rhel} >= 9 -%define have_libcacard 0 -%endif - -# LTO still has issues with qemu on armv7hl and aarch64 -# https://bugzilla.redhat.com/show_bug.cgi?id=1952483 -%global _lto_cflags %{nil} - -# OOM killer breaks builds with parallel make on s390(x) -%ifarch s390x -%global _smp_mflags %{nil} -%endif - -%global firmwaredirs "%{_datadir}/qemu-firmware:%{_datadir}/ipxe/qemu:%{_datadir}/seavgabios:%{_datadir}/seabios:%{_datadir}/sgabios" - -%global qemudocdir %{_docdir}/%{name} -%define evr %{epoch}:%{version}-%{release} - -%define requires_block_curl Requires: %{name}-block-curl = %{evr} -%define requires_block_dmg Requires: %{name}-block-dmg = %{evr} -%if %{have_block_gluster} -%define requires_block_gluster Requires: %{name}-block-gluster = %{evr} -%define obsoletes_block_gluster %{nil} -%else -%define requires_block_gluster %{nil} -%define obsoletes_block_gluster Obsoletes: %{name}-block-gluster < %{evr} -%endif -%define requires_block_iscsi Requires: %{name}-block-iscsi = %{evr} -%if %{have_block_nfs} -%define requires_block_nfs Requires: %{name}-block-nfs = %{evr} -%define obsoletes_block_nfs %{nil} -%else -%define requires_block_nfs %{nil} -%define obsoletes_block_nfs Obsoletes: %{name}-block-nfs < %{evr} -%endif -%if %{have_block_rbd} -%define requires_block_rbd Requires: %{name}-block-rbd = %{evr} -%define obsoletes_block_rbd %{nil} -%else -%define requires_block_rbd %{nil} -%define obsoletes_block_rbd Obsoletes: %{name}-block-rbd < %{evr} -%endif -%define requires_block_ssh Requires: %{name}-block-ssh = %{evr} -%define requires_audio_alsa Requires: %{name}-audio-alsa = %{evr} -%define requires_audio_oss Requires: %{name}-audio-oss = %{evr} -%define requires_audio_pa Requires: %{name}-audio-pa = %{evr} -%define requires_audio_sdl Requires: %{name}-audio-sdl = %{evr} -%define requires_char_baum Requires: %{name}-char-baum = %{evr} -%define requires_device_usb_host Requires: %{name}-device-usb-host = %{evr} -%define requires_device_usb_redirect Requires: %{name}-device-usb-redirect = %{evr} -%define requires_ui_curses Requires: %{name}-ui-curses = %{evr} -%define requires_ui_gtk Requires: %{name}-ui-gtk = %{evr} -%define requires_ui_sdl Requires: %{name}-ui-sdl = %{evr} -%define requires_ui_egl_headless Requires: %{name}-ui-egl-headless = %{evr} -%define requires_ui_opengl Requires: %{name}-ui-opengl = %{evr} -%define requires_device_display_virtio_gpu Requires: %{name}-device-display-virtio-gpu = %{evr} -%define requires_device_display_virtio_gpu_gl Requires: %{name}-device-display-virtio-gpu-gl = %{evr} -%define requires_device_display_virtio_gpu_pci Requires: %{name}-device-display-virtio-gpu-pci = %{evr} -%define requires_device_display_virtio_gpu_pci_gl Requires: %{name}-device-display-virtio-gpu-pci-gl = %{evr} -%define requires_device_display_virtio_gpu_ccw Requires: %{name}-device-display-virtio-gpu-ccw = %{evr} -%define requires_device_display_virtio_vga Requires: %{name}-device-display-virtio-vga = %{evr} -%define requires_device_display_virtio_vga_gl Requires: %{name}-device-display-virtio-vga-gl = %{evr} - -%if %{have_virgl} -%define requires_device_display_vhost_user_gpu Requires: %{name}-device-display-vhost-user-gpu = %{evr} -%else -%define requires_device_display_vhost_user_gpu %{nil} -%endif - -%if %{have_jack} -%define jack_drv jack, -%define requires_audio_jack Requires: %{name}-audio-jack = %{evr} -%else -%define requires_audio_jack %{nil} -%endif - -%if %{have_spice} -%define requires_ui_spice_app Requires: %{name}-ui-spice-app = %{evr} -%define requires_ui_spice_core Requires: %{name}-ui-spice-core = %{evr} -%define requires_device_display_qxl Requires: %{name}-device-display-qxl = %{evr} -%define requires_audio_spice Requires: %{name}-audio-spice = %{evr} -%define requires_char_spice Requires: %{name}-char-spice = %{evr} -%else -%define requires_ui_spice_app %{nil} -%define requires_ui_spice_core %{nil} -%define requires_device_display_qxl %{nil} -%define requires_audio_spice %{nil} -%define requires_char_spice %{nil} -%endif - -%if %{have_libcacard} -%define requires_device_usb_smartcard Requires: %{name}-device-usb-smartcard = %{evr} -%else -%define requires_device_usb_smartcard %{nil} -%endif - -%global requires_all_modules \ -%{requires_block_curl} \ -%{requires_block_dmg} \ -%{requires_block_gluster} \ -%{requires_block_iscsi} \ -%{requires_block_nfs} \ -%{requires_block_rbd} \ -%{requires_block_ssh} \ -%{requires_audio_alsa} \ -%{requires_audio_oss} \ -%{requires_audio_pa} \ -%{requires_audio_sdl} \ -%{requires_audio_jack} \ -%{requires_audio_spice} \ -%{requires_ui_curses} \ -%{requires_ui_gtk} \ -%{requires_ui_sdl} \ -%{requires_ui_egl_headless} \ -%{requires_ui_opengl} \ -%{requires_ui_spice_app} \ -%{requires_ui_spice_core} \ -%{requires_char_baum} \ -%{requires_char_spice} \ -%{requires_device_display_qxl} \ -%{requires_device_display_vhost_user_gpu} \ -%{requires_device_display_virtio_gpu} \ -%{requires_device_display_virtio_gpu_gl} \ -%{requires_device_display_virtio_gpu_pci} \ -%{requires_device_display_virtio_gpu_pci_gl} \ -%{requires_device_display_virtio_vga} \ -%{requires_device_display_virtio_vga_gl} \ -%{requires_device_usb_host} \ -%{requires_device_usb_redirect} \ -%{requires_device_usb_smartcard} \ - -# Modules which can be conditionally built -%global obsoletes_some_modules \ -%{obsoletes_block_gluster} \ -%{obsoletes_block_rbd} \ -%{obsoletes_block_rbd} \ -Obsoletes: %{name}-system-lm32 <= %{epoch}:%{version}-%{release} \ -Obsoletes: %{name}-system-lm32-core <= %{epoch}:%{version}-%{release} \ -Obsoletes: %{name}-system-moxie <= %{epoch}:%{version}-%{release} \ -Obsoletes: %{name}-system-moxie-core <= %{epoch}:%{version}-%{release} \ -Obsoletes: %{name}-system-unicore32 <= %{epoch}:%{version}-%{release} \ -Obsoletes: %{name}-system-unicore32-core <= %{epoch}:%{version}-%{release} - -# Release candidate version tracking -# global rcver rc4 -%if 0%{?rcver:1} -%global rcrel .%{rcver} -%global rcstr -%{rcver} -%endif - -# To prevent rpmdev-bumpspec breakage -%global baserelease 2 - -Summary: QEMU is a FAST! processor emulator -Name: qemu -Version: 7.0.0 -Release: %{baserelease}%{?rcrel}%{?dist} -Epoch: 15 -License: GPLv2 and BSD and MIT and CC-BY -URL: http://www.qemu.org/ - -Source0: http://wiki.qemu-project.org/download/%{name}-%{version}%{?rcstr}.tar.xz - -Source10: qemu-guest-agent.service -Source11: 99-qemu-guest-agent.rules -Source12: bridge.conf -Source17: qemu-ga.sysconfig -Source21: 95-kvm-memlock.conf -Source26: vhost.conf -Source27: kvm.conf -Source30: kvm-s390x.conf -Source31: kvm-x86.conf -Source36: README.tests - -Patch0001: 0001-sgx-stub-fix.patch -Patch0004: 0004-Initial-redhat-build.patch -Patch0005: 0005-Enable-disable-devices-for-RHEL.patch -Patch0006: 0006-Machine-type-related-general-changes.patch -Patch0007: 0007-Add-aarch64-machine-types.patch -Patch0008: 0008-Add-ppc64-machine-types.patch -Patch0009: 0009-Add-s390x-machine-types.patch -Patch0010: 0010-Add-x86_64-machine-types.patch -Patch0011: 0011-Enable-make-check.patch -Patch0012: 0012-vfio-cap-number-of-devices-that-can-be-assigned.patch -Patch0013: 0013-Add-support-statement-to-help-output.patch -Patch0014: 0014-globally-limit-the-maximum-number-of-CPUs.patch -Patch0015: 0015-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch -Patch0016: 0016-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch -Patch0017: 0017-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch -Patch0018: 0018-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch -Patch0019: 0019-WRB-Introduce-RHEL-9.0.0-hw-compat-structure.patch -Patch0020: 0020-redhat-Update-s390x-machine-type-compatibility-for-r.patch -Patch0021: 0021-pc-Move-s3-s4-suspend-disabling-to-compat.patch - - -BuildRequires: meson >= %{meson_version} -BuildRequires: zlib-devel -BuildRequires: glib2-devel -BuildRequires: gnutls-devel -BuildRequires: libselinux-devel -BuildRequires: cyrus-sasl-devel -BuildRequires: libaio-devel -BuildRequires: python3-devel -BuildRequires: libiscsi-devel -BuildRequires: libattr-devel -BuildRequires: libusbx-devel >= %{libusbx_version} -%if %{have_usbredir} -BuildRequires: usbredir-devel >= %{usbredir_version} -%endif -BuildRequires: texinfo -BuildRequires: python3-sphinx -BuildRequires: python3-sphinx_rtd_theme -BuildRequires: libseccomp-devel >= %{libseccomp_version} -# For network block driver -BuildRequires: libcurl-devel -BuildRequires: libssh-devel -%if %{have_block_rbd} -BuildRequires: librbd-devel -%endif -# We need both because the 'stap' binary is probed for by configure -BuildRequires: systemtap -BuildRequires: systemtap-sdt-devel -# For VNC PNG support -BuildRequires: libpng-devel -# For virtiofs -BuildRequires: libcap-ng-devel -# Hard requirement for version >= 1.3 -BuildRequires: pixman-devel -# For rdma -%if %{have_librdma} -BuildRequires: rdma-core-devel -%endif -%if %{have_fdt} -BuildRequires: libfdt-devel >= %{libfdt_version} -%endif -# For compressed guest memory dumps -BuildRequires: lzo-devel snappy-devel -# For NUMA memory binding -%if %{have_numactl} -BuildRequires: numactl-devel -%endif -# qemu-pr-helper multipath support (requires libudev too) -BuildRequires: device-mapper-multipath-devel -BuildRequires: systemd-devel -%if %{have_pmem} -BuildRequires: libpmem-devel -%endif -# qemu-keymap -BuildRequires: pkgconfig(xkbcommon) -%if %{have_opengl} -BuildRequires: pkgconfig(epoxy) -BuildRequires: pkgconfig(libdrm) -BuildRequires: pkgconfig(gbm) -%endif -BuildRequires: perl-Test-Harness -BuildRequires: libslirp-devel -BuildRequires: libbpf-devel - - -# Fedora specific -%if "%{toolchain}" == "clang" -BuildRequires: clang -%else -BuildRequires: gcc -%endif -BuildRequires: make -# -display sdl support -BuildRequires: SDL2-devel -# pulseaudio audio output -BuildRequires: pulseaudio-libs-devel -# alsa audio output -BuildRequires: alsa-lib-devel -%if %{have_block_nfs} -# NFS drive support -BuildRequires: libnfs-devel -%endif -# curses display backend -BuildRequires: ncurses-devel -%if %{have_spice} -# spice graphics support -BuildRequires: spice-protocol -BuildRequires: spice-server-devel -%endif -# VNC JPEG support -BuildRequires: libjpeg-devel -# Braille device support -BuildRequires: brlapi-devel -%if %{have_block_gluster} -# gluster block driver -BuildRequires: glusterfs-api-devel -%endif -# GTK frontend -BuildRequires: gtk3-devel -BuildRequires: vte291-devel -# GTK translations -BuildRequires: gettext -%if %{have_xen} -# Xen support -BuildRequires: xen-devel -%endif -# reading bzip2 compressed dmg images -BuildRequires: bzip2-devel -# TLS test suite -BuildRequires: libtasn1-devel -%if %{have_libcacard} -# smartcard device -BuildRequires: libcacard-devel -%endif -%if %{have_virgl} -# virgl 3d support -BuildRequires: virglrenderer-devel -%endif -%if %{have_capstone_devel} -# preferred disassembler for TCG -BuildRequires: capstone-devel -%endif -# qemu-ga -BuildRequires: libudev-devel -# qauth infrastructure -BuildRequires: pam-devel -%if %{have_liburing} -# liburing support. Library isn't built for arm -BuildRequires: liburing-devel -%endif -# zstd compression support -BuildRequires: libzstd-devel -# `hostname` used by test suite -BuildRequires: hostname -# nvdimm dax -BuildRequires: daxctl-devel -# fuse block device -BuildRequires: fuse-devel -%if %{have_jack} -# jack audio driver -BuildRequires: jack-audio-connection-kit-devel -%endif -BuildRequires: fuse3-devel -%if %{have_sdl_image} -BuildRequires: SDL2_image-devel -%endif - -%if %{user_static} -BuildRequires: glibc-static pcre-static glib2-static zlib-static -%endif - -# Requires for the Fedora 'qemu' metapackage -Requires: %{name}-user = %{epoch}:%{version}-%{release} -Requires: %{name}-system-aarch64 = %{epoch}:%{version}-%{release} -Requires: %{name}-system-alpha = %{epoch}:%{version}-%{release} -Requires: %{name}-system-arm = %{epoch}:%{version}-%{release} -Requires: %{name}-system-avr = %{epoch}:%{version}-%{release} -Requires: %{name}-system-cris = %{epoch}:%{version}-%{release} -Requires: %{name}-system-m68k = %{epoch}:%{version}-%{release} -Requires: %{name}-system-microblaze = %{epoch}:%{version}-%{release} -Requires: %{name}-system-mips = %{epoch}:%{version}-%{release} -Requires: %{name}-system-nios2 = %{epoch}:%{version}-%{release} -Requires: %{name}-system-or1k = %{epoch}:%{version}-%{release} -Requires: %{name}-system-ppc = %{epoch}:%{version}-%{release} -Requires: %{name}-system-riscv = %{epoch}:%{version}-%{release} -Requires: %{name}-system-rx = %{epoch}:%{version}-%{release} -Requires: %{name}-system-s390x = %{epoch}:%{version}-%{release} -Requires: %{name}-system-sh4 = %{epoch}:%{version}-%{release} -Requires: %{name}-system-sparc = %{epoch}:%{version}-%{release} -Requires: %{name}-system-tricore = %{epoch}:%{version}-%{release} -Requires: %{name}-system-x86 = %{epoch}:%{version}-%{release} -Requires: %{name}-system-xtensa = %{epoch}:%{version}-%{release} -Requires: %{name}-img = %{epoch}:%{version}-%{release} -Requires: %{name}-tools = %{epoch}:%{version}-%{release} -Requires: qemu-pr-helper = %{epoch}:%{version}-%{release} -Requires: vhostuser-backend(fs) - - -%description -%{name} is an open source virtualizer that provides hardware -emulation for the KVM hypervisor. %{name} acts as a virtual -machine monitor together with the KVM kernel modules, and emulates the -hardware for a full system such as a PC and its associated peripherals. - -%package common -Summary: QEMU common files needed by all QEMU targets -Requires(post): /usr/bin/getent -Requires(post): /usr/sbin/groupadd -Requires(post): /usr/sbin/useradd -Requires(post): systemd-units -Requires(preun): systemd-units -Requires(postun): systemd-units -%{obsoletes_some_modules} -Requires: ipxe-roms-qemu >= %{ipxe_version} -%description common -%{name} is an open source virtualizer that provides hardware emulation for -the KVM hypervisor. - -This package provides documentation and auxiliary programs used with %{name}. - - -%package docs -Summary: %{name} documentation -%description docs -%{name}-docs provides documentation files regarding %{name}. - - -%package -n qemu-img -Summary: QEMU command line tool for manipulating disk images -%description -n qemu-img -This package provides a command line tool for manipulating disk images. - - -%package -n qemu-guest-agent -Summary: QEMU guest agent -Requires(post): systemd-units -Requires(preun): systemd-units -Requires(postun): systemd-units -%description -n qemu-guest-agent -%{name} is an open source virtualizer that provides hardware emulation for -the KVM hypervisor. - -This package provides an agent to run inside guests, which communicates -with the host over a virtio-serial channel named "org.qemu.guest_agent.0" - -This package does not need to be installed on the host OS. - - -%package tools -Summary: %{name} support tools -%description tools -%{name}-tools provides various tools related to %{name} usage. - - -%package -n qemu-pr-helper -Summary: qemu-pr-helper utility for %{name} -%description -n qemu-pr-helper -This package provides the qemu-pr-helper utility that is required for certain -SCSI features. - - -%package -n qemu-virtiofsd -Summary: QEMU virtio-fs shared file system daemon -Provides: vhostuser-backend(fs) -%description -n qemu-virtiofsd -This package provides virtiofsd daemon. This program is a vhost-user backend -that implements the virtio-fs device that is used for sharing a host directory -tree with a guest. - - -%package tests -Summary: tests for the %{name} package -Requires: %{name} = %{epoch}:%{version}-%{release} - -%define testsdir %{_libdir}/%{name}/tests-src - -%description tests -The %{name}-tests rpm contains tests that can be used to verify -the functionality of the installed %{name} package - -Install this package if you want access to the avocado_qemu -tests, or qemu-iotests. - - -%package block-curl -Summary: QEMU CURL block driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description block-curl -This package provides the additional CURL block driver for QEMU. - -Install this package if you want to access remote disks over -http, https, ftp and other transports provided by the CURL library. - - -%package block-iscsi -Summary: QEMU iSCSI block driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description block-iscsi -This package provides the additional iSCSI block driver for QEMU. - -Install this package if you want to access iSCSI volumes. - - -%if %{have_block_rbd} -%package block-rbd -Summary: QEMU Ceph/RBD block driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description block-rbd -This package provides the additional Ceph/RBD block driver for QEMU. - -Install this package if you want to access remote Ceph volumes -using the rbd protocol. -%endif - - -%package block-ssh -Summary: QEMU SSH block driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description block-ssh -This package provides the additional SSH block driver for QEMU. - -Install this package if you want to access remote disks using -the Secure Shell (SSH) protocol. - - -%if %{have_opengl} -%package ui-opengl -Summary: QEMU opengl support -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: mesa-libGL -Requires: mesa-libEGL -Requires: mesa-dri-drivers -%description ui-opengl -This package provides opengl support. -%endif - - -# Fedora specific -%package block-dmg -Summary: QEMU block driver for DMG disk images -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description block-dmg -This package provides the additional DMG block driver for QEMU. - -Install this package if you want to open '.dmg' files. - - -%if %{have_block_gluster} -%package block-gluster -Summary: QEMU Gluster block driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description block-gluster -This package provides the additional Gluster block driver for QEMU. - -Install this package if you want to access remote Gluster storage. -%endif - - -%if %{have_block_nfs} -%package block-nfs -Summary: QEMU NFS block driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} - -%description block-nfs -This package provides the additional NFS block driver for QEMU. - -Install this package if you want to access remote NFS storage. -%endif - - -%package audio-alsa -Summary: QEMU ALSA audio driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description audio-alsa -This package provides the additional ALSA audio driver for QEMU. - -%package audio-oss -Summary: QEMU OSS audio driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description audio-oss -This package provides the additional OSS audio driver for QEMU. - -%package audio-pa -Summary: QEMU PulseAudio audio driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description audio-pa -This package provides the additional PulseAudi audio driver for QEMU. - -%package audio-sdl -Summary: QEMU SDL audio driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description audio-sdl -This package provides the additional SDL audio driver for QEMU. - -%if %{have_jack} -%package audio-jack -Summary: QEMU Jack audio driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description audio-jack -This package provides the additional Jack audio driver for QEMU. -%endif - - -%package ui-curses -Summary: QEMU curses UI driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description ui-curses -This package provides the additional curses UI for QEMU. - -%package ui-gtk -Summary: QEMU GTK UI driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-ui-opengl%{?_isa} = %{epoch}:%{version}-%{release} -%description ui-gtk -This package provides the additional GTK UI for QEMU. - -%package ui-sdl -Summary: QEMU SDL UI driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-ui-opengl%{?_isa} = %{epoch}:%{version}-%{release} -%description ui-sdl -This package provides the additional SDL UI for QEMU. - -%package ui-egl-headless -Summary: QEMU EGL headless driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-ui-opengl%{?_isa} = %{epoch}:%{version}-%{release} -%description ui-egl-headless -This package provides the additional egl-headless UI for QEMU. - - -%package char-baum -Summary: QEMU Baum chardev driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description char-baum -This package provides the Baum chardev driver for QEMU. - - -%package device-display-virtio-gpu -Summary: QEMU virtio-gpu display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-virtio-gpu -This package provides the virtio-gpu display device for QEMU. - -%package device-display-virtio-gpu-gl -Summary: QEMU virtio-gpu-gl display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-virtio-gpu-gl -This package provides the virtio-gpu-gl display device for QEMU. - -%package device-display-virtio-gpu-pci -Summary: QEMU virtio-gpu-pci display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-virtio-gpu-pci -This package provides the virtio-gpu-pci display device for QEMU. - -%package device-display-virtio-gpu-pci-gl -Summary: QEMU virtio-gpu-pci-gl display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-virtio-gpu-pci-gl -This package provides the virtio-gpu-pci-gl display device for QEMU. - -%package device-display-virtio-gpu-ccw -Summary: QEMU virtio-gpu-ccw display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-virtio-gpu-ccw -This package provides the virtio-gpu-ccw display device for QEMU. - -%package device-display-virtio-vga -Summary: QEMU virtio-vga display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-virtio-vga -This package provides the virtio-vga display device for QEMU. - -%package device-display-virtio-vga-gl -Summary: QEMU virtio-vga-gl display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-virtio-vga-gl -This package provides the virtio-vga-gl display device for QEMU. - -%package device-usb-host -Summary: QEMU usb host device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-usb-host -This package provides the USB pass through driver for QEMU. - -%package device-usb-redirect -Summary: QEMU usbredir device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-usb-redirect -This package provides the usbredir device for QEMU. - -%if %{have_libcacard} -%package device-usb-smartcard -Summary: QEMU USB smartcard device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-usb-smartcard -This package provides the USB smartcard device for QEMU. -%endif - -%if %{have_virgl} -%package device-display-vhost-user-gpu -Summary: QEMU QXL display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-vhost-user-gpu -This package provides the vhost-user-gpu display device for QEMU. -%endif - -%if %{have_spice} -%package ui-spice-core -Summary: QEMU spice-core UI driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-ui-opengl%{?_isa} = %{epoch}:%{version}-%{release} -%description ui-spice-core -This package provides the additional spice-core UI for QEMU. - -%package ui-spice-app -Summary: QEMU spice-app UI driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-ui-spice-core%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-char-spice%{?_isa} = %{epoch}:%{version}-%{release} -%description ui-spice-app -This package provides the additional spice-app UI for QEMU. - -%package device-display-qxl -Summary: QEMU QXL display device -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-ui-spice-core%{?_isa} = %{epoch}:%{version}-%{release} -%description device-display-qxl -This package provides the QXL display device for QEMU. - -%package char-spice -Summary: QEMU spice chardev driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-ui-spice-core%{?_isa} = %{epoch}:%{version}-%{release} -%description char-spice -This package provides the spice chardev driver for QEMU. - -%package audio-spice -Summary: QEMU spice audio driver -Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} -Requires: %{name}-ui-spice-core%{?_isa} = %{epoch}:%{version}-%{release} -%description audio-spice -This package provides the spice audio driver for QEMU. -%endif - - -%if %{have_kvm} -%package kvm -Summary: QEMU metapackage for KVM support -Requires: qemu-%{kvm_package} = %{epoch}:%{version}-%{release} -%description kvm -This is a meta-package that provides a qemu-system- package for native -architectures where kvm can be enabled. For example, in an x86 system, this -will install qemu-system-x86 - - -%package kvm-core -Summary: QEMU metapackage for KVM support -Requires: qemu-%{kvm_package}-core = %{epoch}:%{version}-%{release} -%description kvm-core -This is a meta-package that provides a qemu-system--core package -for native architectures where kvm can be enabled. For example, in an -x86 system, this will install qemu-system-x86-core -%endif - - -%package user -Summary: QEMU user mode emulation of qemu targets -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description user -This package provides the user mode emulation of qemu targets - - -%package user-binfmt -Summary: QEMU user mode emulation of qemu targets -Requires: %{name}-user = %{epoch}:%{version}-%{release} -Requires(post): systemd-units -Requires(postun): systemd-units -# qemu-user-binfmt + qemu-user-static both provide binfmt rules -# Temporarily disable to get fedora CI working. Re-enable -# once this CI issue let's us deal with subpackage conflicts: -# https://pagure.io/fedora-ci/general/issue/184 -#Conflicts: qemu-user-static -%description user-binfmt -This package provides the user mode emulation of qemu targets - -%if %{user_static} -%package user-static -Summary: QEMU user mode emulation of qemu targets static build -Requires(post): systemd-units -Requires(postun): systemd-units -# qemu-user-binfmt + qemu-user-static both provide binfmt rules -# Temporarily disable to get fedora CI working. Re-enable -# once this CI issue let's us deal with subpackage conflicts: -# https://pagure.io/fedora-ci/general/issue/184 -#Conflicts: qemu-user-binfmt -#Provides: qemu-user-binfmt -%description user-static -This package provides the user mode emulation of qemu targets built as -static binaries -%endif - - -%package system-aarch64 -Summary: QEMU system emulator for AArch64 -Requires: %{name}-system-aarch64-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-aarch64 -This package provides the QEMU system emulator for AArch64. - -%package system-aarch64-core -Summary: QEMU system emulator for AArch64 -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%if %{have_edk2} -Requires: edk2-aarch64 -%endif -%description system-aarch64-core -This package provides the QEMU system emulator for AArch64. - - -%package system-alpha -Summary: QEMU system emulator for Alpha -Requires: %{name}-system-alpha-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-alpha -This package provides the QEMU system emulator for Alpha systems. - -%package system-alpha-core -Summary: QEMU system emulator for Alpha -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-alpha-core -This package provides the QEMU system emulator for Alpha systems. - - -%package system-arm -Summary: QEMU system emulator for ARM -Requires: %{name}-system-arm-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-arm -This package provides the QEMU system emulator for ARM systems. - -%package system-arm-core -Summary: QEMU system emulator for ARM -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%if %{have_edk2} -Requires: edk2-arm -%endif -%description system-arm-core -This package provides the QEMU system emulator for ARM boards. - - -%package system-avr -Summary: QEMU system emulator for AVR -Requires: %{name}-system-avr-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-avr -This package provides the QEMU system emulator for AVR systems. - -%package system-avr-core -Summary: QEMU system emulator for AVR -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-avr-core -This package provides the QEMU system emulator for AVR systems. - - -%package system-cris -Summary: QEMU system emulator for CRIS -Requires: %{name}-system-cris-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-cris -This package provides the system emulator for CRIS systems. - -%package system-cris-core -Summary: QEMU system emulator for CRIS -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-cris-core -This package provides the system emulator for CRIS boards. - - -%package system-hppa -Summary: QEMU system emulator for HPPA -Requires: %{name}-system-hppa-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-hppa -This package provides the QEMU system emulator for HPPA. - -%package system-hppa-core -Summary: QEMU system emulator for hppa -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-hppa-core -This package provides the QEMU system emulator for HPPA. - - -%package system-m68k -Summary: QEMU system emulator for ColdFire (m68k) -Requires: %{name}-system-m68k-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-m68k -This package provides the QEMU system emulator for ColdFire boards. - -%package system-m68k-core -Summary: QEMU system emulator for ColdFire (m68k) -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-m68k-core -This package provides the QEMU system emulator for ColdFire boards. - - -%package system-microblaze -Summary: QEMU system emulator for Microblaze -Requires: %{name}-system-microblaze-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-microblaze -This package provides the QEMU system emulator for Microblaze boards. - -%package system-microblaze-core -Summary: QEMU system emulator for Microblaze -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-microblaze-core -This package provides the QEMU system emulator for Microblaze boards. - - -%package system-mips -Summary: QEMU system emulator for MIPS -Requires: %{name}-system-mips-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-mips -This package provides the QEMU system emulator for MIPS systems. - -%package system-mips-core -Summary: QEMU system emulator for MIPS -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-mips-core -This package provides the QEMU system emulator for MIPS systems. - - -%package system-nios2 -Summary: QEMU system emulator for nios2 -Requires: %{name}-system-nios2-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-nios2 -This package provides the QEMU system emulator for NIOS2. - -%package system-nios2-core -Summary: QEMU system emulator for nios2 -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-nios2-core -This package provides the QEMU system emulator for NIOS2. - - -%package system-or1k -Summary: QEMU system emulator for OpenRisc32 -Requires: %{name}-system-or1k-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-or1k -This package provides the QEMU system emulator for OpenRisc32 boards. - -%package system-or1k-core -Summary: QEMU system emulator for OpenRisc32 -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-or1k-core -This package provides the QEMU system emulator for OpenRisc32 boards. - - -%package system-ppc -Summary: QEMU system emulator for PPC -Requires: %{name}-system-ppc-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-ppc -This package provides the QEMU system emulator for PPC and PPC64 systems. - -%package system-ppc-core -Summary: QEMU system emulator for PPC -Requires: %{name}-common = %{epoch}:%{version}-%{release} -Requires: openbios -Requires: SLOF -Requires: seavgabios-bin -%description system-ppc-core -This package provides the QEMU system emulator for PPC and PPC64 systems. - - -%package system-riscv -Summary: QEMU system emulator for RISC-V -Requires: %{name}-system-riscv-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-riscv -This package provides the QEMU system emulator for RISC-V systems. - -%package system-riscv-core -Summary: QEMU system emulator for RISC-V -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-riscv-core -This package provides the QEMU system emulator for RISC-V systems. - - -%package system-rx -Summary: QEMU system emulator for RX -Requires: %{name}-system-rx-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-rx -This package provides the QEMU system emulator for RX systems. - -%package system-rx-core -Summary: QEMU system emulator for RX -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-rx-core -This package provides the QEMU system emulator for RX systems. - - -%package system-s390x -Summary: QEMU system emulator for S390 -Requires: %{name}-system-s390x-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-s390x -This package provides the QEMU system emulator for S390 systems. - -%package system-s390x-core -Summary: QEMU system emulator for S390 -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-s390x-core -This package provides the QEMU system emulator for S390 systems. - - -%package system-sh4 -Summary: QEMU system emulator for SH4 -Requires: %{name}-system-sh4-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-sh4 -This package provides the QEMU system emulator for SH4 boards. - -%package system-sh4-core -Summary: QEMU system emulator for SH4 -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-sh4-core -This package provides the QEMU system emulator for SH4 boards. - - -%package system-sparc -Summary: QEMU system emulator for SPARC -Requires: %{name}-system-sparc-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-sparc -This package provides the QEMU system emulator for SPARC and SPARC64 systems. - -%package system-sparc-core -Summary: QEMU system emulator for SPARC -Requires: %{name}-common = %{epoch}:%{version}-%{release} -Requires: openbios -%description system-sparc-core -This package provides the QEMU system emulator for SPARC and SPARC64 systems. - - -%package system-tricore -Summary: QEMU system emulator for tricore -Requires: %{name}-system-tricore-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-tricore -This package provides the QEMU system emulator for Tricore. - -%package system-tricore-core -Summary: QEMU system emulator for tricore -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-tricore-core -This package provides the QEMU system emulator for Tricore. - - -%package system-x86 -Summary: QEMU system emulator for x86 -Requires: %{name}-system-x86-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-x86 -This package provides the QEMU system emulator for x86. When being run in a x86 -machine that supports it, this package also provides the KVM virtualization -platform. - -%package system-x86-core -Summary: QEMU system emulator for x86 -Requires: %{name}-common = %{epoch}:%{version}-%{release} -Requires: seabios-bin -Requires: sgabios-bin -Requires: seavgabios-bin -%if %{have_edk2} -Requires: edk2-ovmf -%endif -%description system-x86-core -This package provides the QEMU system emulator for x86. When being run in a x86 -machine that supports it, this package also provides the KVM virtualization -platform. - - -%package system-xtensa -Summary: QEMU system emulator for Xtensa -Requires: %{name}-system-xtensa-core = %{epoch}:%{version}-%{release} -%{requires_all_modules} -%description system-xtensa -This package provides the QEMU system emulator for Xtensa boards. - -%package system-xtensa-core -Summary: QEMU system emulator for Xtensa -Requires: %{name}-common = %{epoch}:%{version}-%{release} -%description system-xtensa-core -This package provides the QEMU system emulator for Xtensa boards. - - - - -%prep -%setup -q -n qemu-%{version}%{?rcstr} -%autopatch -p1 - -%global qemu_kvm_build qemu_kvm_build -mkdir -p %{qemu_kvm_build} -%global static_builddir static_builddir -mkdir -p %{static_builddir} - - - -%build -%define disable_everything \\\ - --audio-drv-list= \\\ - --disable-attr \\\ - --disable-auth-pam \\\ - --disable-avx2 \\\ - --disable-avx512f \\\ - --disable-block-drv-whitelist-in-tools \\\ - --disable-bochs \\\ - --disable-bpf \\\ - --disable-brlapi \\\ - --disable-bsd-user \\\ - --disable-bzip2 \\\ - --disable-cap-ng \\\ - --disable-capstone \\\ - --disable-cfi \\\ - --disable-cfi-debug \\\ - --disable-cloop \\\ - --disable-cocoa \\\ - --disable-coreaudio \\\ - --disable-coroutine-pool \\\ - --disable-crypto-afalg \\\ - --disable-curl \\\ - --disable-curses \\\ - --disable-debug-info \\\ - --disable-debug-mutex \\\ - --disable-debug-tcg \\\ - --disable-dmg \\\ - --disable-docs \\\ - --disable-dsound \\\ - --disable-fdt \\\ - --disable-fuse \\\ - --disable-fuse-lseek \\\ - --disable-gcrypt \\\ - --disable-gettext \\\ - --disable-gio \\\ - --disable-glusterfs \\\ - --disable-gnutls \\\ - --disable-gtk \\\ - --disable-guest-agent \\\ - --disable-guest-agent-msi \\\ - --disable-hax \\\ - --disable-hvf \\\ - --disable-iconv \\\ - --disable-jack \\\ - --disable-kvm \\\ - --disable-l2tpv3 \\\ - --disable-libdaxctl \\\ - --disable-libiscsi \\\ - --disable-libnfs \\\ - --disable-libpmem \\\ - --disable-libssh \\\ - --disable-libudev \\\ - --disable-libusb \\\ - --disable-linux-aio \\\ - --disable-linux-io-uring \\\ - --disable-linux-user \\\ - --disable-live-block-migration \\\ - --disable-lto \\\ - --disable-lzfse \\\ - --disable-lzo \\\ - --disable-malloc-trim \\\ - --disable-membarrier \\\ - --disable-modules \\\ - --disable-module-upgrades \\\ - --disable-mpath \\\ - --disable-multiprocess \\\ - --disable-netmap \\\ - --disable-nettle \\\ - --disable-numa \\\ - --disable-nvmm \\\ - --disable-opengl \\\ - --disable-oss \\\ - --disable-pa \\\ - --disable-parallels \\\ - --disable-pie \\\ - --disable-pvrdma \\\ - --disable-qcow1 \\\ - --disable-qed \\\ - --disable-qom-cast-debug \\\ - --disable-rbd \\\ - --disable-rdma \\\ - --disable-replication \\\ - --disable-rng-none \\\ - --disable-safe-stack \\\ - --disable-sanitizers \\\ - --disable-sdl \\\ - --disable-sdl-image \\\ - --disable-seccomp \\\ - --disable-selinux \\\ - --disable-slirp \\\ - --disable-slirp-smbd \\\ - --disable-smartcard \\\ - --disable-snappy \\\ - --disable-sparse \\\ - --disable-spice \\\ - --disable-spice-protocol \\\ - --disable-strip \\\ - --disable-system \\\ - --disable-tcg \\\ - --disable-tools \\\ - --disable-tpm \\\ - --disable-u2f \\\ - --disable-usb-redir \\\ - --disable-user \\\ - --disable-vde \\\ - --disable-vdi \\\ - --disable-vhost-crypto \\\ - --disable-vhost-kernel \\\ - --disable-vhost-net \\\ - --disable-vhost-scsi \\\ - --disable-vhost-user \\\ - --disable-vhost-user-blk-server \\\ - --disable-vhost-vdpa \\\ - --disable-vhost-vsock \\\ - --disable-virglrenderer \\\ - --disable-virtfs \\\ - --disable-virtiofsd \\\ - --disable-vnc \\\ - --disable-vnc-jpeg \\\ - --disable-vnc-png \\\ - --disable-vnc-sasl \\\ - --disable-vte \\\ - --disable-vvfat \\\ - --disable-werror \\\ - --disable-whpx \\\ - --disable-xen \\\ - --disable-xen-pci-passthrough \\\ - --disable-xkbcommon \\\ - --disable-zstd \\\ - --with-git-submodules=ignore \\\ - --without-default-devices - -run_configure() { - ../configure \ - --cc=%{__cc} \ - --cxx=/bin/false \ - --prefix="%{_prefix}" \ - --libdir="%{_libdir}" \ - --datadir="%{_datadir}" \ - --sysconfdir="%{_sysconfdir}" \ - --interp-prefix=%{_prefix}/qemu-%M \ - --localstatedir="%{_localstatedir}" \ - --docdir="%{_docdir}" \ - --libexecdir="%{_libexecdir}" \ - --extra-ldflags="%{build_ldflags}" \ -%ifnarch %{arm} - --extra-cflags="%{optflags}" \ -%else - --extra-cflags="%{optflags} -DSTAP_SDT_ARG_CONSTRAINT=g" \ -%endif - --with-pkgversion="%{name}-%{version}-%{release}" \ - --with-suffix="%{name}" \ - --firmwarepath="%firmwaredirs" \ - --meson="%{__meson}" \ - --enable-trace-backends=dtrace \ - --with-coroutine=ucontext \ - --with-git=git \ - --tls-priority=@QEMU,SYSTEM \ - %{disable_everything} \ - "$@" - - echo "config-host.mak contents:" - echo "===" - cat config-host.mak - echo "===" -} - - -pushd %{qemu_kvm_build} -run_configure \ -%if %{defined target_list} - --target-list="%{target_list}" \ -%endif -%if %{defined block_drivers_rw_list} - --block-drv-rw-whitelist=%{block_drivers_rw_list} \ -%endif -%if %{defined block_drivers_ro_list} - --block-drv-ro-whitelist=%{block_drivers_ro_list} \ -%endif - --enable-attr \ -%ifarch %{ix86} x86_64 - --enable-avx2 \ -%endif - --enable-bpf \ - --enable-cap-ng \ - --enable-capstone=auto \ - --enable-coroutine-pool \ - --enable-curl \ - --enable-debug-info \ - --enable-docs \ -%if %{have_fdt} - --enable-fdt=system \ -%endif - --enable-gettext \ - --enable-gnutls \ - --enable-guest-agent \ - --enable-iconv \ - --enable-jack \ - --enable-kvm \ - --enable-l2tpv3 \ - --enable-libiscsi \ -%if %{have_pmem} - --enable-libpmem \ -%endif - --enable-libssh \ - --enable-libusb \ - --enable-libudev \ - --enable-linux-aio \ -%if "%{_lto_cflags}" != "%{nil}" - --enable-lto \ -%endif - --enable-lzo \ - --enable-malloc-trim \ - --enable-modules \ - --enable-mpath \ -%if %{have_numactl} - --enable-numa \ -%endif -%if %{have_opengl} - --enable-opengl \ -%endif - --enable-oss \ - --enable-pa \ - --enable-pie \ -%if %{have_block_rbd} - --enable-rbd \ -%endif -%if %{have_librdma} - --enable-rdma \ -%endif - --enable-seccomp \ - --enable-selinux \ - --enable-slirp=system \ - --enable-slirp-smbd \ - --enable-snappy \ - --enable-system \ - --enable-tcg \ - --enable-tools \ - --enable-tpm \ -%if %{have_usbredir} - --enable-usb-redir \ -%endif - --enable-virtiofsd \ - --enable-vhost-kernel \ - --enable-vhost-net \ - --enable-vhost-user \ - --enable-vhost-user-blk-server \ - --enable-vhost-vdpa \ - --enable-vhost-vsock \ - --enable-vnc \ - --enable-vnc-png \ - --enable-vnc-sasl \ -%if %{enable_werror} - --enable-werror \ -%endif - --enable-xkbcommon \ - \ - \ - --audio-drv-list=pa,sdl,alsa,%{?jack_drv}oss \ - --target-list-exclude=moxie-softmmu \ - --with-default-devices \ - --enable-auth-pam \ - --enable-bochs \ - --enable-brlapi \ - --enable-bzip2 \ - --enable-cloop \ - --enable-curses \ - --enable-dmg \ - --enable-fuse \ - --enable-gio \ -%if %{have_block_gluster} - --enable-glusterfs \ -%endif - --enable-gtk \ - --enable-libdaxctl \ -%if %{have_block_nfs} - --enable-libnfs \ -%endif - --enable-libudev \ -%if %{have_liburing} - --enable-linux-io-uring \ -%endif - --enable-linux-user \ - --enable-live-block-migration \ - --enable-multiprocess \ - --enable-vnc-jpeg \ - --enable-parallels \ -%if %{have_librdma} - --enable-pvrdma \ -%endif - --enable-qcow1 \ - --enable-qed \ - --enable-qom-cast-debug \ - --enable-replication \ - --enable-sdl \ -%if %{have_sdl_image} - --enable-sdl-image \ -%endif -%if %{have_libcacard} - --enable-smartcard \ -%endif -%if %{have_spice} - --enable-spice \ - --enable-spice-protocol \ -%endif - --enable-usb-redir \ - --enable-vdi \ - --enable-vhost-crypto \ - --enable-vhost-scsi \ -%if %{have_virgl} - --enable-virglrenderer \ -%endif - --enable-virtfs \ - --enable-vnc-jpeg \ - --enable-vte \ - --enable-vvfat \ -%if %{have_xen} - --enable-xen \ - --enable-xen-pci-passthrough \ -%endif - --enable-zstd \ - - -%if %{tools_only} -%make_build qemu-img -%make_build qemu-io -%make_build qemu-nbd -%make_build storage-daemon/qemu-storage-daemon - -%make_build docs/qemu-img.1 -%make_build docs/qemu-nbd.8 -%make_build docs/qemu-storage-daemon.1 -%make_build docs/qemu-storage-daemon-qmp-ref.7 - -%make_build qga/qemu-ga -%make_build docs/qemu-ga.8 -# endif tools_only -%endif - - -%if !%{tools_only} -%make_build -popd - -# Fedora build for qemu-user-static -%if %{user_static} -pushd %{static_builddir} - -run_configure \ - --enable-attr \ - --enable-linux-user \ - --enable-tcg \ - --disable-install-blobs \ - --static - -%make_build -popd # static -%endif -# endif !tools_only -%endif - - - -%install -# Install qemu-guest-agent service and udev rules -install -D -m 0644 %{_sourcedir}/qemu-guest-agent.service %{buildroot}%{_unitdir}/qemu-guest-agent.service -install -D -m 0644 %{_sourcedir}/qemu-ga.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/qemu-ga -install -D -m 0644 %{_sourcedir}/99-qemu-guest-agent.rules %{buildroot}%{_udevrulesdir}/99-qemu-guest-agent.rules - - -# Install qemu-ga fsfreeze bits -mkdir -p %{buildroot}%{_sysconfdir}/qemu-ga/fsfreeze-hook.d -install -p scripts/qemu-guest-agent/fsfreeze-hook %{buildroot}%{_sysconfdir}/qemu-ga/fsfreeze-hook -mkdir -p %{buildroot}%{_datadir}/%{name}/qemu-ga/fsfreeze-hook.d/ -install -p -m 0644 scripts/qemu-guest-agent/fsfreeze-hook.d/*.sample %{buildroot}%{_datadir}/%{name}/qemu-ga/fsfreeze-hook.d/ -mkdir -p -v %{buildroot}%{_localstatedir}/log/qemu-ga/ - - -%if %{tools_only} -pushd %{qemu_kvm_build} -install -D -p -m 0755 qga/qemu-ga %{buildroot}%{_bindir}/qemu-ga -install -D -p -m 0755 qemu-img %{buildroot}%{_bindir}/qemu-img -install -D -p -m 0755 qemu-io %{buildroot}%{_bindir}/qemu-io -install -D -p -m 0755 qemu-nbd %{buildroot}%{_bindir}/qemu-nbd -install -D -p -m 0755 storage-daemon/qemu-storage-daemon %{buildroot}%{_bindir}/qemu-storage-daemon - -mkdir -p %{buildroot}%{_mandir}/man1/ -mkdir -p %{buildroot}%{_mandir}/man7/ -mkdir -p %{buildroot}%{_mandir}/man8/ - -install -D -p -m 644 docs/qemu-img.1* %{buildroot}%{_mandir}/man1 -install -D -p -m 644 docs/qemu-nbd.8* %{buildroot}%{_mandir}/man8 -install -D -p -m 644 docs/qemu-storage-daemon.1* %{buildroot}%{_mandir}/man1 -install -D -p -m 644 docs/qemu-storage-daemon-qmp-ref.7* %{buildroot}%{_mandir}/man7 -install -D -p -m 644 docs/qemu-ga.8* %{buildroot}%{_mandir}/man8 -popd -# endif tools_only -%endif - - -%if !%{tools_only} -# Install rules to use the bridge helper with libvirt's virbr0 -install -D -m 0644 %{_sourcedir}/bridge.conf %{buildroot}%{_sysconfdir}/%{name}/bridge.conf - -# Install qemu-pr-helper service -install -m 0644 contrib/systemd/qemu-pr-helper.service %{buildroot}%{_unitdir} -install -m 0644 contrib/systemd/qemu-pr-helper.socket %{buildroot}%{_unitdir} - -%if %{have_memlock_limits} -install -D -p -m 644 %{_sourcedir}/95-kvm-memlock.conf %{buildroot}%{_sysconfdir}/security/limits.d/95-kvm-memlock.conf -%endif - -%if %{have_kvm} -install -D -p -m 0644 %{_sourcedir}/vhost.conf %{buildroot}%{_sysconfdir}/modprobe.d/vhost.conf -install -D -p -m 0644 %{modprobe_kvm_conf} %{buildroot}%{_sysconfdir}/modprobe.d/kvm.conf -%endif - -# Copy some static data into place -install -D -p -m 0644 -t %{buildroot}%{qemudocdir} README.rst COPYING COPYING.LIB LICENSE docs/interop/qmp-spec.txt -install -D -p -m 0644 qemu.sasl %{buildroot}%{_sysconfdir}/sasl2/%{name}.conf - -install -m 0644 scripts/dump-guest-memory.py %{buildroot}%{_datadir}/%{name} - - -# Install simpletrace -install -m 0755 scripts/simpletrace.py %{buildroot}%{_datadir}/%{name}/simpletrace.py -mkdir -p %{buildroot}%{_datadir}/%{name}/tracetool -install -m 0644 -t %{buildroot}%{_datadir}/%{name}/tracetool scripts/tracetool/*.py -mkdir -p %{buildroot}%{_datadir}/%{name}/tracetool/backend -install -m 0644 -t %{buildroot}%{_datadir}/%{name}/tracetool/backend scripts/tracetool/backend/*.py -mkdir -p %{buildroot}%{_datadir}/%{name}/tracetool/format -install -m 0644 -t %{buildroot}%{_datadir}/%{name}/tracetool/format scripts/tracetool/format/*.py - - -# Create new directories and put them all under tests-src -mkdir -p %{buildroot}%{testsdir}/python -mkdir -p %{buildroot}%{testsdir}/tests -mkdir -p %{buildroot}%{testsdir}/tests/avocado -mkdir -p %{buildroot}%{testsdir}/tests/qemu-iotests -mkdir -p %{buildroot}%{testsdir}/scripts/qmp - -# Install avocado_qemu tests -cp -R %{qemu_kvm_build}/tests/avocado/* %{buildroot}%{testsdir}/tests/avocado/ - -# Install qemu.py and qmp/ scripts required to run avocado_qemu tests -cp -R %{qemu_kvm_build}/python/qemu %{buildroot}%{testsdir}/python -cp -R %{qemu_kvm_build}/scripts/qmp/* %{buildroot}%{testsdir}/scripts/qmp -install -p -m 0755 tests/Makefile.include %{buildroot}%{testsdir}/tests/ - -# Install qemu-iotests -cp -R tests/qemu-iotests/* %{buildroot}%{testsdir}/tests/qemu-iotests/ -cp -ur %{qemu_kvm_build}/tests/qemu-iotests/* %{buildroot}%{testsdir}/tests/qemu-iotests/ - -# Install our custom tests README -install -p -m 0644 %{_sourcedir}/README.tests %{buildroot}%{testsdir}/README - - -# Do the actual qemu tree install -pushd %{qemu_kvm_build} -%make_install -popd - - -# We need to make the block device modules and other qemu SO files executable -# otherwise RPM won't pick up their dependencies. -chmod +x %{buildroot}%{_libdir}/%{name}/*.so - -# Remove docs we don't care about -find %{buildroot}%{qemudocdir} -name .buildinfo -delete -rm -rf %{buildroot}%{qemudocdir}/specs - - -# Provided by package openbios -rm -rf %{buildroot}%{_datadir}/%{name}/openbios-ppc -rm -rf %{buildroot}%{_datadir}/%{name}/openbios-sparc32 -rm -rf %{buildroot}%{_datadir}/%{name}/openbios-sparc64 -# Provided by package SLOF -rm -rf %{buildroot}%{_datadir}/%{name}/slof.bin -# Provided by package ipxe -rm -rf %{buildroot}%{_datadir}/%{name}/pxe*rom -rm -rf %{buildroot}%{_datadir}/%{name}/efi*rom -# Provided by package seavgabios -rm -rf %{buildroot}%{_datadir}/%{name}/vgabios*bin -# Provided by package seabios -rm -rf %{buildroot}%{_datadir}/%{name}/bios*.bin -# Provided by package sgabios -rm -rf %{buildroot}%{_datadir}/%{name}/sgabios.bin -# Provided by edk2 -rm -rf %{buildroot}%{_datadir}/%{name}/edk2* -rm -rf %{buildroot}%{_datadir}/%{name}/firmware - -# Fedora specific stuff below -%find_lang %{name} - -# Generate qemu-system-* man pages -chmod -x %{buildroot}%{_mandir}/man1/* -for emu in %{buildroot}%{_bindir}/qemu-system-*; do - ln -sf qemu.1.gz %{buildroot}%{_mandir}/man1/$(basename $emu).1.gz - done - -# Install kvm specific source bits, and qemu-kvm manpage -%if %{need_qemu_kvm} -ln -sf qemu.1.gz %{buildroot}%{_mandir}/man1/qemu-kvm.1.gz -ln -sf qemu-system-x86_64 %{buildroot}%{_bindir}/qemu-kvm -ln -sf %{_bindir}/qemu-system-x86_64 %{buildroot}%{_libexecdir}/qemu-kvm -%endif - - -# Install binfmt -%global binfmt_dir %{buildroot}%{_exec_prefix}/lib/binfmt.d -mkdir -p %{binfmt_dir} - -./scripts/qemu-binfmt-conf.sh --systemd ALL --exportdir %{binfmt_dir} --qemu-path %{_bindir} -for i in %{binfmt_dir}/*; do mv $i $(echo $i | sed 's/.conf/-dynamic.conf/'); done - - -# Install qemu-user-static tree -%if %{user_static} -%define static_buildroot %{buildroot}/static/ -mkdir -p %{static_buildroot} - -pushd %{static_builddir} -make DESTDIR=%{static_buildroot} install - -# Duplicates what the main build installs and we don't -# need second copy with a -static suffix -rm -f %{static_buildroot}%{_bindir}/qemu-trace-stap -popd # static - -# Rename all QEMU user emulators to have a -static suffix -for src in %{static_buildroot}%{_bindir}/qemu-*; do - mv $src %{buildroot}%{_bindir}/$(basename $src)-static; done - -# Rename trace files to match -static suffix -for src in %{static_buildroot}%{_datadir}/systemtap/tapset/qemu-*.stp; do - dst=`echo $src | sed -e 's/.stp/-static.stp/'` - mv $src $dst - perl -i -p -e 's/(qemu-\w+)/$1-static/g; s/(qemu\.user\.\w+)/$1.static/g' $dst - mv $dst %{buildroot}%{_datadir}/systemtap/tapset - done - -for regularfmt in %{binfmt_dir}/*; do - staticfmt="$(echo $regularfmt | sed 's/-dynamic/-static/g')" - cat $regularfmt | tr -d '\n' | sed "s/:$/-static:F/" > $staticfmt - done - -rm -rf %{static_buildroot} -# endif user_static - %endif -# end Fedora specific -# endif !tools_only -%endif - - - -%check -%if %{with check} -%if !%{tools_only} - -pushd %{qemu_kvm_build} -echo "Testing %{name}-build" -# 2021-09: s390x tests randomly failing with 'Broken pipe' errors -# dhorak couldn't reproduce locally on an s390x machine so guessed -# it's a resource issue -# 2021-09: ppc64le intermittently hanging with no discernable pattern -%ifnarch s390x %{power64} -%make_build check -%endif - -popd - -# endif !tools_only -%endif -# endif with check -%endif - - -%post -n qemu-guest-agent -%systemd_post qemu-guest-agent.service -%preun -n qemu-guest-agent -%systemd_preun qemu-guest-agent.service -%postun -n qemu-guest-agent -%systemd_postun_with_restart qemu-guest-agent.service - - -%if !%{tools_only} -%post common -getent group kvm >/dev/null || groupadd -g 36 -r kvm -getent group qemu >/dev/null || groupadd -g 107 -r qemu -getent passwd qemu >/dev/null || \ -useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ - -c "qemu user" qemu - - - - - - -%post user-binfmt -/bin/systemctl --system try-restart systemd-binfmt.service &>/dev/null || : -%postun user-binfmt -/bin/systemctl --system try-restart systemd-binfmt.service &>/dev/null || : - -%if %{user_static} -%post user-static -/bin/systemctl --system try-restart systemd-binfmt.service &>/dev/null || : -%postun user-static -/bin/systemctl --system try-restart systemd-binfmt.service &>/dev/null || : -%endif -# endif !tools_only -%endif - - - -%files -n qemu-img -%{_bindir}/qemu-img -%{_bindir}/qemu-io -%{_bindir}/qemu-nbd -%{_bindir}/qemu-storage-daemon -%{_mandir}/man1/qemu-img.1* -%{_mandir}/man8/qemu-nbd.8* -%{_mandir}/man1/qemu-storage-daemon.1* -%{_mandir}/man7/qemu-storage-daemon-qmp-ref.7* - - -%files -n qemu-guest-agent -%doc COPYING README.rst -%{_bindir}/qemu-ga -%{_mandir}/man8/qemu-ga.8* -%{_unitdir}/qemu-guest-agent.service -%{_udevrulesdir}/99-qemu-guest-agent.rules -%config(noreplace) %{_sysconfdir}/sysconfig/qemu-ga -%{_sysconfdir}/qemu-ga -%{_datadir}/%{name}/qemu-ga -%dir %{_localstatedir}/log/qemu-ga - - -%if !%{tools_only} -%files -# Deliberately empty - - -%files -n qemu-pr-helper -%{_bindir}/qemu-pr-helper -%{_unitdir}/qemu-pr-helper.service -%{_unitdir}/qemu-pr-helper.socket -%{_mandir}/man8/qemu-pr-helper.8* - - -%files -n qemu-virtiofsd -%{_mandir}/man1/virtiofsd.1* -%{_libexecdir}/virtiofsd -%{_datadir}/qemu/vhost-user/50-qemu-virtiofsd.json - - -%files tools -%{_bindir}/qemu-keymap -%{_bindir}/qemu-edid -%{_bindir}/qemu-trace-stap -%{_datadir}/%{name}/simpletrace.py* -%{_datadir}/%{name}/tracetool/*.py* -%{_datadir}/%{name}/tracetool/backend/*.py* -%{_datadir}/%{name}/tracetool/format/*.py* -%{_datadir}/%{name}/dump-guest-memory.py* -%{_datadir}/%{name}/trace-events-all -%{_mandir}/man1/qemu-trace-stap.1* -# Fedora specific -%{_bindir}/elf2dmp - - -%files docs -%doc %{qemudocdir} - - -%files common -f %{name}.lang -%license COPYING COPYING.LIB LICENSE -%dir %{_datadir}/%{name}/ -%{_datadir}/icons/* -%{_datadir}/%{name}/keymaps/ -%{_datadir}/%{name}/linuxboot_dma.bin -%attr(4755, -, -) %{_libexecdir}/qemu-bridge-helper -%{_mandir}/man1/%{name}.1* -%{_mandir}/man7/qemu-block-drivers.7* -%{_mandir}/man7/qemu-cpu-models.7* -%{_mandir}/man7/qemu-ga-ref.7* -%{_mandir}/man7/qemu-qmp-ref.7* -%dir %{_sysconfdir}/%{name} -%config(noreplace) %{_sysconfdir}/%{name}/bridge.conf -%if %{have_kvm} -%config(noreplace) %{_sysconfdir}/modprobe.d/kvm.conf -%config(noreplace) %{_sysconfdir}/modprobe.d/vhost.conf -%endif -%config(noreplace) %{_sysconfdir}/sasl2/%{name}.conf - - -# Fedora specific -%{_datadir}/applications/qemu.desktop -%exclude %{_datadir}/%{name}/qemu-nsis.bmp -%{_libexecdir}/virtfs-proxy-helper -%{_mandir}/man1/virtfs-proxy-helper.1* - - -%files tests -%{testsdir} -%{_libdir}/%{name}/accel-qtest-*.so - -%files block-curl -%{_libdir}/%{name}/block-curl.so -%files block-iscsi -%{_libdir}/%{name}/block-iscsi.so -%if %{have_block_rbd} -%files block-rbd -%{_libdir}/%{name}/block-rbd.so -%endif -%files block-ssh -%{_libdir}/%{name}/block-ssh.so - -%if %{have_opengl} -%files ui-opengl -%{_libdir}/%{name}/ui-opengl.so -%endif - - -%files block-dmg -%{_libdir}/%{name}/block-dmg-bz2.so -%if %{have_block_gluster} -%files block-gluster -%{_libdir}/%{name}/block-gluster.so -%endif -%if %{have_block_nfs} -%files block-nfs -%{_libdir}/%{name}/block-nfs.so -%endif - -%files audio-alsa -%{_libdir}/%{name}/audio-alsa.so -%files audio-oss -%{_libdir}/%{name}/audio-oss.so -%files audio-pa -%{_libdir}/%{name}/audio-pa.so -%files audio-sdl -%{_libdir}/%{name}/audio-sdl.so -%if %{have_jack} -%files audio-jack -%{_libdir}/%{name}/audio-jack.so -%endif - - -%files ui-curses -%{_libdir}/%{name}/ui-curses.so -%files ui-gtk -%{_libdir}/%{name}/ui-gtk.so -%files ui-sdl -%{_libdir}/%{name}/ui-sdl.so -%files ui-egl-headless -%{_libdir}/%{name}/ui-egl-headless.so - -%files char-baum -%{_libdir}/%{name}/chardev-baum.so - - -%files device-display-virtio-gpu -%{_libdir}/%{name}/hw-display-virtio-gpu.so -%files device-display-virtio-gpu-gl -%{_libdir}/%{name}/hw-display-virtio-gpu-gl.so -%files device-display-virtio-gpu-pci -%{_libdir}/%{name}/hw-display-virtio-gpu-pci.so -%files device-display-virtio-gpu-pci-gl -%{_libdir}/%{name}/hw-display-virtio-gpu-pci-gl.so -%files device-display-virtio-gpu-ccw -%{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so -%files device-display-virtio-vga -%{_libdir}/%{name}/hw-display-virtio-vga.so -%files device-display-virtio-vga-gl -%{_libdir}/%{name}/hw-display-virtio-vga-gl.so -%files device-usb-host -%{_libdir}/%{name}/hw-usb-host.so -%files device-usb-redirect -%{_libdir}/%{name}/hw-usb-redirect.so -%if %{have_libcacard} -%files device-usb-smartcard -%{_libdir}/%{name}/hw-usb-smartcard.so -%endif - - -%if %{have_virgl} -%files device-display-vhost-user-gpu -%{_datadir}/%{name}/vhost-user/50-qemu-gpu.json -%{_libexecdir}/vhost-user-gpu -%endif - -%if %{have_spice} -%files audio-spice -%{_libdir}/%{name}/audio-spice.so -%files char-spice -%{_libdir}/%{name}/chardev-spice.so -%files device-display-qxl -%{_libdir}/%{name}/hw-display-qxl.so -%files ui-spice-core -%{_libdir}/%{name}/ui-spice-core.so -%files ui-spice-app -%{_libdir}/%{name}/ui-spice-app.so -%endif - - -%if %{have_kvm} -%files kvm -%{_libexecdir}/qemu-kvm - -%files kvm-core -# Deliberately empty -%endif - - -%files user -%{_bindir}/qemu-i386 -%{_bindir}/qemu-x86_64 -%{_bindir}/qemu-aarch64 -%{_bindir}/qemu-aarch64_be -%{_bindir}/qemu-alpha -%{_bindir}/qemu-arm -%{_bindir}/qemu-armeb -%{_bindir}/qemu-cris -%{_bindir}/qemu-hppa -%{_bindir}/qemu-hexagon -%{_bindir}/qemu-m68k -%{_bindir}/qemu-microblaze -%{_bindir}/qemu-microblazeel -%{_bindir}/qemu-mips -%{_bindir}/qemu-mipsel -%{_bindir}/qemu-mips64 -%{_bindir}/qemu-mips64el -%{_bindir}/qemu-mipsn32 -%{_bindir}/qemu-mipsn32el -%{_bindir}/qemu-nios2 -%{_bindir}/qemu-or1k -%{_bindir}/qemu-ppc -%{_bindir}/qemu-ppc64 -%{_bindir}/qemu-ppc64le -%{_bindir}/qemu-riscv32 -%{_bindir}/qemu-riscv64 -%{_bindir}/qemu-s390x -%{_bindir}/qemu-sh4 -%{_bindir}/qemu-sh4eb -%{_bindir}/qemu-sparc -%{_bindir}/qemu-sparc32plus -%{_bindir}/qemu-sparc64 -%{_bindir}/qemu-xtensa -%{_bindir}/qemu-xtensaeb - -%{_datadir}/systemtap/tapset/qemu-i386*.stp -%{_datadir}/systemtap/tapset/qemu-x86_64*.stp -%{_datadir}/systemtap/tapset/qemu-aarch64*.stp -%{_datadir}/systemtap/tapset/qemu-alpha*.stp -%{_datadir}/systemtap/tapset/qemu-arm*.stp -%{_datadir}/systemtap/tapset/qemu-cris*.stp -%{_datadir}/systemtap/tapset/qemu-hppa*.stp -%{_datadir}/systemtap/tapset/qemu-hexagon*.stp -%{_datadir}/systemtap/tapset/qemu-m68k*.stp -%{_datadir}/systemtap/tapset/qemu-microblaze*.stp -%{_datadir}/systemtap/tapset/qemu-mips*.stp -%{_datadir}/systemtap/tapset/qemu-nios2*.stp -%{_datadir}/systemtap/tapset/qemu-or1k*.stp -%{_datadir}/systemtap/tapset/qemu-ppc*.stp -%{_datadir}/systemtap/tapset/qemu-riscv*.stp -%{_datadir}/systemtap/tapset/qemu-s390x*.stp -%{_datadir}/systemtap/tapset/qemu-sh4*.stp -%{_datadir}/systemtap/tapset/qemu-sparc*.stp -%{_datadir}/systemtap/tapset/qemu-xtensa*.stp - - -%files user-binfmt -%{_exec_prefix}/lib/binfmt.d/qemu-*-dynamic.conf - -%if %{user_static} -%files user-static -%license COPYING COPYING.LIB LICENSE -# Just use wildcard matches here: we will catch any new/missing files -# in the qemu-user filelists -%{_exec_prefix}/lib/binfmt.d/qemu-*-static.conf -%{_bindir}/qemu-*-static -%{_datadir}/systemtap/tapset/qemu-*-static.stp -%endif - - -%files system-aarch64 -%files system-aarch64-core -%{_bindir}/qemu-system-aarch64 -%{_datadir}/systemtap/tapset/qemu-system-aarch64*.stp -%{_mandir}/man1/qemu-system-aarch64.1* - - -%files system-alpha -%files system-alpha-core -%{_bindir}/qemu-system-alpha -%{_datadir}/systemtap/tapset/qemu-system-alpha*.stp -%{_mandir}/man1/qemu-system-alpha.1* -%{_datadir}/%{name}/palcode-clipper - - -%files system-arm -%files system-arm-core -%{_bindir}/qemu-system-arm -%{_datadir}/%{name}/npcm7xx_bootrom.bin -%{_datadir}/systemtap/tapset/qemu-system-arm*.stp -%{_mandir}/man1/qemu-system-arm.1* - - -%files system-avr -%files system-avr-core -%{_bindir}/qemu-system-avr -%{_datadir}/systemtap/tapset/qemu-system-avr*.stp -%{_mandir}/man1/qemu-system-avr.1* - - -%files system-cris -%files system-cris-core -%{_bindir}/qemu-system-cris -%{_datadir}/systemtap/tapset/qemu-system-cris*.stp -%{_mandir}/man1/qemu-system-cris.1* - - -%files system-hppa -%files system-hppa-core -%{_bindir}/qemu-system-hppa -%{_datadir}/systemtap/tapset/qemu-system-hppa*.stp -%{_mandir}/man1/qemu-system-hppa.1* -%{_datadir}/%{name}/hppa-firmware.img - - -%files system-m68k -%files system-m68k-core -%{_bindir}/qemu-system-m68k -%{_datadir}/systemtap/tapset/qemu-system-m68k*.stp -%{_mandir}/man1/qemu-system-m68k.1* - - -%files system-microblaze -%files system-microblaze-core -%{_bindir}/qemu-system-microblaze -%{_bindir}/qemu-system-microblazeel -%{_datadir}/systemtap/tapset/qemu-system-microblaze*.stp -%{_mandir}/man1/qemu-system-microblaze.1* -%{_mandir}/man1/qemu-system-microblazeel.1* -%{_datadir}/%{name}/petalogix*.dtb - - -%files system-mips -%files system-mips-core -%{_bindir}/qemu-system-mips -%{_bindir}/qemu-system-mipsel -%{_bindir}/qemu-system-mips64 -%{_bindir}/qemu-system-mips64el -%{_datadir}/systemtap/tapset/qemu-system-mips*.stp -%{_mandir}/man1/qemu-system-mips.1* -%{_mandir}/man1/qemu-system-mipsel.1* -%{_mandir}/man1/qemu-system-mips64el.1* -%{_mandir}/man1/qemu-system-mips64.1* - - -%files system-nios2 -%files system-nios2-core -%{_bindir}/qemu-system-nios2 -%{_datadir}/systemtap/tapset/qemu-system-nios2*.stp -%{_mandir}/man1/qemu-system-nios2.1* - - -%files system-or1k -%files system-or1k-core -%{_bindir}/qemu-system-or1k -%{_datadir}/systemtap/tapset/qemu-system-or1k*.stp -%{_mandir}/man1/qemu-system-or1k.1* - - -%files system-ppc -%files system-ppc-core -%{_bindir}/qemu-system-ppc -%{_bindir}/qemu-system-ppc64 -%{_datadir}/systemtap/tapset/qemu-system-ppc*.stp -%{_mandir}/man1/qemu-system-ppc.1* -%{_mandir}/man1/qemu-system-ppc64.1* -%{_datadir}/%{name}/bamboo.dtb -%{_datadir}/%{name}/canyonlands.dtb -%{_datadir}/%{name}/qemu_vga.ndrv -%{_datadir}/%{name}/skiboot.lid -%{_datadir}/%{name}/u-boot.e500 -%{_datadir}/%{name}/u-boot-sam460-20100605.bin -%{_datadir}/%{name}/vof*.bin -%if %{have_memlock_limits} -%{_sysconfdir}/security/limits.d/95-kvm-memlock.conf -%endif - - -%files system-riscv -%files system-riscv-core -%{_bindir}/qemu-system-riscv32 -%{_bindir}/qemu-system-riscv64 -%{_datadir}/%{name}/opensbi-riscv*.bin -%{_datadir}/systemtap/tapset/qemu-system-riscv*.stp -%{_mandir}/man1/qemu-system-riscv*.1* - - -%files system-rx -%files system-rx-core -%{_bindir}/qemu-system-rx -%{_datadir}/systemtap/tapset/qemu-system-rx*.stp -%{_mandir}/man1/qemu-system-rx.1* - - -%files system-s390x -%files system-s390x-core -%{_bindir}/qemu-system-s390x -%{_datadir}/systemtap/tapset/qemu-system-s390x*.stp -%{_mandir}/man1/qemu-system-s390x.1* -%{_datadir}/%{name}/s390-ccw.img -%{_datadir}/%{name}/s390-netboot.img - - -%files system-sh4 -%files system-sh4-core -%{_bindir}/qemu-system-sh4 -%{_bindir}/qemu-system-sh4eb -%{_datadir}/systemtap/tapset/qemu-system-sh4*.stp -%{_mandir}/man1/qemu-system-sh4.1* -%{_mandir}/man1/qemu-system-sh4eb.1* - - -%files system-sparc -%files system-sparc-core -%{_bindir}/qemu-system-sparc -%{_bindir}/qemu-system-sparc64 -%{_datadir}/systemtap/tapset/qemu-system-sparc*.stp -%{_mandir}/man1/qemu-system-sparc.1* -%{_mandir}/man1/qemu-system-sparc64.1* -%{_datadir}/%{name}/QEMU,tcx.bin -%{_datadir}/%{name}/QEMU,cgthree.bin - - -%files system-tricore -%files system-tricore-core -%{_bindir}/qemu-system-tricore -%{_datadir}/systemtap/tapset/qemu-system-tricore*.stp -%{_mandir}/man1/qemu-system-tricore.1* - - -%files system-x86 -%files system-x86-core -%{_bindir}/qemu-system-i386 -%{_bindir}/qemu-system-x86_64 -%{_libdir}/%{name}/accel-tcg-i386.so -%{_libdir}/%{name}/accel-tcg-x86_64.so -%{_datadir}/systemtap/tapset/qemu-system-i386*.stp -%{_datadir}/systemtap/tapset/qemu-system-x86_64*.stp -%{_mandir}/man1/qemu-system-i386.1* -%{_mandir}/man1/qemu-system-x86_64.1* -%{_datadir}/%{name}/kvmvapic.bin -%{_datadir}/%{name}/linuxboot.bin -%{_datadir}/%{name}/multiboot.bin -%{_datadir}/%{name}/multiboot_dma.bin -%{_datadir}/%{name}/pvh.bin -%{_datadir}/%{name}/qboot.rom -%if %{need_qemu_kvm} -%{_bindir}/qemu-kvm -%{_mandir}/man1/qemu-kvm.1* -%endif - - -%files system-xtensa -%files system-xtensa-core -%{_bindir}/qemu-system-xtensa -%{_bindir}/qemu-system-xtensaeb -%{_datadir}/systemtap/tapset/qemu-system-xtensa*.stp -%{_mandir}/man1/qemu-system-xtensa.1* -%{_mandir}/man1/qemu-system-xtensaeb.1* -# endif !tools_only -%endif - - -%changelog -* Tue May 3 2022 Daniel P. Berrangé - 7.0.0-2 -- Drop redundant qemu-trace-stap copy from qemu-user-static (rhbz#2061584) -- Remove qemu-common dep from qemu-user-static (rhbz#2061584) - -* Fri Apr 08 2022 Eduardo Lima (Etrunko) - 7.0.0-1 -- Rebase to qemu 7.0.0-1 - -* Wed Apr 06 2022 Richard W.M. Jones - 2:6.2.0-8 -- acpi: fix QEMU crash when started with SLIC table (RHBZ#2072303) - -* Fri Apr 01 2022 Neal Gompa - 2:6.2.0-7 -- Backport virtiofsd changes to fix crashes on F36+ - Resolves: rhbz#2070066 - -* Fri Apr 01 2022 Richard W.M. Jones - 2:6.2.0-6 -- Bump and rebuild for SONAME change in libmpathpersist (RHBZ#2069778) - -* Thu Feb 10 2022 Cole Robinson - 6.2.0-5 -- Split out qemu-virtiofsd subpackage - -* Wed Feb 09 2022 Eduardo Lima (Etrunko) - 2:6.2.0-4 -- virtiofsd: Drop membership of all supplementary groups (CVE-2022-0358) - Resolves: rhbz#2044863 - -* Wed Feb 2 2022 Paolo Bonzini - 2:6.2.0-3 -- Fix non-SGX builds - -* Fri Jan 21 2022 Fedora Release Engineering - 2:6.2.0-2.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Tue Jan 11 2022 Richard W.M. Jones - 2:6.2.0-2 -- Bump release and rebuild for new xen - -* Wed Dec 15 2021 Eduardo Lima (Etrunko) - 6.2.0-1 -- Rebase to qemu 6.2.0 - -* Thu Dec 09 2021 Eduardo Lima (Etrunko) - 6.2.0-0.1-rc4 -- Rebase to qemu 6.2.0-rc4 - -* Fri Dec 03 2021 Eduardo Lima (Etrunko) - 6.2.0-0.1-rc3 -- Rebase to qemu 6.2.0-rc3 - -* Thu Nov 25 2021 Daniel P. Berrangé - 6.1.0-13 -- Fix iovec limits with scsi-generic - -* Wed Nov 24 2021 Richard W.M. Jones - 6.1.0-12 -- Add support for qemu-nbd --selinux-relabel option (RHBZ#1984938) -- Define STAP_SDT_ARG_CONSTRAINT=g on %%{arm}, workaround for: - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103395 - -* Mon Nov 08 2021 Adam Williamson - 6.1.0-10 -- Fix snapshot creation with qxl graphics - -* Fri Oct 08 2021 Cole Robinson - 6.1.0-9 -- Fix tcg PVH test with binutils 2.36+ - -* Wed Oct 06 2021 Cole Robinson - 6.1.0-8 -- Fix qemu crash with vnc + libvirt virDomainOpenConsole - -* Sun Sep 12 2021 Richard W.M. Jones - 6.1.0-7 -- Alternate fix for assertion on armv7hl (RHBZ#1999878) - -* Wed Sep 01 2021 Richard W.M. Jones - 6.1.0-6 -- Fix assertion on armv7hl (RHBZ#1999878) - -* Tue Aug 31 2021 Richard W.M. Jones - 6.1.0-5 -- Fix -cpu max (RHBZ#1999700) - -* Fri Aug 27 2021 Richard W.M. Jones - 6.1.0-4 -- Disable gcrypt (for real this time). - -* Fri Aug 27 2021 Richard W.M. Jones - 6.1.0-3 -- Revert "Disable gcrypt" which seems to disable gnutls (RHBZ#1998452) - -* Thu Aug 26 2021 Richard W.M. Jones - 6.1.0-2 -- Fix dependency pci_gl -> pci-gl and vga_gl -> vga-gl (RHBZ#1997855) - -* Tue Aug 24 2021 Eduardo Lima (Etrunko) - 6.1.0-1 -- Rebase to qemu 6.1.0 - -* Tue Aug 10 2021 Eduardo Lima (Etrunko) - 6.1.0-0.3-rc4 -- Rebase to qemu 6.1.0-rc4 - -* Tue Aug 10 2021 Eduardo Lima (Etrunko) - 6.1.0-0.2-rc3 -- Rebase to qemu 6.1.0-rc3 - -* Mon Aug 9 2021 Eduardo Lima (Etrunko) - 6.1.0-0.1-rc2 -- Rebase to qemu 6.1.0-rc2 - -* Thu Jul 29 2021 Cole Robinson - 6.0.0-12 -- Drop python3 shebang fixup for tests rpm -- Parallelize make check -- Explicitly disable c++ build - -* Fri Jul 23 2021 Richard W.M. Jones - 6.0.0-11 -- Fix dependencies of qemu metapackage. - -* Fri Jul 23 2021 Fedora Release Engineering - 2:6.0.0-10.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Sun Jul 18 2021 Cole Robinson - 6.0.0-10 -- Split out qemu-pr-helper and qemu-tools subpackages - -* Wed Jul 07 2021 Cole Robinson - 6.0.0-9 -- Use standard fedora build macros -- Access roms directly in ipxe, seabios, seavgabios directories - -* Wed Jun 30 2021 Cole Robinson - 6.0.0-8 -- Relax meson version to fix building on older Fedora -- More attempts to get CI working - -* Wed Jun 23 2021 Cole Robinson - 6.0.0-7 -- Add qemu-tests package -- Move qemu-sanity-check test to fedora CI -- Add s390x and generic kvm modprobe file from RHEL -- Add vhost modprobe file from RHEL -- Distribute tracetool, simpletrace, dump-guest-memory tools - -* Wed Jun 16 2021 Cole Robinson - 6.0.0-6 -- Build against fuse3 and SDL2_image -- Move qemu-storage-daemon to qemu-img subpackage - -* Mon Jun 07 2021 Cole Robinson - 6.0.0-5 -- Rebuild for xen 4.15 - -* Tue Jun 01 2021 Cole Robinson - 2:6.0.0-4 -- Split out qemu-device-display-vhost-user-gpu subpackage -- Split out qemu-docs subpackage - -* Wed May 19 2021 Paolo Bonzini - 2:6.0.0-3 -- add another patch to fix configuration files - -* Wed May 19 2021 Paolo Bonzini - 2:6.0.0-2 -- fix spice option from configuration file -- fix object option from configuration file -- allow not specifying size in -m when using -M memory-backend - -* Wed May 12 2021 Cole Robinson - 2:6.0.0-1 -- Rebase to qemu 6.0.0 GA - -* Wed Apr 21 2021 Cole Robinson - 2:6.0.0-0.3.rc4 -- Rebase to qemu 6.0.0-rc4 - -* Wed Apr 14 2021 Richard W.M. Jones - 2:6.0.0-0.2.rc2 -- Rebuild for updated liburing. - -* Tue Apr 06 2021 Cole Robinson - 6.0.0-0.1.rc2 -- Rebase to qemu 6.0.0-rc2 - -* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 2:5.2.0-6.1 -- Rebuilt for updated systemd-rpm-macros - See https://pagure.io/fesco/issue/2583. - -* Mon Mar 01 2021 Cole Robinson - 5.2.0-6 -- Fix building on centos stream in copr - -* Wed Jan 27 2021 Fedora Release Engineering - 2:5.2.0-5.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Mon Jan 11 2021 Paolo Bonzini - 2:5.2.0-5 -- Use symlink for qemu-kvm. -- Fix make check on bash 5.1. - -* Fri Dec 11 2020 Richard W.M. Jones - 2:5.2.0-4 -- qemu-char-spice not qemu-chardev-spice. - -* Thu Dec 10 2020 Mohan Boddu - 5.2.0-2 -- Fixing the ISA Dependencies - -* Wed Dec 09 2020 Cole Robinson - 5.2.0-1 -- Rebase to qemu-5.2.0 GA -- Fix spice and GL UI module deps (bz 1904603) - -* Thu Dec 03 2020 Richard W.M. Jones - 5.2.0-0.9.rc4 -- Enable qemu-kvm-core package on riscv64. - -* Thu Dec 03 2020 Cole Robinson - 5.2.0-0.8.rc4 -- Rebase to qemu-5.2.0-rc4 - -* Tue Nov 24 2020 Cole Robinson - 5.2.0-0.7.rc2 -- Fix running 9p tests in copr - -* Thu Nov 19 2020 Paolo Bonzini - 5.2.0-0.6.rc2 -- Remove --python=... to force use of system meson - -* Thu Nov 19 2020 Daniel P. Berrangé - 5.2.0-0.5.rc2 -- Re-enable systemtap tracing - -* Wed Nov 18 2020 Cole Robinson - 5.2.0-0.4.rc2 -- Rebase to qemu-5.2.0-rc2 - -* Fri Nov 13 2020 Daniel P. Berrangé - 5.2.0-0.3.rc1 -- Disable user mode static builds in ELN - -* Wed Nov 11 2020 Cole Robinson - 5.2.0-0.2.rc1 -- Rebase to qemu-5.2.0-rc1 - -* Sun Nov 08 2020 Cole Robinson - 5.2.0-0.1.rc0 -- Rebase to qemu-5.2.0-rc0 - -* Thu Nov 5 2020 Daniel P. Berrangé - 5.1.0-7 -- Disable LTO again. Tests were not passing, we were ignoring failures. - -* Mon Oct 26 2020 Daniel P. Berrangé - 5.1.0-6 -- Re-enable LTO since tests now pass without asserts - -* Fri Sep 4 2020 Daniel P. Berrangé - 5.1.0-5 -- Drop conditions for ppc, ppc64, mips64 and s390 arches -- Fix host qemu binary path for aarch64 -- Re-enable kernel BR for QEMU sanity check -- Fix conditionals for enabling QEMU sanity check -- Check whether emulator works before doing sanity check -- Provide explicit kernel path for QEMU sanity check -- Make QEMU sanity check a build blocker - -* Thu Sep 3 2020 Daniel P. Berrangé - 5.1.0-4 -- Add btrfs ioctls to linux-user (rhbz #1872918) - -* Tue Aug 18 2020 Tom Stellard - 5.1.0-3 -- Add BuildRequires: gcc -- https://fedoraproject.org/wiki/Packaging:C_and_C%2B%2B#BuildRequires_and_Requires - -* Mon Aug 17 2020 Cole Robinson - 5.1.0-2 -- Disable dtrace generation to fix use of modules (bz 1869339) - -* Tue Aug 11 2020 Cole Robinson - 5.1.0-1 -- Update to version 5.1.0 - -* Fri Aug 07 2020 Cole Robinson - 5.1.0-0.3.rc3 -- Update to version 5.1.0-rc3 - -* Thu Aug 06 2020 Merlin Mathesius - 5.1.0-0.2.rc2 -- Use new %%{kernel_arches} macro to determine when a full kernel is available - -* Wed Aug 05 2020 Cole Robinson - 5.1.0-0.2.rc2 -- Pull in new modules by default, like we do for others - -* Tue Aug 04 2020 Cole Robinson - 5.1.0-0.1.rc2 -- Update to qemu 5.1.0 rc2 - -* Fri Jul 31 2020 Daniel P. Berrangé - 5.0.0-6 -- Remove obsolete Fedora conditionals (PR#9) - -* Thu Jul 30 2020 Richard W.M. Jones - 5.0.0-5 -- Disable LTO as it caused many strange assert failures. - -* Wed Jul 29 2020 Richard W.M. Jones - 5.0.0-4 -- Backport Dan's upstream patch to fix insecure cert in test suite. - -* Mon Jul 27 2020 Kevin Fenzi - 5.0.0-3 -- Rebuild for new xen - -* Wed May 13 2020 Cole Robinson - 5.0.0-2 -- Fix iouring hang (bz #1823751) - -* Wed May 06 2020 Cole Robinson - 5.0.0-1 -- Update to version 5.0.0 - -* Thu Apr 16 2020 Cole Robinson - 5.0.0-0.3.rc3 -- Update to qemu 5.0.0 rc3 - -* Thu Apr 09 2020 Cole Robinson - 5.0.0-0.3.rc2 -- Update to qemu 5.0.0 rc2 - -* Wed Apr 08 2020 Adam Williamson - 2:5.0.0-0.2.rc0 -- Rebuild for new brltty - -* Wed Mar 25 2020 Cole Robinson - 2:5.0.0-0.1.rc0 -- Update to qemu-5.0.0-rc0 - -* Tue Mar 17 2020 Fabiano Fidêncio - 2:4.2.0-7 -- Fix segfault with SR-IOV hot-{plug,unplug} (bz #1814017) - -* Tue Feb 25 2020 Cole Robinson - 2:4.2.0-6 -- Rebuild for libiscsi soname bump - -* Sat Feb 15 2020 Cole Robinson - 2:4.2.0-5 -- Fix ppc shutdown issue (bz #1784961) - -* Tue Jan 28 2020 Cole Robinson - 2:4.2.0-4 -- virtio-fs support - -* Sat Jan 25 2020 Richard W.M. Jones - 4.2.0-3 -- Add miscellaneous fixes for RISC-V (RHBZ#1794902). diff --git a/extras/qemu/vhost.conf b/extras/qemu/vhost.conf deleted file mode 100644 index 68d6d7f..0000000 --- a/extras/qemu/vhost.conf +++ /dev/null @@ -1,3 +0,0 @@ -# Increase default vhost memory map limit to match -# KVM's memory slot limit -options vhost max_mem_regions=509