diff mbox series

[1/5] gcr: initialize libgcrypt from the secret exchange

Message ID 20260922092411.262885-1-f_l_k@t-online.de
State New
Headers show
Series [1/5] gcr: initialize libgcrypt from the secret exchange | expand

Commit Message

Markus Volk Sept. 22, 2026, 9:23 a.m. UTC
gnome-shell logs a libgcrypt warning on the first keyring prompt:

    Libgcrypt warning: missing initialization - please fix the application

gcr3 initialized libgcrypt from GcrSecretExchange's class_init; gcr 4
dropped that call, and _gcr_initialize_library() is only reached from
the certificate, parser and importer paths, never from the prompt path.
The guard in that function is inverted on top of it, so even when it is
called the first caller returns without initializing anything.

The secret exchange itself works either way, but libgcrypt then runs
without the egg secure memory allocators, which puts passwords into
ordinary swappable heap instead of locked pages.

AI-Generated: Uses Claude Code
Signed-off-by: Markus Volk <f_l_k@t-online.de>
---
 ...e-libgcrypt-from-the-secret-exchange.patch | 81 +++++++++++++++++++
 meta/recipes-gnome/gcr/gcr_4.4.1.bb           |  1 +
 2 files changed, 82 insertions(+)
 create mode 100644 meta/recipes-gnome/gcr/gcr/0001-gcr-initialize-libgcrypt-from-the-secret-exchange.patch

Comments

patchtest@automation.yoctoproject.org Sept. 22, 2026, 9:33 a.m. UTC | #1
Thank you for your submission. Patchtest identified one
or more issues with the patch. Please see the log below for
more information:

---
Testing patch /home/patchtest/share/mboxes/1-5-gcr-initialize-libgcrypt-from-the-secret-exchange.patch

FAIL: test Signed-off-by presence: A patch file has been added without a Signed-off-by tag: '0001-gcr-initialize-libgcrypt-from-the-secret-exchange.patch' (test_patch.TestPatch.test_signed_off_by_presence)

PASS: pretest src uri left files (test_metadata.TestMetadata.pretest_src_uri_left_files)
PASS: test CVE check ignore (test_metadata.TestMetadata.test_cve_check_ignore)
PASS: test CVE tag format (test_patch.TestPatch.test_cve_tag_format)
PASS: test Signed-off-by presence (test_mbox.TestMbox.test_signed_off_by_presence)
PASS: test Upstream-Status presence (test_patch.TestPatch.test_upstream_status_presence_format)
PASS: test auh changelog truncation notice (test_mbox.TestMbox.test_auh_changelog_truncation_notice)
PASS: test author valid (test_mbox.TestMbox.test_author_valid)
PASS: test commit message presence (test_mbox.TestMbox.test_commit_message_presence)
PASS: test commit message user tags (test_mbox.TestMbox.test_commit_message_user_tags)
PASS: test lic files chksum modified not mentioned (test_metadata.TestMetadata.test_lic_files_chksum_modified_not_mentioned)
PASS: test max line length (test_metadata.TestMetadata.test_max_line_length)
PASS: test mbox format (test_mbox.TestMbox.test_mbox_format)
PASS: test non-AUH upgrade (test_mbox.TestMbox.test_non_auh_upgrade)
PASS: test shortlog format (test_mbox.TestMbox.test_shortlog_format)
PASS: test shortlog length (test_mbox.TestMbox.test_shortlog_length)
PASS: test src uri left files (test_metadata.TestMetadata.test_src_uri_left_files)
PASS: test target mailing list (test_mbox.TestMbox.test_target_mailing_list)

SKIP: pretest pylint: No python related patches, skipping test (test_python_pylint.PyLint.pretest_pylint)
SKIP: test bugzilla entry format: No bug ID found (test_mbox.TestMbox.test_bugzilla_entry_format)
SKIP: test lic files chksum presence: No added recipes, skipping test (test_metadata.TestMetadata.test_lic_files_chksum_presence)
SKIP: test license presence: No added recipes, skipping test (test_metadata.TestMetadata.test_license_presence)
SKIP: test pylint: No python related patches, skipping test (test_python_pylint.PyLint.test_pylint)
SKIP: test series merge on head: Merge test is disabled for now (test_mbox.TestMbox.test_series_merge_on_head)
SKIP: test summary presence: No added recipes, skipping test (test_metadata.TestMetadata.test_summary_presence)

---

Please address the issues identified and
submit a new revision of the patch, or alternatively, reply to this
email with an explanation of why the patch should be accepted. If you
believe these results are due to an error in patchtest, please submit a
bug at https://bugzilla.yoctoproject.org/ (use the 'Patchtest' category
under 'Yocto Project Subprojects'). For more information on specific
failures, see: https://wiki.yoctoproject.org/wiki/Patchtest. Thank
you!
diff mbox series

Patch

