Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package cryptsetup for openSUSE:Factory 
checked in at 2026-07-10 17:33:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cryptsetup (Old)
 and      /work/SRC/openSUSE:Factory/.cryptsetup.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cryptsetup"

Fri Jul 10 17:33:36 2026 rev:138 rq:1364661 version:2.8.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/cryptsetup/cryptsetup.changes    2026-04-08 
17:13:20.730037731 +0200
+++ /work/SRC/openSUSE:Factory/.cryptsetup.new.1991/cryptsetup.changes  
2026-07-10 17:34:19.634803255 +0200
@@ -1,0 +2,24 @@
+Mon Jul  6 09:00:09 UTC 2026 - Pedro Monreal <[email protected]>
+
+- Fix for (bsc#1270254) to avoid undesired pinning of all volume
+  keys (via the thread keyring) through the caller's credentials
+  when the kernel opens a file. This is due to the refactoring in
+  kernel commit a28d893eb327 ("md: port block device access to file")
+  that accidentally causes the caller's thread keyring to be kept
+  alive long beyond the caller's lifetime, the kernel part is tracked
+  in (bsc#1270252).
+  * Add keyring key type. [b6fb6fc0]
+  * Load volume keys in intermediary keyring linked in thread
+    keyring. [413a3dd0]
+  * Use unique intermediary keyring name per device. [04ef07a7]
+  * Add regression tests. [bfcb0c38, bb5e8e9f, e6573494, aa214c09]
+  * Add upstream patches:
+    - cryptsetup-Add-keyring-key-type.patch
+    - cryptsetup-Load-volume-keys-in-intermediary-keyring-linked-in-t.patch
+    - cryptsetup-Use-unique-intermediary-keyring-name-per-device.patch
+    - cryptsetup-tests-revoke-keys-instead-unlinking-from-thread-keyr.patch
+    - cryptsetup-tests-verify-VK-and-internal-keyring-cleanup-after-p.patch
+    - cryptsetup-tests-refactor-keyring-helpers.patch
+    - cryptsetup-tests-verify-intermediary-keyring-cleanup-after-cryp.patch
+
+-------------------------------------------------------------------

New:
----
  cryptsetup-Add-keyring-key-type.patch
  cryptsetup-Load-volume-keys-in-intermediary-keyring-linked-in-t.patch
  cryptsetup-Use-unique-intermediary-keyring-name-per-device.patch
  cryptsetup-tests-refactor-keyring-helpers.patch
  cryptsetup-tests-revoke-keys-instead-unlinking-from-thread-keyr.patch
  cryptsetup-tests-verify-VK-and-internal-keyring-cleanup-after-p.patch
  cryptsetup-tests-verify-intermediary-keyring-cleanup-after-cryp.patch

----------(New B)----------
  New:  * Add upstream patches:
    - cryptsetup-Add-keyring-key-type.patch
    - cryptsetup-Load-volume-keys-in-intermediary-keyring-linked-in-t.patch
  New:    - cryptsetup-Add-keyring-key-type.patch
    - cryptsetup-Load-volume-keys-in-intermediary-keyring-linked-in-t.patch
    - cryptsetup-Use-unique-intermediary-keyring-name-per-device.patch
  New:    - 
cryptsetup-Load-volume-keys-in-intermediary-keyring-linked-in-t.patch
    - cryptsetup-Use-unique-intermediary-keyring-name-per-device.patch
    - cryptsetup-tests-revoke-keys-instead-unlinking-from-thread-keyr.patch
  New:    - 
cryptsetup-tests-verify-VK-and-internal-keyring-cleanup-after-p.patch
    - cryptsetup-tests-refactor-keyring-helpers.patch
    - cryptsetup-tests-verify-intermediary-keyring-cleanup-after-cryp.patch
  New:    - cryptsetup-Use-unique-intermediary-keyring-name-per-device.patch
    - cryptsetup-tests-revoke-keys-instead-unlinking-from-thread-keyr.patch
    - cryptsetup-tests-verify-VK-and-internal-keyring-cleanup-after-p.patch
  New:    - 
cryptsetup-tests-revoke-keys-instead-unlinking-from-thread-keyr.patch
    - cryptsetup-tests-verify-VK-and-internal-keyring-cleanup-after-p.patch
    - cryptsetup-tests-refactor-keyring-helpers.patch
  New:    - cryptsetup-tests-refactor-keyring-helpers.patch
    - cryptsetup-tests-verify-intermediary-keyring-cleanup-after-cryp.patch
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cryptsetup.spec ++++++
--- /var/tmp/diff_new_pack.cNipyy/_old  2026-07-10 17:34:21.610870686 +0200
+++ /var/tmp/diff_new_pack.cNipyy/_new  2026-07-10 17:34:21.610870686 +0200
@@ -30,6 +30,14 @@
 Source2:        baselibs.conf
 Source3:        cryptsetup.keyring
 Patch0:         cryptsetup-fips140-3.patch
+# PATCH-FIX-UPSTREAM bsc#1270254 Load volume keys in intermediary keyring 
linked in thread keyring
+Patch1:         cryptsetup-Add-keyring-key-type.patch
+Patch2:         
cryptsetup-Load-volume-keys-in-intermediary-keyring-linked-in-t.patch
+Patch3:         
cryptsetup-Use-unique-intermediary-keyring-name-per-device.patch
+Patch4:         
cryptsetup-tests-revoke-keys-instead-unlinking-from-thread-keyr.patch
+Patch5:         
cryptsetup-tests-verify-VK-and-internal-keyring-cleanup-after-p.patch
+Patch6:         cryptsetup-tests-refactor-keyring-helpers.patch
+Patch7:         
cryptsetup-tests-verify-intermediary-keyring-cleanup-after-cryp.patch
 # 2.6.38 has the required if_alg.h
 BuildRequires:  linux-glibc-devel >= 2.6.38
 BuildRequires:  fdupes


++++++ cryptsetup-Add-keyring-key-type.patch ++++++
>From b6fb6fc0fdc661afba734f4c29350fa6be2ede8f Mon Sep 17 00:00:00 2001
From: Ondrej Kozina <[email protected]>
Date: Fri, 19 Jun 2026 16:41:47 +0200
Subject: [PATCH] Add keyring key type.


diff --git a/lib/utils_keyring.c b/lib/utils_keyring.c
index da1ccd85..86aecfe4 100644
--- a/lib/utils_keyring.c
+++ b/lib/utils_keyring.c
@@ -32,6 +32,7 @@ static const struct {
        { BIG_KEY,       "big_key" },
        { TRUSTED_KEY,   "trusted" },
        { ENCRYPTED_KEY, "encrypted" },
+       { KEYRING_KEY,   "keyring" },
 };
 
 #include <linux/keyctl.h>
diff --git a/lib/utils_keyring.h b/lib/utils_keyring.h
index 5809f70d..b910767a 100644
--- a/lib/utils_keyring.h
+++ b/lib/utils_keyring.h
@@ -17,7 +17,7 @@
 typedef int32_t key_serial_t;
 #endif
 
-typedef enum { LOGON_KEY = 0, USER_KEY, BIG_KEY, TRUSTED_KEY, ENCRYPTED_KEY, 
INVALID_KEY } key_type_t;
+typedef enum { LOGON_KEY = 0, USER_KEY, BIG_KEY, TRUSTED_KEY, ENCRYPTED_KEY, 
KEYRING_KEY, INVALID_KEY } key_type_t;
 
 const char *key_type_name(key_type_t ktype);
 key_type_t key_type_by_name(const char *name);
-- 
2.54.0


++++++ cryptsetup-Load-volume-keys-in-intermediary-keyring-linked-in-t.patch 
++++++
>From 413a3dd04ec07ad7c3afaed84561cbc7a42f108f Mon Sep 17 00:00:00 2001
From: Ondrej Kozina <[email protected]>
Date: Thu, 25 Jun 2026 12:05:53 +0200
Subject: [PATCH] Load volume keys in intermediary keyring linked in
 thread keyring.

Instead of loading volume keys directly in the thread keyring, create
an intermediary keyring linked in the thread keyring and load volume
keys there. The intermediary keyring is bulk-cleaned on crypt_free().

This avoids undesired pinning of all volume keys (via the thread
keyring) through the caller's credentials when the kernel opens
a file, as was the case with
https://lore.kernel.org/all/[email protected]/

Fixes: #993.

diff --git a/lib/internal.h b/lib/internal.h
index 24b5bd86..e398d0ae 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -74,7 +74,7 @@ struct volume_key *crypt_volume_key_next(struct volume_key 
*vk);
 struct volume_key *crypt_volume_key_by_id(struct volume_key *vk, int id);
 void crypt_volume_key_pass_safe_alloc(struct volume_key *vk, void 
**safe_alloc);
 bool crypt_volume_key_is_set(const struct volume_key *vk);
-bool crypt_volume_key_upload_kernel_key(struct volume_key *vk);
+bool crypt_volume_key_upload_kernel_key(struct volume_key *vk, key_serial_t 
keyring);
 void crypt_volume_key_drop_uploaded_kernel_key(struct crypt_device *cd, struct 
volume_key *vk);
 void crypt_volume_key_drop_kernel_key(struct crypt_device *cd, struct 
volume_key *vk);
 
@@ -247,9 +247,9 @@ int crypt_keyring_get_keysize_by_name(struct crypt_device 
*cd,
                size_t *r_key_size);
 
 int crypt_use_keyring_for_vk(struct crypt_device *cd);
-void crypt_unlink_key_from_thread_keyring(struct crypt_device *cd,
+void crypt_unlink_key_from_keyring(struct crypt_device *cd,
                key_serial_t key_id);
-void crypt_unlink_key_by_description_from_thread_keyring(struct crypt_device 
*cd,
+void crypt_unlink_key_by_description_from_keyring(struct crypt_device *cd,
                const char *key_description,
                key_type_t ktype);
 void crypt_drop_uploaded_keyring_key(struct crypt_device *cd, struct 
volume_key *vks);
diff --git a/lib/setup.c b/lib/setup.c
index 560b5e1f..4b051e57 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -54,6 +54,9 @@ struct crypt_device {
        const char *user_key_name2;
        key_type_t keyring_key_type;
 
+       const char *keyring_description;
+       key_serial_t keyring_id;
+
        uint64_t data_offset;
        uint64_t metadata_size; /* Used in LUKS2 format */
        uint64_t keyslots_size; /* Used in LUKS2 format */
@@ -4141,6 +4144,15 @@ int crypt_header_is_detached(struct crypt_device *cd)
        return r ? 0 : 1;
 }
 
+static void crypt_unlink_keyring_from_thread_keyring(struct crypt_device *cd,
+               key_serial_t keyring_id)
+{
+       log_dbg(cd, "Unlinking keyring (id: %" PRIi32 ") from thread keyring.", 
keyring_id);
+
+       if (keyring_unlink_key_from_thread_keyring(keyring_id))
+               log_dbg(cd, "keyring_unlink_key_from_thread_keyring failed with 
errno %d.", errno);
+}
+
 void crypt_free(struct crypt_device *cd)
 {
        if (!cd)
@@ -4151,6 +4163,11 @@ void crypt_free(struct crypt_device *cd)
        dm_backend_exit(cd);
        crypt_free_volume_key(cd->volume_key);
 
+       if (cd->keyring_description) {
+               crypt_unlink_keyring_from_thread_keyring(cd, cd->keyring_id);
+               free(CONST_CAST(void*)cd->keyring_description);
+       }
+
        crypt_free_type(cd, NULL);
 
        device_free(cd, cd->device);
@@ -4335,18 +4352,35 @@ static int resume_luks1_by_volume_key(struct 
crypt_device *cd,
        return r;
 }
 
+static bool unlink_key_from_keyring(struct crypt_device *cd, key_serial_t kid, 
key_serial_t keyring_id)
+{
+       log_dbg(cd, "Unlinking volume key (id: %" PRIi32 ") from kernel keyring 
(id: %" PRIi32 ").",
+               kid, keyring_id);
+
+       if (!keyring_unlink_key_from_keyring(kid, keyring_id))
+               return true;
+
+       log_dbg(cd, "keyring_unlink_key_from_keyring failed with errno %d.", 
errno);
+
+       return false;
+}
+
+/* internal only */
+void crypt_unlink_key_from_keyring(struct crypt_device *cd,
+               key_serial_t key_id)
+{
+       (void)unlink_key_from_keyring(cd, key_id, cd->keyring_id);
+}
+
 static void crypt_unlink_key_from_custom_keyring(struct crypt_device *cd, 
key_serial_t kid)
 {
        assert(cd);
        assert(cd->keyring_to_link_vk);
 
-       log_dbg(cd, "Unlinking volume key (id: %" PRIi32 ") from kernel keyring 
(id: %" PRIi32 ").",
-               kid, cd->keyring_to_link_vk);
 
-       if (!keyring_unlink_key_from_keyring(kid, cd->keyring_to_link_vk))
+       if (unlink_key_from_keyring(cd, kid, cd->keyring_to_link_vk))
                return;
 
-       log_dbg(cd, "keyring_unlink_key_from_keyring failed with errno %d.", 
errno);
        log_err(cd, _("Failed to unlink volume key from user specified 
keyring."));
 }
 
@@ -7638,6 +7672,8 @@ int crypt_volume_key_keyring(struct crypt_device *cd 
__attribute__((unused)), in
 /* internal only */
 int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct 
volume_key *vk)
 {
+       key_serial_t keyring_id;
+
        if (!vk || !cd)
                return -EINVAL;
 
@@ -7646,14 +7682,31 @@ int crypt_volume_key_load_in_keyring(struct 
crypt_device *cd, struct volume_key
                return -EINVAL;
        }
 
-       log_dbg(cd, "Loading key (type logon, name %s) in thread keyring.",
-               crypt_volume_key_description(vk));
+       if (!cd->keyring_description) {
+               cd->keyring_description = strdup("cryptsetup-keyring");
+               if (!cd->keyring_description)
+                       return -ENOMEM;
+
+               log_dbg(cd, "Loading key (type keyring, name %s) in thread 
keyring.", cd->keyring_description);
+               keyring_id = keyring_add_key_in_thread_keyring(KEYRING_KEY, 
cd->keyring_description, NULL, 0);
+               if (keyring_id < 0) {
+                       free(CONST_CAST(void*)cd->keyring_description);
+                       cd->keyring_description = NULL;
+                       log_dbg(cd, "keyring_add_key_in_thread_keyring failed 
(error %d)", errno);
+                       log_err(cd, _("Failed to load key in kernel keyring."));
+                       return -EINVAL;
+               }
+               cd->keyring_id = keyring_id;
+       }
+
+       log_dbg(cd, "Loading key (type logon, name %s) in %s keyring.",
+               crypt_volume_key_description(vk), cd->keyring_description);
 
-       if (crypt_volume_key_upload_kernel_key(vk)) {
+       if (crypt_volume_key_upload_kernel_key(vk, cd->keyring_id)) {
                crypt_set_key_in_keyring(cd, 1);
                return 0;
        } else {
-               log_dbg(cd, "keyring_add_key_in_thread_keyring failed (error 
%d)", errno);
+               log_dbg(cd, "keyring_add_key_to_keyring failed (error %d)", 
errno);
                log_err(cd, _("Failed to load key in kernel keyring."));
                return -EINVAL;
        }
@@ -7769,17 +7822,7 @@ void crypt_set_key_in_keyring(struct crypt_device *cd, 
unsigned key_in_keyring)
        cd->key_in_keyring = key_in_keyring;
 }
 
-/* internal only */
-void crypt_unlink_key_from_thread_keyring(struct crypt_device *cd,
-               key_serial_t key_id)
-{
-       log_dbg(cd, "Unlinking volume key (id: %" PRIi32 ") from thread 
keyring.", key_id);
-
-       if (keyring_unlink_key_from_thread_keyring(key_id))
-               log_dbg(cd, "keyring_unlink_key_from_thread_keyring failed with 
errno %d.", errno);
-}
-
-void crypt_unlink_key_by_description_from_thread_keyring(struct crypt_device 
*cd,
+void crypt_unlink_key_by_description_from_keyring(struct crypt_device *cd,
                const char *key_description,
                key_type_t ktype)
 {
@@ -7802,7 +7845,7 @@ void 
crypt_unlink_key_by_description_from_thread_keyring(struct crypt_device *cd
                return;
        }
 
-       crypt_unlink_key_from_thread_keyring(cd, kid);
+       crypt_unlink_key_from_keyring(cd, kid);
 }
 
 int crypt_set_keyring_to_link(struct crypt_device *cd, const char 
*key_description,
diff --git a/lib/volumekey.c b/lib/volumekey.c
index bcd8349a..7df62267 100644
--- a/lib/volumekey.c
+++ b/lib/volumekey.c
@@ -243,14 +243,14 @@ bool crypt_volume_key_is_set(const struct volume_key *vk)
        return vk && vk->key;
 }
 
-bool crypt_volume_key_upload_kernel_key(struct volume_key *vk)
+bool crypt_volume_key_upload_kernel_key(struct volume_key *vk, key_serial_t 
keyring)
 {
        key_serial_t kid;
 
        assert(vk && vk->key && vk->key_description && vk->keyring_key_type != 
INVALID_KEY);
 
-       kid = keyring_add_key_in_thread_keyring(vk->keyring_key_type, 
vk->key_description,
-                                        vk->key, vk->keylength);
+       kid = keyring_add_key_to_keyring(vk->keyring_key_type, 
vk->key_description, vk->key,
+                                        vk->keylength, keyring);
        if (kid >= 0) {
                vk->key_id = kid;
                return true;
@@ -265,9 +265,7 @@ void crypt_volume_key_drop_kernel_key(struct crypt_device 
*cd, struct volume_key
        assert(vk->key_description || vk->keyring_key_type == INVALID_KEY);
        assert(!vk->key_description || vk->keyring_key_type != INVALID_KEY);
 
-       crypt_unlink_key_by_description_from_thread_keyring(cd,
-                                                           vk->key_description,
-                                                           
vk->keyring_key_type);
+       crypt_unlink_key_by_description_from_keyring(cd, vk->key_description, 
vk->keyring_key_type);
 }
 
 void crypt_volume_key_drop_uploaded_kernel_key(struct crypt_device *cd, struct 
volume_key *vk)
@@ -277,6 +275,6 @@ void crypt_volume_key_drop_uploaded_kernel_key(struct 
crypt_device *cd, struct v
        if (vk->key_id < 0)
                return;
 
-       crypt_unlink_key_from_thread_keyring(cd, vk->key_id);
+       crypt_unlink_key_from_keyring(cd, vk->key_id);
        vk->key_id = -1;
 }
-- 
2.54.0


++++++ cryptsetup-Use-unique-intermediary-keyring-name-per-device.patch ++++++
>From 04ef07a7070fc8f71dc8da57d6cc23423e1b632e Mon Sep 17 00:00:00 2001
From: Ondrej Kozina <[email protected]>
Date: Fri, 19 Jun 2026 16:45:49 +0200
Subject: [PATCH] Use unique intermediary keyring name per device.

Replace the static "cryptsetup-keyring" name with
"cryptsetup-<uuid_prefix>-<random>" to avoid collisions when
multiple LUKS devices are opened by the same process.

Fixes: #993.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

diff --git a/lib/setup.c b/lib/setup.c
index 4b051e57..1c0f21e6 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -7673,6 +7673,9 @@ int crypt_volume_key_keyring(struct crypt_device *cd 
__attribute__((unused)), in
 int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct 
volume_key *vk)
 {
        key_serial_t keyring_id;
+       char *keyring_description;
+       char rnd[4];
+       const char *uuid;
 
        if (!vk || !cd)
                return -EINVAL;
@@ -7683,20 +7686,28 @@ int crypt_volume_key_load_in_keyring(struct 
crypt_device *cd, struct volume_key
        }
 
        if (!cd->keyring_description) {
-               cd->keyring_description = strdup("cryptsetup-keyring");
-               if (!cd->keyring_description)
+               uuid = crypt_get_uuid(cd);
+               if (!uuid)
+                       return -EINVAL;
+
+               if (crypt_random_get(cd, rnd, sizeof(rnd), CRYPT_RND_NORMAL) < 
0)
+                       return -EINVAL;
+
+               if (asprintf(&keyring_description, 
"cryptsetup-%.8s-%02x%02x%02x%02x",
+                            uuid, (unsigned char)rnd[0], (unsigned char)rnd[1],
+                            (unsigned char)rnd[2], (unsigned char)rnd[3]) < 0)
                        return -ENOMEM;
 
-               log_dbg(cd, "Loading key (type keyring, name %s) in thread 
keyring.", cd->keyring_description);
-               keyring_id = keyring_add_key_in_thread_keyring(KEYRING_KEY, 
cd->keyring_description, NULL, 0);
+               log_dbg(cd, "Loading key (type keyring, name %s) in thread 
keyring.", keyring_description);
+               keyring_id = keyring_add_key_in_thread_keyring(KEYRING_KEY, 
keyring_description, NULL, 0);
                if (keyring_id < 0) {
-                       free(CONST_CAST(void*)cd->keyring_description);
-                       cd->keyring_description = NULL;
+                       free(keyring_description);
                        log_dbg(cd, "keyring_add_key_in_thread_keyring failed 
(error %d)", errno);
                        log_err(cd, _("Failed to load key in kernel keyring."));
                        return -EINVAL;
                }
                cd->keyring_id = keyring_id;
+               cd->keyring_description = keyring_description;
        }
 
        log_dbg(cd, "Loading key (type logon, name %s) in %s keyring.",
-- 
2.54.0


++++++ cryptsetup-tests-refactor-keyring-helpers.patch ++++++
>From bfcb0c38eb95c08852c7dcd488c28e26c7775cf0 Mon Sep 17 00:00:00 2001
From: Ondrej Kozina <[email protected]>
Date: Fri, 26 Jun 2026 16:26:45 +0200
Subject: [PATCH] tests: refactor keyring helpers.


diff --git a/tests/api-test-2.c b/tests/api-test-2.c
index c41eb4dc..3ef0adca 100644
--- a/tests/api-test-2.c
+++ b/tests/api-test-2.c
@@ -477,25 +477,27 @@ static key_serial_t add_key_set_perm(const char *type, 
const char *description,
        return l == 0 ? kid : -EINVAL;
 }
 
-static key_serial_t _kernel_key_by_segment_and_type(struct crypt_device *_cd, 
int segment,
-                                                   const char* type)
+static key_serial_t _kernel_key_by_segment_uuid_and_type(const char *uuid, int 
segment,
+                                                        const char *type)
+
 {
        char key_description[1024];
 
-       if (snprintf(key_description, sizeof(key_description), 
"cryptsetup:%s-d%u", crypt_get_uuid(_cd), segment) < 1)
+       if (snprintf(key_description, sizeof(key_description), 
"cryptsetup:%s-d%u", uuid, segment) < 1)
                return -1;
 
        return request_key(type, key_description, NULL, 0);
 }
 
-static key_serial_t _kernel_key_by_segment(struct crypt_device *_cd, int 
segment)
+static key_serial_t _kernel_key_by_segment_and_type(struct crypt_device *_cd, 
int segment,
+                                                   const char* type)
 {
-       return _kernel_key_by_segment_and_type(_cd, segment, "logon");
+       return _kernel_key_by_segment_uuid_and_type(crypt_get_uuid(_cd), 
segment, type);
 }
 
 static int _volume_key_in_keyring(struct crypt_device *_cd, int segment)
 {
-       return _kernel_key_by_segment(_cd, segment) >= 0 ? 0 : -1;
+       return _kernel_key_by_segment_and_type(_cd, segment, "logon") >= 0 ? 0 
: -1;
 }
 
 static int _drop_keyring_key_from_keyring_name(const char *key_description, 
key_serial_t keyring, const char* type)
-- 
2.54.0


++++++ cryptsetup-tests-revoke-keys-instead-unlinking-from-thread-keyr.patch 
++++++
>From bb5e8e9f0b34fb8135e948ce60d956c2af7d5c8d Mon Sep 17 00:00:00 2001
From: Ondrej Kozina <[email protected]>
Date: Fri, 19 Jun 2026 14:58:46 +0200
Subject: [PATCH] tests: revoke keys instead unlinking from thread
 keyring.

With the intermediary thread keyring we can not simply unlink
key from thread keyring. Let's make it simple and invalidate the
key instead.

diff --git a/tests/api-test-2.c b/tests/api-test-2.c
index 0523e11d..c41eb4dc 100644
--- a/tests/api-test-2.c
+++ b/tests/api-test-2.c
@@ -427,6 +427,11 @@ static key_serial_t keyctl_unlink(key_serial_t key, 
key_serial_t keyring)
        return syscall(__NR_keyctl, KEYCTL_UNLINK, key, keyring);
 }
 
+static key_serial_t keyctl_revoke(key_serial_t key)
+{
+       return syscall(__NR_keyctl, KEYCTL_REVOKE, key);
+}
+
 static key_serial_t keyctl_link(key_serial_t key, key_serial_t keyring)
 {
        return syscall(__NR_keyctl, KEYCTL_LINK, key, keyring);
@@ -504,20 +509,14 @@ static int _drop_keyring_key_from_keyring_name(const char 
*key_description, key_
        return keyctl_unlink(kid, keyring);
 }
 
-static int _drop_keyring_key_from_keyring_type(struct crypt_device *_cd, int 
segment,
-                                              key_serial_t keyring, const 
char* type)
+static int _revoke_keyring_key(struct crypt_device *_cd, int segment)
 {
-       key_serial_t kid = _kernel_key_by_segment_and_type(_cd, segment, type);
+       key_serial_t kid = _kernel_key_by_segment_and_type(_cd, segment, 
"logon");
 
        if (kid < 0)
                return -1;
 
-       return keyctl_unlink(kid, keyring);
-}
-
-static int _drop_keyring_key(struct crypt_device *_cd, int segment)
-{
-       return _drop_keyring_key_from_keyring_type(_cd, segment, 
KEY_SPEC_THREAD_KEYRING, "logon");
+       return keyctl_revoke(kid);
 }
 #endif
 
@@ -690,11 +689,11 @@ static void UseLuks2Device(void)
        // repeat previous tests and check kernel keyring is released when not 
needed
        if (t_dm_crypt_keyring_support()) {
                OK_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, 
KEY1, strlen(KEY1), 0));
-               FAIL_(_drop_keyring_key(cd, 0), "");
+               FAIL_(_revoke_keyring_key(cd, 0), "");
                OK_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, 
KEY1, strlen(KEY1), CRYPT_ACTIVATE_KEYRING_KEY));
-               OK_(_drop_keyring_key(cd, 0));
+               OK_(_revoke_keyring_key(cd, 0));
                OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, 
KEY1, strlen(KEY1), 0));
-               OK_(_drop_keyring_key(cd, 0));
+               OK_(_revoke_keyring_key(cd, 0));
                FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, 
CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0), "already open");
                FAIL_(_volume_key_in_keyring(cd, 0), "");
                OK_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, 
KEY1, strlen(KEY1), 0));
@@ -704,11 +703,11 @@ static void UseLuks2Device(void)
                if (!_fips_mode) {
                        /* keyslot 0 is PBKDF2, keyslot 1 is Argon2id */
                        EQ_(crypt_activate_by_passphrase(cd, NULL, 1, KEY2, 
strlen(KEY2), 0), 1);
-                       FAIL_(_drop_keyring_key(cd, 0), "");
+                       FAIL_(_revoke_keyring_key(cd, 0), "");
                        EQ_(crypt_activate_by_passphrase(cd, NULL, 1, KEY2, 
strlen(KEY2), CRYPT_ACTIVATE_KEYRING_KEY), 1);
-                       OK_(_drop_keyring_key(cd, 0));
+                       OK_(_revoke_keyring_key(cd, 0));
                        EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 1, 
KEY2, strlen(KEY2), 0), 1);
-                       OK_(_drop_keyring_key(cd, 0));
+                       OK_(_revoke_keyring_key(cd, 0));
                        FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, 1, 
KEY2, strlen(KEY2), 0), "already open");
                        FAIL_(_volume_key_in_keyring(cd, 0), "");
                        EQ_(crypt_activate_by_passphrase(cd, NULL, 1, KEY2, 
strlen(KEY2), 0), 1);
@@ -1828,9 +1827,9 @@ static void ResizeDeviceLuks2(void)
        OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
        // erase volume key from kernel keyring
        if (t_dm_crypt_keyring_support())
-               OK_(_drop_keyring_key(cd, 0));
+               OK_(_revoke_keyring_key(cd, 0));
        else
-               FAIL_(_drop_keyring_key(cd, 0), "key not found");
+               FAIL_(_revoke_keyring_key(cd, 0), "key not found");
        // same size is ok
        OK_(crypt_resize(cd, CDEVICE_1, 0));
        // kernel fails to find the volume key in keyring
-- 
2.54.0


++++++ cryptsetup-tests-verify-VK-and-internal-keyring-cleanup-after-p.patch 
++++++
>From aa214c098a11297f1669fd4d30d2b9c98cbd365e Mon Sep 17 00:00:00 2001
From: Ondrej Kozina <[email protected]>
Date: Wed, 24 Jun 2026 11:21:27 +0200
Subject: [PATCH] tests: verify VK and internal keyring cleanup after
 process exit.

Check that both the intermediary keyring and the volume key logon
key are removed from the kernel keyring after the cryptsetup
process exits. Verify via search in /proc/keys.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

Index: cryptsetup-2.8.6/tests/compat-test2
===================================================================
--- cryptsetup-2.8.6.orig/tests/compat-test2
+++ cryptsetup-2.8.6/tests/compat-test2
@@ -485,6 +485,26 @@ test_reencrypt_vk_link_and_reactivate()
        echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring 
"$KEY_DESC" --volume-key-keyring "$KEY_DESC2" > /dev/null 2>&1 && fail
 }
 
+
+# $1 substring to search for in /proc/keys
+wait_key_dissapeared()
+{
+       local ret=
+       local tries=50
+
+       grep -q $1 /proc/keys
+       ret=$?
+
+       while [ $ret -eq 0 -a $tries -gt 0 ]; do
+               sleep .1
+               grep -q $1 /proc/keys
+               ret=$?
+               tries=$((tries-1))
+       done
+
+       test $ret -ne 0
+}
+
 expect_run()
 {
        export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}"
@@ -1714,5 +1734,20 @@ if ! fips_mode -a -d $LUKS2_LOCKING_DIR;
        test -f $LUKS2_LOCKING_DIR/$MEMORY_HARD_LOCK_FILE && fail "The 
--serialize-memory-hard-pbkdf option did not remove the locking file (did not 
use the file)."
 fi
 
+if dm_crypt_keyring_support && dm_crypt_keyring_new_kernel; then
+       prepare "[54] Intermediary keyring VK cleanup" wipe
+       echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 
$LOOPDEV || fail
+       UUID=$($CRYPTSETUP luksUUID $LOOPDEV)
+
+       echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME || fail
+       $CRYPTSETUP -q status $DEV_NAME | grep "key location:" | grep -q 
"keyring" || fail
+
+       # after cryptsetup open exits both the intermediary keyring and VK 
logon key must be gone
+       wait_key_dissapeared "keyring.*cryptsetup-${UUID:0:8}" || fail 
"Intermediary keyring persists in /proc/keys after process exit"
+       wait_key_dissapeared "logon.*cryptsetup:${UUID}" || fail "VK logon key 
persists in /proc/keys after process exit"
+
+       $CRYPTSETUP close $DEV_NAME || fail
+fi
+
 remove_mapping
 exit 0

++++++ cryptsetup-tests-verify-intermediary-keyring-cleanup-after-cryp.patch 
++++++
>From e6573494f0feee971c8079d2697a2d925c3799a0 Mon Sep 17 00:00:00 2001
From: Ondrej Kozina <[email protected]>
Date: Thu, 25 Jun 2026 15:35:07 +0200
Subject: [PATCH] tests: verify intermediary keyring cleanup after
 crypt_free().

Add API-level test that checks both the intermediary keyring and
VK logon key are unlinked from the thread keyring after
crypt_free(). Unlike the compat-test2 checks (which verify after
process exit), this runs in-process where the thread keyring is
still alive.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

diff --git a/tests/api-test-2.c b/tests/api-test-2.c
index 3ef0adca..a6b82d18 100644
--- a/tests/api-test-2.c
+++ b/tests/api-test-2.c
@@ -520,6 +520,36 @@ static int _revoke_keyring_key(struct crypt_device *_cd, 
int segment)
 
        return keyctl_revoke(kid);
 }
+
+static long keyctl_describe(key_serial_t id, char *buffer, size_t buflen)
+{
+       return syscall(__NR_keyctl, KEYCTL_DESCRIBE, id, buffer, buflen);
+}
+
+static int _intermediary_keyring_in_thread_keyring(const char *uuid)
+{
+       key_serial_t keys[64];
+       char rdesc[256], prefix[20];
+       long r;
+       int i, count;
+
+       r = snprintf(prefix, sizeof(prefix), "cryptsetup-%.8s", uuid);
+       if (r < 0 || (size_t)r > sizeof(prefix) - 1)
+               return -1;
+
+       r = keyctl_read(KEY_SPEC_THREAD_KEYRING, (char *)keys, sizeof(keys));
+       if (r < 0)
+               return -1;
+
+       count = r / sizeof(key_serial_t);
+       for (i = 0; i < count; i++) {
+               r = keyctl_describe(keys[i], rdesc, sizeof(rdesc));
+               if (r > 0 && (size_t)r <= sizeof(rdesc) && strstr(rdesc, 
prefix))
+                       return 0;
+       }
+
+       return -1;
+}
 #endif
 
 static void _cleanup(void)
@@ -736,8 +766,26 @@ static void UseLuks2Device(void)
        key[1] = ~key[1];
        FAIL_(crypt_volume_key_verify(cd, key, key_size), "key mismatch");
        FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), 
"key mismatch");
+       CRYPT_FREE(cd);
 
+#if KERNEL_KEYRING
+       OK_(crypt_init(&cd, DEVICE_1));
+       OK_(crypt_load(cd, CRYPT_LUKS2, NULL));
+       if (t_dm_crypt_keyring_support()) {
+               OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, 
KEY1, strlen(KEY1), 0));
+               OK_(_intermediary_keyring_in_thread_keyring(DEVICE_1_UUID));
+               OK_(_volume_key_in_keyring(cd, 0));
+       }
+       // All keys uploaded via current device context must be freed.
        CRYPT_FREE(cd);
+       if (t_dm_crypt_keyring_support()) {
+               FAIL_(_intermediary_keyring_in_thread_keyring(DEVICE_1_UUID), 
"intermediary keyring not cleaned up");
+               FAIL_(_kernel_key_by_segment_uuid_and_type(DEVICE_1_UUID, 0, 
"logon"), "VK not cleaned up");
+       }
+       OK_(crypt_init_by_name(&cd, CDEVICE_1));
+       OK_(crypt_deactivate(cd, CDEVICE_1));
+       CRYPT_FREE(cd);
+#endif
 }
 
 static void SuspendDevice(void)
-- 
2.54.0

Reply via email to