Skip to content

Commit e657349

Browse files
onikoclaude
andcommitted
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 <noreply@anthropic.com>
1 parent bfcb0c3 commit e657349

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

tests/api-test-2.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,36 @@ static int _revoke_keyring_key(struct crypt_device *_cd, int segment)
520520

521521
return keyctl_revoke(kid);
522522
}
523+
524+
static long keyctl_describe(key_serial_t id, char *buffer, size_t buflen)
525+
{
526+
return syscall(__NR_keyctl, KEYCTL_DESCRIBE, id, buffer, buflen);
527+
}
528+
529+
static int _intermediary_keyring_in_thread_keyring(const char *uuid)
530+
{
531+
key_serial_t keys[64];
532+
char rdesc[256], prefix[20];
533+
long r;
534+
int i, count;
535+
536+
r = snprintf(prefix, sizeof(prefix), "cryptsetup-%.8s", uuid);
537+
if (r < 0 || (size_t)r > sizeof(prefix) - 1)
538+
return -1;
539+
540+
r = keyctl_read(KEY_SPEC_THREAD_KEYRING, (char *)keys, sizeof(keys));
541+
if (r < 0)
542+
return -1;
543+
544+
count = r / sizeof(key_serial_t);
545+
for (i = 0; i < count; i++) {
546+
r = keyctl_describe(keys[i], rdesc, sizeof(rdesc));
547+
if (r > 0 && (size_t)r <= sizeof(rdesc) && strstr(rdesc, prefix))
548+
return 0;
549+
}
550+
551+
return -1;
552+
}
523553
#endif
524554

525555
static void _cleanup(void)
@@ -736,8 +766,26 @@ static void UseLuks2Device(void)
736766
key[1] = ~key[1];
737767
FAIL_(crypt_volume_key_verify(cd, key, key_size), "key mismatch");
738768
FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "key mismatch");
769+
CRYPT_FREE(cd);
739770

771+
#if KERNEL_KEYRING
772+
OK_(crypt_init(&cd, DEVICE_1));
773+
OK_(crypt_load(cd, CRYPT_LUKS2, NULL));
774+
if (t_dm_crypt_keyring_support()) {
775+
OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
776+
OK_(_intermediary_keyring_in_thread_keyring(DEVICE_1_UUID));
777+
OK_(_volume_key_in_keyring(cd, 0));
778+
}
779+
// All keys uploaded via current device context must be freed.
740780
CRYPT_FREE(cd);
781+
if (t_dm_crypt_keyring_support()) {
782+
FAIL_(_intermediary_keyring_in_thread_keyring(DEVICE_1_UUID), "intermediary keyring not cleaned up");
783+
FAIL_(_kernel_key_by_segment_uuid_and_type(DEVICE_1_UUID, 0, "logon"), "VK not cleaned up");
784+
}
785+
OK_(crypt_init_by_name(&cd, CDEVICE_1));
786+
OK_(crypt_deactivate(cd, CDEVICE_1));
787+
CRYPT_FREE(cd);
788+
#endif
741789
}
742790

743791
static void SuspendDevice(void)

0 commit comments

Comments
 (0)