diff --git a/meta/recipes-gnome/gcr/gcr/0001-gcr-initialize-libgcrypt-from-the-secret-exchange.patch b/meta/recipes-gnome/gcr/gcr/0001-gcr-initialize-libgcrypt-from-the-secret-exchange.patch
new file mode 100644
index 0000000000..3a55cf30aa
--- /dev/null
+++ b/meta/recipes-gnome/gcr/gcr/0001-gcr-initialize-libgcrypt-from-the-secret-exchange.patch
@@ -0,0 +1,81 @@ 
+From e8b729cc6ceddd22b5160f27396cf07cecd977ad Mon Sep 17 00:00:00 2001
+From: Markus Volk <f_l_k@t-online.de>
+Date: Tue, 15 Sep 2026 18:24:45 +0200
+Subject: [PATCH] gcr: initialize libgcrypt from the secret exchange
+
+gnome-shell logs this on the first keyring prompt:
+
+    gnome-shell: Libgcrypt warning: missing initialization - please fix the application
+
+gcr3 initialized libgcrypt from the class_init of GcrSecretExchange
+(gcr/gcr-secret-exchange.c:847). That call is gone in gcr 4, leaving
+only _gcr_initialize_library(), which is reached from the certificate,
+parser and importer paths but never from the prompt path.
+
+On top of that the guard in _gcr_initialize_library() is inverted, in
+gcr3 as much as in gcr 4:
+
+    static gint gcr_initialize = 0;
+    if (g_atomic_int_add (&gcr_initialize, 1) == 0)
+            return;
+
+g_atomic_int_add() returns the value from before the addition, so the
+first call returns without ever reaching egg_libgcrypt_initialize() and
+only the second one initializes anything.
+
+This is not what breaks the keyring - the secret exchange was tested
+against both gcr3 and gcr 4 and transfers the secret correctly either
+way - but libgcrypt then runs without the egg secure memory allocators,
+so passwords end up in ordinary swappable heap instead of locked pages.
+
+Fix the guard and initialize from the secret exchange again.
+
+Upstream-Status: Pending
+
+AI-Generated: Uses Claude Code (Claude Opus 5)
+---
+ gcr/gcr-library.c         | 3 ++-
+ gcr/gcr-secret-exchange.c | 9 +++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/gcr/gcr-library.c b/gcr/gcr-library.c
+index 560772b..9d03f25 100644
+--- a/gcr/gcr-library.c
++++ b/gcr/gcr-library.c
+@@ -125,7 +125,8 @@ _gcr_initialize_library (void)
+ {
+ 	static gint gcr_initialize = 0;
+ 
+-	if (g_atomic_int_add (&gcr_initialize, 1) == 0)
++	/* Initialize on the first call, do nothing on every call after it */
++	if (g_atomic_int_add (&gcr_initialize, 1) != 0)
+ 		return;
+ 
+ #ifdef WITH_GCRYPT
+diff --git a/gcr/gcr-secret-exchange.c b/gcr/gcr-secret-exchange.c
+index 943b2af..3e5f889 100644
+--- a/gcr/gcr-secret-exchange.c
++++ b/gcr/gcr-secret-exchange.c
+@@ -21,6 +21,8 @@
+ 
+ #include "gcr-secret-exchange.h"
+ 
++#include "gcr-internal.h"
++
+ #include "egg/egg-crypto.h"
+ #include "egg/egg-dh.h"
+ #include "egg/egg-fips.h"
+@@ -817,6 +819,13 @@ gcr_secret_exchange_class_init (GcrSecretExchangeClass *klass)
+ 	klass->decrypt_transport_data = gcr_secret_exchange_default_decrypt_transport_data;
+ 	klass->encrypt_transport_data = gcr_secret_exchange_default_encrypt_transport_data;
+ 
++	/*
++	 * The exchange is the only part of the library that some callers ever
++	 * touch - gnome-shell through keyring.js for one - so initialize
++	 * libgcrypt here as well. gcr3 did this and gcr-4 dropped it.
++	 */
++	_gcr_initialize_library ();
++
+ 	/**
+ 	 * GcrSecretExchange:protocol:
+ 	 *
diff --git a/meta/recipes-gnome/gcr/gcr_4.4.1.bb b/meta/recipes-gnome/gcr/gcr_4.4.1.bb
index 93028d2497..aedbe60b69 100644
--- a/meta/recipes-gnome/gcr/gcr_4.4.1.bb
+++ b/meta/recipes-gnome/gcr/gcr_4.4.1.bb
@@ -17,6 +17,7 @@  inherit gnomebase gi-docgen vala gobject-introspection lib_package
 UPSTREAM_CHECK_REGEX = "gcr-(?P<pver>\d+\.\d+\.(?!9\d+)\d+(\.\d+)?)"
 
 SRC_URI[archive.sha256sum] = "c4442c15d4330f17a1f5194df08c576877af68412ab2521446a93bd5e24c931b"
+SRC_URI += "file://0001-gcr-initialize-libgcrypt-from-the-secret-exchange.patch"
 
 PACKAGECONFIG ??= "${@bb.utils.contains('GI_DATA_ENABLED', 'True', 'vapi', '', d)}"
 PACKAGECONFIG[ssh_agent] = "-Dssh_agent=true,-Dssh_agent=false,libsecret"