* [LTP] [PATCH v3 01/36] lapi/keyctl.h: Add fallback definitions for extended ops
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 9:35 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 02/36] lapi/keyctl.h: Add SAFE_ADD_KEY() Petr Vorel
` (35 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add fallback definitions for KEYCTL_LINK, KEYCTL_RESTRICT_KEYRING,
KEYCTL_MOVE, and KEYCTL_MOVE_EXCL, as well as fallback definitions
for struct keyctl_dh_params and struct keyctl_kdf_params when built
without linux/keyctl.h.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel
* Remove <keyutils.h> usage - use only <linux/keyctl.h>
* Add check for struct keyctl_dh_params.priv for Leap 42.2 ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
include/lapi/keyctl.h | 36 +++++++++++++++++++++++++++++++++++-
m4/ltp-keyutils.m4 | 7 +++++++
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/include/lapi/keyctl.h b/include/lapi/keyctl.h
index 83fa09303c..1c6627f555 100644
--- a/include/lapi/keyctl.h
+++ b/include/lapi/keyctl.h
@@ -8,6 +8,8 @@
#include "config.h"
+#include <stdint.h>
+
#if defined(HAVE_KEYUTILS_H) && defined(HAVE_LIBKEYUTILS)
# include <keyutils.h>
#else
@@ -16,7 +18,6 @@
# endif /* HAVE_LINUX_KEYCTL_H */
# include <stdarg.h>
-# include <stdint.h>
# include "lapi/syscalls.h"
typedef int32_t key_serial_t;
@@ -60,6 +61,23 @@ static inline key_serial_t keyctl_join_session_keyring(const char *name) {
#endif /* defined(HAVE_KEYUTILS_H) && defined(HAVE_LIBKEYUTILS) */
+#ifndef HAVE_STRUCT_KEYCTL_DH_PARAMS
+struct keyctl_dh_params {
+ int32_t priv;
+ int32_t prime;
+ int32_t base;
+};
+#endif
+
+#ifndef HAVE_STRUCT_KEYCTL_KDF_PARAMS
+struct keyctl_kdf_params {
+ char *hashname;
+ char *otherinfo;
+ uint32_t otherinfolen;
+ uint32_t __spare[8];
+};
+#endif
+
/* special process keyring shortcut IDs */
#ifndef KEY_SPEC_THREAD_KEYRING
# define KEY_SPEC_THREAD_KEYRING -1
@@ -124,6 +142,10 @@ static inline key_serial_t keyctl_join_session_keyring(const char *name) {
# define KEYCTL_CLEAR 7
#endif
+#ifndef KEYCTL_LINK
+# define KEYCTL_LINK 8
+#endif
+
#ifndef KEYCTL_UNLINK
# define KEYCTL_UNLINK 9
#endif
@@ -168,6 +190,18 @@ static inline key_serial_t keyctl_join_session_keyring(const char *name) {
# define KEYCTL_WATCH_KEY 32
#endif
+#ifndef KEYCTL_RESTRICT_KEYRING
+# define KEYCTL_RESTRICT_KEYRING 29
+#endif
+
+#ifndef KEYCTL_MOVE
+# define KEYCTL_MOVE 30
+#endif
+
+#ifndef KEYCTL_MOVE_EXCL
+# define KEYCTL_MOVE_EXCL 0x00000001 /* do not displace from the to-keyring */
+#endif
+
/* key permissions */
#ifndef KEY_POS_VIEW
# define KEY_POS_VIEW 0x01000000
diff --git a/m4/ltp-keyutils.m4 b/m4/ltp-keyutils.m4
index 451c549f38..35bad783e5 100644
--- a/m4/ltp-keyutils.m4
+++ b/m4/ltp-keyutils.m4
@@ -1,10 +1,17 @@
dnl SPDX-License-Identifier: GPL-2.0-or-later
dnl Copyright (c) 2016 Fujitsu Ltd.
dnl Copyright (c) 2017 Petr Vorel <pvorel@suse.cz>
+dnl Copyright (c) Linux Test Project, 2019-2026
dnl Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
AC_DEFUN([LTP_CHECK_KEYUTILS_SUPPORT], [
AC_CHECK_LIB([keyutils], [add_key],
[AC_DEFINE(HAVE_LIBKEYUTILS, 1, [Define to 1 if you have libkeyutils installed.])
AC_SUBST(KEYUTILS_LIBS, "-lkeyutils")])
+
+ AC_CHECK_TYPES([struct keyctl_dh_params, struct keyctl_kdf_params,
+ struct keyctl_pkey_query, struct keyctl_pkey_params],,,
+ [#include <linux/keyctl.h>])
+
+ AC_CHECK_MEMBERS([struct keyctl_dh_params.priv],,,[#include <linux/keyctl.h>])
])
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 02/36] lapi/keyctl.h: Add SAFE_ADD_KEY()
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
2026-09-16 14:03 ` [LTP] [PATCH v3 01/36] lapi/keyctl.h: Add fallback definitions for extended ops Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 9:38 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 03/36] tree: keyctl: Use SAFE_ADD_KEY() Petr Vorel
` (34 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
include/lapi/keyctl.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/include/lapi/keyctl.h b/include/lapi/keyctl.h
index 1c6627f555..4ba797bf9c 100644
--- a/include/lapi/keyctl.h
+++ b/include/lapi/keyctl.h
@@ -283,8 +283,35 @@ static inline long safe_keyctl(const char *file, const int lineno,
return rval;
}
+
#define SAFE_KEYCTL(cmd, arg2, arg3, arg4, arg5) \
safe_keyctl(__FILE__, __LINE__, \
(cmd), (arg2), (arg3), (arg4), (arg5))
+static inline key_serial_t safe_add_key(const char *file, const int lineno,
+ const char *type, const char *desc,
+ const void *payload, size_t size,
+ key_serial_t keyring)
+{
+
+ int rval;
+
+ rval = add_key(type, desc, payload, size, keyring);
+
+ if (rval == -1) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "add_key(%s, '%s', %p, %ld, %d) failed",
+ type, desc, payload, size, keyring);
+ } else if (rval < -1) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "Invalid add_key(%s, '%s', %p, %ld, %d) return value %d",
+ type, desc, payload, size, keyring, rval);
+ }
+
+ return rval;
+}
+
+#define SAFE_ADD_KEY(type, desc, payload, size, keyring) \
+ safe_add_key(__FILE__, __LINE__, \
+ (type), (desc), (payload), (size), (keyring))
#endif /* LAPI_KEYCTL_H__ */
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 03/36] tree: keyctl: Use SAFE_ADD_KEY()
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
2026-09-16 14:03 ` [LTP] [PATCH v3 01/36] lapi/keyctl.h: Add fallback definitions for extended ops Petr Vorel
2026-09-16 14:03 ` [LTP] [PATCH v3 02/36] lapi/keyctl.h: Add SAFE_ADD_KEY() Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 9:43 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 04/36] keyctl10: Test KEYCTL_DESCRIBE format parsing Petr Vorel
` (33 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
testcases/cve/cve-2016-7042.c | 4 +---
testcases/kernel/syscalls/add_key/add_key03.c | 9 ++-------
testcases/kernel/syscalls/add_key/add_key04.c | 14 ++++----------
testcases/kernel/syscalls/keyctl/keyctl02.c | 8 ++------
testcases/kernel/syscalls/keyctl/keyctl03.c | 4 +---
testcases/kernel/syscalls/keyctl/keyctl06.c | 6 ++----
.../kernel/syscalls/request_key/request_key01.c | 4 +---
.../kernel/syscalls/request_key/request_key02.c | 4 +---
testcases/kernel/watchqueue/common.h | 4 +---
9 files changed, 15 insertions(+), 42 deletions(-)
diff --git a/testcases/cve/cve-2016-7042.c b/testcases/cve/cve-2016-7042.c
index 24915ad441..0556789d61 100644
--- a/testcases/cve/cve-2016-7042.c
+++ b/testcases/cve/cve-2016-7042.c
@@ -25,9 +25,7 @@ static void do_test(void)
{
char buf[BUFSIZ];
- key = add_key("user", "ltptestkey", "a", 1, KEY_SPEC_SESSION_KEYRING);
- if (key == -1)
- tst_brk(TBROK, "Failed to add key");
+ key = SAFE_ADD_KEY("user", "ltptestkey", "a", 1, KEY_SPEC_SESSION_KEYRING);
if (keyctl(KEYCTL_UPDATE, key, "b", 1))
tst_brk(TBROK, "Failed to update key");
diff --git a/testcases/kernel/syscalls/add_key/add_key03.c b/testcases/kernel/syscalls/add_key/add_key03.c
index fe2406fcc2..4b0e49127e 100644
--- a/testcases/kernel/syscalls/add_key/add_key03.c
+++ b/testcases/kernel/syscalls/add_key/add_key03.c
@@ -24,13 +24,8 @@
static key_serial_t create_keyring(const char *description)
{
- TEST(add_key("keyring", description, NULL, 0,
- KEY_SPEC_PROCESS_KEYRING));
- if (TST_RET < 0) {
- tst_brk(TBROK | TTERRNO,
- "unable to create keyring '%s'", description);
- }
- return TST_RET;
+ return SAFE_ADD_KEY("keyring", description, NULL, 0,
+ KEY_SPEC_PROCESS_KEYRING);
}
static key_serial_t get_keyring_id(key_serial_t special_id)
diff --git a/testcases/kernel/syscalls/add_key/add_key04.c b/testcases/kernel/syscalls/add_key/add_key04.c
index 3fbb52479b..ff0895efd1 100644
--- a/testcases/kernel/syscalls/add_key/add_key04.c
+++ b/testcases/kernel/syscalls/add_key/add_key04.c
@@ -50,18 +50,12 @@ static void do_test(void)
for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++) {
sprintf(description, "keyring%d", i);
- TEST(add_key("keyring", description, NULL, 0,
- KEY_SPEC_SESSION_KEYRING));
- if (TST_RET < 0) {
- tst_brk(TBROK | TTERRNO,
- "unable to create keyring %d", i);
- }
+ SAFE_ADD_KEY("keyring", description, NULL, 0,
+ KEY_SPEC_SESSION_KEYRING);
}
- TEST(add_key("user", "userkey", payload, sizeof(PAYLOAD),
- KEY_SPEC_SESSION_KEYRING));
- if (TST_RET < 0)
- tst_brk(TBROK | TTERRNO, "unable to create user key");
+ SAFE_ADD_KEY("user", "userkey", payload, sizeof(PAYLOAD),
+ KEY_SPEC_SESSION_KEYRING);
exit(0);
}
diff --git a/testcases/kernel/syscalls/keyctl/keyctl02.c b/testcases/kernel/syscalls/keyctl/keyctl02.c
index 306181c44a..964dfad316 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl02.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl02.c
@@ -61,10 +61,8 @@ static void do_test(void)
pthread_t pth[4];
for (i = 0; i < LOOPS; i++) {
- key = add_key("user", "ltptestkey", "foo", 3,
+ key = SAFE_ADD_KEY("user", "ltptestkey", "foo", 3,
KEY_SPEC_PROCESS_KEYRING);
- if (key == -1)
- tst_brk(TBROK | TERRNO, "Failed to add key");
SAFE_PTHREAD_CREATE(&pth[0], NULL, do_read,
(void *)(unsigned long)key);
@@ -103,10 +101,8 @@ static void do_test(void)
*
* We create extra key here, to remove reference to last revoked key.
*/
- key_inv = add_key("user", "ltptestkey", "foo", 3,
+ key_inv = SAFE_ADD_KEY("user", "ltptestkey", "foo", 3,
KEY_SPEC_PROCESS_KEYRING);
- if (key_inv == -1)
- tst_brk(TBROK | TERRNO, "Failed to add key");
/*
* If we have invalidate, we can drop extra key immediately as well,
diff --git a/testcases/kernel/syscalls/keyctl/keyctl03.c b/testcases/kernel/syscalls/keyctl/keyctl03.c
index 676dddcd0b..d5339cb43d 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl03.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl03.c
@@ -20,9 +20,7 @@ static void do_test(void)
{
key_serial_t key;
- key = add_key("user", "ltptestkey", "a", 1, KEY_SPEC_SESSION_KEYRING);
- if (key == -1)
- tst_brk(TBROK, "Failed to add key");
+ key = SAFE_ADD_KEY("user", "ltptestkey", "a", 1, KEY_SPEC_SESSION_KEYRING);
request_key("keyring", "foo", "bar", KEY_SPEC_THREAD_KEYRING);
diff --git a/testcases/kernel/syscalls/keyctl/keyctl06.c b/testcases/kernel/syscalls/keyctl/keyctl06.c
index b3c61b9d15..e3fdbcb841 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl06.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl06.c
@@ -21,10 +21,8 @@
static void add_test_key(const char *description)
{
- TEST(add_key("user", description, "payload", 7,
- KEY_SPEC_PROCESS_KEYRING));
- if (TST_RET < 0)
- tst_brk(TBROK | TTERRNO, "Failed to add test key");
+ SAFE_ADD_KEY("user", description, "payload", 7,
+ KEY_SPEC_PROCESS_KEYRING);
}
static void do_test(void)
diff --git a/testcases/kernel/syscalls/request_key/request_key01.c b/testcases/kernel/syscalls/request_key/request_key01.c
index 97121533da..0aa5fd85f7 100644
--- a/testcases/kernel/syscalls/request_key/request_key01.c
+++ b/testcases/kernel/syscalls/request_key/request_key01.c
@@ -35,9 +35,7 @@ static void verify_request_key(void)
static void setup(void)
{
- key = add_key("keyring", "ltp", NULL, 0, KEY_SPEC_THREAD_KEYRING);
- if (key == -1)
- tst_brk(TBROK | TERRNO, "add_key() failed");
+ key = SAFE_ADD_KEY("keyring", "ltp", NULL, 0, KEY_SPEC_THREAD_KEYRING);
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/request_key/request_key02.c b/testcases/kernel/syscalls/request_key/request_key02.c
index 2d35aceeee..d7e0664e68 100644
--- a/testcases/kernel/syscalls/request_key/request_key02.c
+++ b/testcases/kernel/syscalls/request_key/request_key02.c
@@ -48,9 +48,7 @@ static int init_key(char *name, int cmd)
int n;
int sec = 1;
- n = add_key("keyring", name, NULL, 0, KEY_SPEC_THREAD_KEYRING);
- if (n == -1)
- tst_brk(TBROK | TERRNO, "add_key() failed");
+ n = SAFE_ADD_KEY("keyring", name, NULL, 0, KEY_SPEC_THREAD_KEYRING);
if (cmd == KEYCTL_REVOKE) {
if (keyctl(cmd, n) == -1)
diff --git a/testcases/kernel/watchqueue/common.h b/testcases/kernel/watchqueue/common.h
index 0921dce9a6..639dd4a7cd 100644
--- a/testcases/kernel/watchqueue/common.h
+++ b/testcases/kernel/watchqueue/common.h
@@ -81,9 +81,7 @@ static inline key_serial_t wqueue_add_key(int fd)
{
key_serial_t key;
- key = add_key("user", "ltptestkey", "a", 1, KEY_SPEC_SESSION_KEYRING);
- if (key == -1)
- tst_brk(TBROK, "add_key error: %s", tst_strerrno(errno));
+ key = SAFE_ADD_KEY("user", "ltptestkey", "a", 1, KEY_SPEC_SESSION_KEYRING);
SAFE_KEYCTL(KEYCTL_WATCH_KEY, key, fd, 0x01, 0);
SAFE_KEYCTL(KEYCTL_WATCH_KEY, KEY_SPEC_SESSION_KEYRING, fd, 0x02, 0);
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 04/36] keyctl10: Test KEYCTL_DESCRIBE format parsing
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (2 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 03/36] tree: keyctl: Use SAFE_ADD_KEY() Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 9:54 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 05/36] keyctl11: Test KEYCTL_DESCRIBE with exact buffer size Petr Vorel
` (32 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test the format parsing of KEYCTL_DESCRIBE: verify that describing
a valid key returns a string formatted as "type;uid;gid;perm;description"
and that all five fields match the key's attributes.
Also add keyctl_common.h helper header for shared test definitions.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: Define as macros, use safe_add_key(), remove search_ring() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl10.c | 99 +++++++++++++++++++
.../kernel/syscalls/keyctl/keyctl_common.h | 33 +++++++
4 files changed, 134 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl10.c
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl_common.h
diff --git a/runtest/syscalls b/runtest/syscalls
index d953f05588..9840cf678b 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -727,6 +727,7 @@ keyctl06 keyctl06
keyctl07 keyctl07
keyctl08 keyctl08
keyctl09 keyctl09
+keyctl10 keyctl10
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index f9948c1766..08b2d101db 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -7,3 +7,4 @@
/keyctl07
/keyctl08
/keyctl09
+/keyctl10
diff --git a/testcases/kernel/syscalls/keyctl/keyctl10.c b/testcases/kernel/syscalls/keyctl/keyctl10.c
new file mode 100644
index 0000000000..f069e91d37
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl10.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test the format parsing of ``KEYCTL_DESCRIBE`` of :manpage:`keyctl(2)`.
+ *
+ * ``KEYCTL_DESCRIBE`` formats a key description as
+ * "type;uid;gid;perm;description" and returns the full length of the
+ * string including the terminating NUL byte.
+ *
+ * [Algorithm]
+ *
+ * - describe a valid key and verify all five fields of the description
+ * match the key's attributes
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "keyctl_common.h"
+
+#define KEY_DESC "ltpkeyctl10"
+#define PAYLOAD "payload"
+#define BUF_SIZE 64
+
+static key_serial_t key;
+static long desc_len;
+static char buf[BUF_SIZE];
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key = SAFE_NEW_USER_KEY(KEY_DESC, PAYLOAD, sizeof(PAYLOAD),
+ KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key, KEY_PERM_SET, 0, 0);
+
+ TEST(keyctl(KEYCTL_DESCRIBE, key, (unsigned long)NULL, 0, 0));
+ if (TST_RET < 0)
+ tst_brk(TBROK | TTERRNO, "KEYCTL_DESCRIBE failed");
+
+ desc_len = TST_RET;
+}
+
+static void run(void)
+{
+ char type[32], desc[BUF_SIZE];
+ unsigned int uid, gid, perm;
+
+ memset(buf, 0, sizeof(buf));
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_DESCRIBE, key, (unsigned long)buf,
+ sizeof(buf), 0), desc_len);
+ if (!TST_PASS)
+ return;
+
+ TST_EXP_EQ_SZ_SILENT((size_t)desc_len, strlen(buf) + 1);
+ if (!TST_PASS) {
+ tst_res(TINFO, "unexpected description '%s'", buf);
+ return;
+ }
+
+ if (sscanf(buf, "%31[^;];%u;%u;%x;%63[^\n]",
+ type, &uid, &gid, &perm, desc) != 5) {
+ tst_res(TFAIL, "malformed description '%s'", buf);
+ return;
+ }
+
+ if (strcmp(type, "user")) {
+ tst_res(TFAIL, "wrong key type '%s', expected 'user'", type);
+ return;
+ }
+
+ if (uid != getuid() || gid != getgid()) {
+ tst_res(TFAIL, "wrong owner uid %u gid %u, expected %u %u",
+ uid, gid, getuid(), getgid());
+ return;
+ }
+
+ if (perm != KEY_PERM_SET) {
+ tst_res(TFAIL, "wrong permissions %08x, expected %08x",
+ perm, KEY_PERM_SET);
+ return;
+ }
+
+ if (strcmp(desc, KEY_DESC)) {
+ tst_res(TFAIL, "wrong description '%s', expected '%s'",
+ desc, KEY_DESC);
+ return;
+ }
+
+ tst_res(TPASS, "described the key correctly");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl_common.h b/testcases/kernel/syscalls/keyctl/keyctl_common.h
new file mode 100644
index 0000000000..1063163bc1
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl_common.h
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+#ifndef KEYCTL_COMMON_H__
+#define KEYCTL_COMMON_H__
+
+#include <stdint.h>
+#include <string.h>
+
+#include "tst_test.h"
+#include "lapi/keyctl.h"
+
+#define KEY_PERM_ALL (KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)
+#define KEY_PERM_SET (KEY_POS_ALL | KEY_USR_ALL)
+
+#define KEY_VIEW_BITS (KEY_POS_VIEW | KEY_USR_VIEW | KEY_GRP_VIEW | KEY_OTH_VIEW)
+#define KEY_PERM_NO_VIEW (KEY_PERM_ALL & ~KEY_VIEW_BITS)
+
+#define KEY_WRITE_BITS (KEY_POS_WRITE | KEY_USR_WRITE | KEY_GRP_WRITE | KEY_OTH_WRITE)
+#define KEY_PERM_NO_WRITE (KEY_PERM_ALL & ~KEY_WRITE_BITS)
+
+#define KEY_SETATTR_BITS (KEY_POS_SETATTR | KEY_USR_SETATTR | KEY_GRP_SETATTR | KEY_OTH_SETATTR)
+#define KEY_PERM_NO_SETATTR (KEY_PERM_ALL & ~KEY_SETATTR_BITS)
+
+#define SAFE_NEW_RING(desc) \
+ safe_add_key(__FILE__, __LINE__, "keyring", (desc), NULL, 0, KEY_SPEC_PROCESS_KEYRING)
+
+#define SAFE_NEW_USER_KEY(desc, payload, plen, ring) \
+ safe_add_key(__FILE__, __LINE__, "user", (desc), (payload), (plen), (ring))
+
+#endif /* KEYCTL_COMMON_H__ */
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 05/36] keyctl11: Test KEYCTL_DESCRIBE with exact buffer size
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (3 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 04/36] keyctl10: Test KEYCTL_DESCRIBE format parsing Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-16 18:19 ` [LTP] lapi/keyctl.h: Add fallback definitions for extended ops linuxtestproject.agent
2026-09-17 11:07 ` [LTP] [PATCH v3 05/36] keyctl11: Test KEYCTL_DESCRIBE with exact buffer size Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 06/36] keyctl12: Test KEYCTL_DESCRIBE with too small buffer Petr Vorel
` (31 subsequent siblings)
36 siblings, 2 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_DESCRIBE when called with a buffer sized exactly to the
full description length: verify the string is copied completely
including the terminating NUL byte.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY(), memset() to 0xff ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl11.c | 62 +++++++++++++++++++++
3 files changed, 64 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl11.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 9840cf678b..a074af68dd 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -728,6 +728,7 @@ keyctl07 keyctl07
keyctl08 keyctl08
keyctl09 keyctl09
keyctl10 keyctl10
+keyctl11 keyctl11
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 08b2d101db..4974fe48d5 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -8,3 +8,4 @@
/keyctl08
/keyctl09
/keyctl10
+/keyctl11
diff --git a/testcases/kernel/syscalls/keyctl/keyctl11.c b/testcases/kernel/syscalls/keyctl/keyctl11.c
new file mode 100644
index 0000000000..83f4814df6
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl11.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_DESCRIBE`` of :manpage:`keyctl(2)` with exact buffer size.
+ *
+ * [Algorithm]
+ *
+ * Describe a key into a buffer sized exactly to the full string length,
+ * verify full string copy including terminating NUL byte.
+ */
+
+#include "keyctl_common.h"
+
+static key_serial_t key;
+static long desc_len;
+static char *buf;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key = SAFE_NEW_USER_KEY("k", "payload", 7, KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key, KEY_PERM_SET, 0, 0);
+
+ TEST(keyctl(KEYCTL_DESCRIBE, key, (unsigned long)NULL, 0, 0));
+ if (TST_RET < 0)
+ tst_brk(TBROK | TTERRNO, "KEYCTL_DESCRIBE failed");
+
+ desc_len = TST_RET;
+ buf = SAFE_MALLOC(desc_len);
+}
+
+static void cleanup(void)
+{
+ free(buf);
+}
+
+static void run(void)
+{
+ memset(buf, 0xff, desc_len);
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_DESCRIBE, key, (unsigned long)buf,
+ desc_len, 0), desc_len);
+ if (!TST_PASS)
+ return;
+
+ if (buf[desc_len - 1] != '\0') {
+ tst_res(TFAIL, "description is not NUL terminated");
+ return;
+ }
+
+ tst_res(TPASS, "full description including NUL fits exact %ld byte buffer",
+ desc_len);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] lapi/keyctl.h: Add fallback definitions for extended ops
2026-09-16 14:03 ` [LTP] [PATCH v3 05/36] keyctl11: Test KEYCTL_DESCRIBE with exact buffer size Petr Vorel
@ 2026-09-16 18:19 ` linuxtestproject.agent
2026-09-17 11:07 ` [LTP] [PATCH v3 05/36] keyctl11: Test KEYCTL_DESCRIBE with exact buffer size Cyril Hrubis
1 sibling, 0 replies; 79+ messages in thread
From: linuxtestproject.agent @ 2026-09-16 18:19 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi Andrea,
On Wed, 16 Sep 2026 16:03:27 +0200, Andrea Cervesato <andrea.cervesato@suse.com> wrote:
> lapi/keyctl.h: Add fallback definitions for extended ops
--- [PATCH 1/36] ---
> +#ifndef HAVE_STRUCT_KEYCTL_DH_PARAMS
> +struct keyctl_dh_params {
> + int32_t priv;
> + int32_t prime;
> + int32_t base;
> +};
> +#endif
HAVE_STRUCT_KEYCTL_DH_PARAMS_PRIV is probed in m4/ltp-keyutils.m4 for Leap
42.2 compatibility but is never handled here. When
HAVE_STRUCT_KEYCTL_DH_PARAMS is defined without
HAVE_STRUCT_KEYCTL_DH_PARAMS_PRIV, accessing dh_params->priv causes a build
failure. Add an alias:
#if defined(HAVE_STRUCT_KEYCTL_DH_PARAMS) && \
!defined(HAVE_STRUCT_KEYCTL_DH_PARAMS_PRIV)
# define priv private
#endif
--- [PATCH 2/36] ---
> + if (rval == -1) {
> + tst_brk_(file, lineno, TBROK | TERRNO,
> + "add_key(%s, '%s', %p, %ld, %d) failed",
> + type, desc, payload, size, keyring);
> + } else if (rval < -1) {
> + tst_brk_(file, lineno, TBROK | TERRNO,
> + "Invalid add_key(%s, '%s', %p, %ld, %d) return value %d",
> + type, desc, payload, size, keyring, rval);
> + }
The size parameter has type size_t, but %ld is used in the format strings.
Use %zu instead.
> +#define SAFE_ADD_KEY(type, desc, payload, size, keyring) \
> + safe_add_key(__FILE__, __LINE__, \
> + (type), (desc), (payload), (size), (keyring))
Use tabs instead of spaces for indentation.
--- [PATCH 4/36] ---
> +#define SAFE_NEW_RING(desc) \
> + safe_add_key(__FILE__, __LINE__, "keyring", (desc), NULL, 0, KEY_SPEC_PROCESS_KEYRING)
> +
> +#define SAFE_NEW_USER_KEY(desc, payload, plen, ring) \
> + safe_add_key(__FILE__, __LINE__, "user", (desc), (payload), (plen), (ring))
The SAFE_* prefix is reserved for LTP core library headers in include/.
Rename these macros without the SAFE_ prefix (e.g. NEW_RING and
NEW_USER_KEY) or move them to include/lapi/keyctl.h.
--- [PATCH 9/36] ---
> + rc = SAFE_KEYCTL(KEYCTL_GET_SECURITY, key, (unsigned long)buf, sizeof(buf), 0);
> +
> + if (buf[0] != '\0')
> + tst_res(TFAIL, "empty label is not NUL terminated");
Checking buf[0] != '\0' unconditionally fails on systems where an LSM
(such as SELinux or Smack) is active and returns a non-empty security label.
Check buf[rc - 1] != '\0' instead to verify NUL-termination, or only check
buf[0] == '\0' when rc == 1.
--- [PATCH 14/36] ---
> +static void run(void)
> +{
> + SAFE_KEYCTL(KEYCTL_LINK, key_a, ring_a, 0, 0);
> + TST_EXP_PASS(keyctl(KEYCTL_MOVE, key_a, ring_a, ring_b, 0));
> +
> + TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring_b, "user", KEY_DESC), key_a);
> +}
When running multiple iterations (-i), key_excl is displaced from ring_b
in the first iteration and is never re-linked to ring_b. Subsequent
iterations therefore do not test displacement. Re-link key_excl to ring_b
in run() before moving key_a.
--- [PATCH 17/36] ---
> case 'i':
> - iterations = SAFE_STRTOL(optarg, 0, INT_MAX);
> + tst_test->iterations = SAFE_STRTOL(optarg, 0, UINT_MAX);
Passing UINT_MAX to SAFE_STRTOL() breaks on 32-bit architectures because
safe_strtol() takes signed long, where UINT_MAX (0xFFFFFFFF) converts to
-1L. This makes safe_strtol() reject any positive iteration count as out of
range 0 to -1. Use SAFE_STRTOUL(optarg, 0, UINT_MAX) or keep INT_MAX.
--- [PATCH 35/36] ---
> + .ulimit = (const struct tst_ulimit_val []) {
> + {RLIMIT_NOFILE, 524288},
> + {}
> + },
Setting .ulimit requires .needs_root = 1 when raising limits above the
current maximum. Without root privileges, safe_setrlimit() fails with
EPERM and aborts the test with TBROK. Either drop .ulimit or add
.needs_root = 1.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 05/36] keyctl11: Test KEYCTL_DESCRIBE with exact buffer size
2026-09-16 14:03 ` [LTP] [PATCH v3 05/36] keyctl11: Test KEYCTL_DESCRIBE with exact buffer size Petr Vorel
2026-09-16 18:19 ` [LTP] lapi/keyctl.h: Add fallback definitions for extended ops linuxtestproject.agent
@ 2026-09-17 11:07 ` Cyril Hrubis
1 sibling, 0 replies; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-17 11:07 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 06/36] keyctl12: Test KEYCTL_DESCRIBE with too small buffer
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (4 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 05/36] keyctl11: Test KEYCTL_DESCRIBE with exact buffer size Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 11:14 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 07/36] keyctl13: Test KEYCTL_DESCRIBE size query Petr Vorel
` (30 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_DESCRIBE when called with a buffer smaller than the
full description length: verify the buffer is left untouched and the
return value still reports the full length.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl12.c | 62 +++++++++++++++++++++
3 files changed, 64 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl12.c
diff --git a/runtest/syscalls b/runtest/syscalls
index a074af68dd..ef6a2ba536 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -729,6 +729,7 @@ keyctl08 keyctl08
keyctl09 keyctl09
keyctl10 keyctl10
keyctl11 keyctl11
+keyctl12 keyctl12
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 4974fe48d5..9ce6e2250b 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -9,3 +9,4 @@
/keyctl09
/keyctl10
/keyctl11
+/keyctl12
diff --git a/testcases/kernel/syscalls/keyctl/keyctl12.c b/testcases/kernel/syscalls/keyctl/keyctl12.c
new file mode 100644
index 0000000000..7c2b9e95e8
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl12.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_DESCRIBE`` of :manpage:`keyctl(2)` with too small buffer.
+ *
+ * [Algorithm]
+ *
+ * - describe a key with buffer smaller than full length, verify the buffer
+ * remains untouched and the return value is unchanged
+ */
+
+#include "keyctl_common.h"
+
+#define BUF_SIZE 64
+
+static key_serial_t key;
+static long desc_len;
+static char buf[BUF_SIZE];
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key = SAFE_NEW_USER_KEY("k", "payload", 7, KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key, KEY_PERM_SET, 0, 0);
+
+ TEST(keyctl(KEYCTL_DESCRIBE, key, (unsigned long)NULL, 0, 0));
+ if (TST_RET < 0)
+ tst_brk(TBROK | TTERRNO, "KEYCTL_DESCRIBE failed");
+
+ desc_len = TST_RET;
+}
+
+static void run(void)
+{
+ size_t i;
+
+ memset(buf, 0xAA, sizeof(buf));
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_DESCRIBE, key, (unsigned long)buf,
+ desc_len - 1, 0), desc_len);
+ if (!TST_PASS)
+ return;
+
+ for (i = 0; i < sizeof(buf); i++) {
+ if (buf[i] != (char)0xAA) {
+ tst_res(TFAIL,
+ "too small buffer was written to at offset %zu",
+ i);
+ return;
+ }
+ }
+
+ tst_res(TPASS, "too small buffer was left untouched");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 07/36] keyctl13: Test KEYCTL_DESCRIBE size query
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (5 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 06/36] keyctl12: Test KEYCTL_DESCRIBE with too small buffer Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 11:32 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 08/36] keyctl14: Negative tests for KEYCTL_DESCRIBE Petr Vorel
` (29 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_DESCRIBE when called with a NULL buffer and buflen 0:
verify the call succeeds and returns the full description length
without writing to userspace memory.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl13.c | 46 +++++++++++++++++++++
3 files changed, 48 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl13.c
diff --git a/runtest/syscalls b/runtest/syscalls
index ef6a2ba536..1199277da0 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -730,6 +730,7 @@ keyctl09 keyctl09
keyctl10 keyctl10
keyctl11 keyctl11
keyctl12 keyctl12
+keyctl13 keyctl13
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 9ce6e2250b..d4ce61a6ee 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -10,3 +10,4 @@
/keyctl10
/keyctl11
/keyctl12
+/keyctl13
diff --git a/testcases/kernel/syscalls/keyctl/keyctl13.c b/testcases/kernel/syscalls/keyctl/keyctl13.c
new file mode 100644
index 0000000000..70f3f5b846
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl13.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_DESCRIBE`` of :manpage:`keyctl(2)` with NULL buffer and buflen 0.
+ *
+ * [Algorithm]
+ *
+ * - describe a key with NULL buffer and ``buflen = 0``, verify the full length
+ * is returned without writing
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "keyctl_common.h"
+
+static key_serial_t key;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key = SAFE_NEW_USER_KEY("k", "payload", 7, KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key, KEY_PERM_SET, 0, 0);
+}
+
+static void run(void)
+{
+ char expected[64];
+ long expected_len;
+
+ expected_len = snprintf(expected, sizeof(expected),
+ "user;%u;%u;%08x;k",
+ getuid(), getgid(), KEY_PERM_SET) + 1;
+
+ TST_EXP_VAL(keyctl(KEYCTL_DESCRIBE, key, (unsigned long)NULL, 0, 0),
+ expected_len);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 08/36] keyctl14: Negative tests for KEYCTL_DESCRIBE
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (6 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 07/36] keyctl13: Test KEYCTL_DESCRIBE size query Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 15:42 ` Petr Vorel
2026-09-16 14:03 ` [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval Petr Vorel
` (28 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test error conditions of KEYCTL_DESCRIBE using a parameterized
tcase table: verify ENOKEY on a bogus key id and EACCES when View
permission is missing.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl14.c | 54 +++++++++++++++++++++
3 files changed, 56 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl14.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 1199277da0..244fea95f4 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -731,6 +731,7 @@ keyctl10 keyctl10
keyctl11 keyctl11
keyctl12 keyctl12
keyctl13 keyctl13
+keyctl14 keyctl14
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index d4ce61a6ee..8120454d8c 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -11,3 +11,4 @@
/keyctl11
/keyctl12
/keyctl13
+/keyctl14
diff --git a/testcases/kernel/syscalls/keyctl/keyctl14.c b/testcases/kernel/syscalls/keyctl/keyctl14.c
new file mode 100644
index 0000000000..0323865c54
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl14.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Negative test cases for ``KEYCTL_DESCRIBE`` of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - describe with bogus key id fails with ``ENOKEY``
+ * - describe without View permission fails with ``EACCES``
+ */
+
+#include "keyctl_common.h"
+
+#define BUF_SIZE 64
+
+static key_serial_t key_no_view;
+static key_serial_t bogus_id = INT32_MAX;
+static char buf[BUF_SIZE];
+
+static struct tcase {
+ key_serial_t *keyid;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ { &bogus_id, ENOKEY, "bogus key id" },
+ { &key_no_view, EACCES, "key without View permission" },
+};
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key_no_view = SAFE_NEW_USER_KEY("k_no_view", "payload", 7, KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key_no_view, KEY_PERM_NO_VIEW, 0, 0);
+}
+
+static void verify_negative(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ TST_EXP_FAIL2(keyctl(KEYCTL_DESCRIBE, (unsigned long)*tc->keyid,
+ (unsigned long)buf, sizeof(buf), 0),
+ tc->exp_errno,
+ "KEYCTL_DESCRIBE with %s", tc->desc);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test = verify_negative,
+ .tcnt = ARRAY_SIZE(tcases),
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (7 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 08/36] keyctl14: Negative tests for KEYCTL_DESCRIBE Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 8:54 ` Li Wang
2026-09-16 14:03 ` [LTP] [PATCH v3 10/36] keyctl16: Test KEYCTL_GET_SECURITY truncated copy Petr Vorel
` (27 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_GET_SECURITY label retrieval: verify reading the security
label of a valid key into a large buffer returns a positive length
and an empty string when no LSM label is set.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel:
* Always check for label being NUL terminated (Cyril)
* Use SAFE_NEW_USER_KEY(), SAFE_KEYCTL()
]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl15.c | 64 +++++++++++++++++++++
3 files changed, 66 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl15.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 244fea95f4..bdac6e09e1 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -732,6 +732,7 @@ keyctl11 keyctl11
keyctl12 keyctl12
keyctl13 keyctl13
keyctl14 keyctl14
+keyctl15 keyctl15
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 8120454d8c..852fee4eab 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -12,3 +12,4 @@
/keyctl12
/keyctl13
/keyctl14
+/keyctl15
diff --git a/testcases/kernel/syscalls/keyctl/keyctl15.c b/testcases/kernel/syscalls/keyctl/keyctl15.c
new file mode 100644
index 0000000000..9af3dd3527
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl15.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_GET_SECURITY`` label retrieval of :manpage:`keyctl(2)`.
+ *
+ * ``KEYCTL_GET_SECURITY`` reads the LSM security label of a key.
+ * When no label is set (no LSM enabled or the LSM does not label keys)
+ * the operation returns 1 and an empty string.
+ *
+ * [Algorithm]
+ *
+ * - read the label of a valid key into a large buffer, verify the return
+ * value is at least 1 and an empty string is returned when no label is set
+ */
+
+#include "keyctl_common.h"
+
+#define KEY_DESC "ltpkeyctl15"
+#define PAYLOAD "payload"
+#define BUF_SIZE 128
+
+static key_serial_t key;
+static char buf[BUF_SIZE];
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key = SAFE_NEW_USER_KEY(KEY_DESC, PAYLOAD, sizeof(PAYLOAD),
+ KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key, KEY_PERM_SET, 0, 0);
+}
+
+static void run(void)
+{
+ int rc;
+
+ memset(buf, 0, sizeof(buf));
+
+ rc = SAFE_KEYCTL(KEYCTL_GET_SECURITY, key, (unsigned long)buf, sizeof(buf), 0);
+
+ if (buf[0] != '\0')
+ tst_res(TFAIL, "empty label is not NUL terminated");
+
+ if (rc < 1) {
+ tst_res(TFAIL, "returned %d, expected >= 1", rc);
+ return;
+ }
+
+ if (rc == 1) {
+ tst_res(TPASS, "no label set, empty string returned");
+ return;
+ }
+
+ tst_res(TPASS, "security label returned, full length %d", rc);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval
2026-09-16 14:03 ` [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval Petr Vorel
@ 2026-09-17 8:54 ` Li Wang
2026-09-17 11:50 ` Cyril Hrubis
0 siblings, 1 reply; 79+ messages in thread
From: Li Wang @ 2026-09-17 8:54 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
> +static void run(void)
> +{
> + int rc;
> +
> + memset(buf, 0, sizeof(buf));
> +
> + rc = SAFE_KEYCTL(KEYCTL_GET_SECURITY, key, (unsigned long)buf, sizeof(buf), 0);
> +
> + if (buf[0] != '\0')
> + tst_res(TFAIL, "empty label is not NUL terminated");
The code unconditionally checks if the buffer is empty (buf[0] != '\0')
without verifying the return code (rc) first. On a system has SELinux enabled,
the kernel returns a valid security label (length 54). Therefore, buf[0]
contains a valid character (not \0), which incorrectly triggers failure:
# getenforce
Enforcing
# ./keyctl15
tst_test.c:2067: TINFO: LTP version: 20260529
tst_test.c:2070: TINFO: Tested kernel: 6.6.145-10.sl26.x86_64 #1 SMP Mon Sep 14 12:59:37 CST 2026 x86_64
tst_kconfig.c:90: TINFO: Parsing kernel config '/proc/config.gz'
tst_test.c:1895: TINFO: Overall timeout per run is 0h 00m 30s
keyctl15.c:46: TFAIL: empty label is not NUL terminated
keyctl15.c:58: TPASS: security label returned, full length 54
...
Maybe refine it like below:
static void run(void)
{
int rc;
memset(buf, 0, sizeof(buf));
rc = SAFE_KEYCTL(KEYCTL_GET_SECURITY, key, (unsigned long)buf, sizeof(buf), 0);
if (rc < 1) {
tst_res(TFAIL, "returned %d, expected >= 1", rc);
return;
}
if (rc == 1) {
if (buf[0] != '\0')
tst_res(TFAIL, "empty label is not NUL terminated");
else
tst_res(TPASS, "no label set, empty string returned");
return;
}
if (buf[0] == '\0')
tst_res(TFAIL, "non-empty label is NUL terminated");
else
tst_res(TPASS, "security label returned, full length %d", rc);
}
> +
> + if (rc < 1) {
> + tst_res(TFAIL, "returned %d, expected >= 1", rc);
> + return;
> + }
> +
> + if (rc == 1) {
> + tst_res(TPASS, "no label set, empty string returned");
> + return;
> + }
> +
> + tst_res(TPASS, "security label returned, full length %d", rc);
> +}
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval
2026-09-17 8:54 ` Li Wang
@ 2026-09-17 11:50 ` Cyril Hrubis
2026-09-18 5:01 ` Li Wang
0 siblings, 1 reply; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-17 11:50 UTC (permalink / raw)
To: Petr Vorel, ltp, Andrea Cervesato
Hi!
> Maybe refine it like below:
>
> static void run(void)
> {
> int rc;
>
> memset(buf, 0, sizeof(buf));
>
> rc = SAFE_KEYCTL(KEYCTL_GET_SECURITY, key, (unsigned long)buf, sizeof(buf), 0);
>
> if (rc < 1) {
> tst_res(TFAIL, "returned %d, expected >= 1", rc);
> return;
> }
>
> if (rc == 1) {
> if (buf[0] != '\0')
> tst_res(TFAIL, "empty label is not NUL terminated");
> else
> tst_res(TPASS, "no label set, empty string returned");
> return;
> }
>
> if (buf[0] == '\0')
> tst_res(TFAIL, "non-empty label is NUL terminated");
> else
> tst_res(TPASS, "security label returned, full length %d", rc);
> }
Shouldn't we check that the security label is NUL terminated as well?
The algorithm description in the doc comment actually says what should
be done:
if (rc == 0) {
tst_res(TFAIL, "empty security label not NUL terminated");
return;
}
if (rc > sizeof(buf)) {
tst_res(TFAIL, "buffer too small");
return;
}
if (buf[rc-1] != '\0') {
tst_res(TFAIL, "security label not NUL terminated");
return;
}
tst_res(TPASS, "Security label was NUL terminated");
And perhaps we can as well check that there is no NUL byte in the buffer
before rc as well:
for (i = 0; i < rc; i++) {
if (buf[i] == '\0')
tst_res(TFAIL, "NUL in the middle of security label at %i", buf[i]);
}
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval
2026-09-17 11:50 ` Cyril Hrubis
@ 2026-09-18 5:01 ` Li Wang
2026-09-18 9:50 ` Cyril Hrubis
0 siblings, 1 reply; 79+ messages in thread
From: Li Wang @ 2026-09-18 5:01 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
On Thu, Sep 17, 2026 at 01:50:39PM +0200, Cyril Hrubis wrote:
> Hi!
> > Maybe refine it like below:
> >
> > static void run(void)
> > {
> > int rc;
> >
> > memset(buf, 0, sizeof(buf));
> >
> > rc = SAFE_KEYCTL(KEYCTL_GET_SECURITY, key, (unsigned long)buf, sizeof(buf), 0);
> >
> > if (rc < 1) {
> > tst_res(TFAIL, "returned %d, expected >= 1", rc);
> > return;
> > }
> >
> > if (rc == 1) {
> > if (buf[0] != '\0')
> > tst_res(TFAIL, "empty label is not NUL terminated");
> > else
> > tst_res(TPASS, "no label set, empty string returned");
> > return;
> > }
> >
> > if (buf[0] == '\0')
> > tst_res(TFAIL, "non-empty label is NUL terminated");
> > else
> > tst_res(TPASS, "security label returned, full length %d", rc);
> > }
>
> Shouldn't we check that the security label is NUL terminated as well?
>
> The algorithm description in the doc comment actually says what should
> be done:
Yes, you're right.
>
> if (rc == 0) {
> tst_res(TFAIL, "empty security label not NUL terminated");
> return;
> }
>
> if (rc > sizeof(buf)) {
> tst_res(TFAIL, "buffer too small");
> return;
> }
My only concern is whether the TFAIL is correct when truncation
occurs. Shouldn't the test allocate a larger buffer instead?
The rest looks good.
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval
2026-09-18 5:01 ` Li Wang
@ 2026-09-18 9:50 ` Cyril Hrubis
2026-09-18 10:59 ` Petr Vorel
0 siblings, 1 reply; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-18 9:50 UTC (permalink / raw)
To: Petr Vorel, ltp, Andrea Cervesato
> > if (rc == 0) {
> > tst_res(TFAIL, "empty security label not NUL terminated");
> > return;
> > }
> >
> > if (rc > sizeof(buf)) {
> > tst_res(TFAIL, "buffer too small");
> > return;
> > }
>
> My only concern is whether the TFAIL is correct when truncation
> occurs. Shouldn't the test allocate a larger buffer instead?
Well we can always allocate large enough buffer in the test setup.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval
2026-09-18 9:50 ` Cyril Hrubis
@ 2026-09-18 10:59 ` Petr Vorel
0 siblings, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-18 10:59 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
Hi Li Cyril,
> > > if (rc == 0) {
> > > tst_res(TFAIL, "empty security label not NUL terminated");
> > > return;
> > > }
> > > if (rc > sizeof(buf)) {
> > > tst_res(TFAIL, "buffer too small");
> > > return;
> > > }
> > My only concern is whether the TFAIL is correct when truncation
> > occurs. Shouldn't the test allocate a larger buffer instead?
> Well we can always allocate large enough buffer in the test setup.
Do you agree with these changes?
BTW it'd be nice to get this merged before git freeze, but that's today night.
Kind regards,
Petr
+++ testcases/kernel/syscalls/keyctl/keyctl15.c
@@ -12,15 +12,16 @@
*
* [Algorithm]
*
- * - read the label of a valid key into a large buffer, verify the return
- * value is at least 1 and an empty string is returned when no label is set
+ * - read the label of a valid key into a large buffer
+ * - verify the return value is at least 1 and an empty string is returned when
+ * no label is set
*/
#include "keyctl_common.h"
#define KEY_DESC "ltpkeyctl15"
#define PAYLOAD "payload"
-#define BUF_SIZE 128
+#define BUF_SIZE 256
static key_serial_t key;
static char buf[BUF_SIZE];
@@ -42,20 +43,17 @@ static void run(void)
rc = SAFE_KEYCTL(KEYCTL_GET_SECURITY, key, (unsigned long)buf, sizeof(buf), 0);
- if (buf[0] != '\0')
- tst_res(TFAIL, "empty label is not NUL terminated");
-
- if (rc < 1) {
- tst_res(TFAIL, "returned %d, expected >= 1", rc);
+ if (rc == 0) {
+ tst_res(TFAIL, "empty security label not NUL terminated");
return;
}
- if (rc == 1) {
- tst_res(TPASS, "no label set, empty string returned");
+ if (buf[rc-1] != '\0') {
+ tst_res(TFAIL, "security label not NUL terminated");
return;
}
- tst_res(TPASS, "security label returned, full length %d", rc);
+ tst_res(TPASS, "Security label was NUL terminated");
}
static struct tst_test test = {
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 10/36] keyctl16: Test KEYCTL_GET_SECURITY truncated copy
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (8 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 09/36] keyctl15: Test KEYCTL_GET_SECURITY label retrieval Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 14:01 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 11/36] keyctl17: Negative tests for KEYCTL_GET_SECURITY Petr Vorel
` (26 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_GET_SECURITY truncated copy behavior: verify that calling
with a 1-byte buffer receives exactly one byte while the return value
still reports the full label length.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl16.c | 74 +++++++++++++++++++++
3 files changed, 76 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl16.c
diff --git a/runtest/syscalls b/runtest/syscalls
index bdac6e09e1..210552fec1 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -733,6 +733,7 @@ keyctl12 keyctl12
keyctl13 keyctl13
keyctl14 keyctl14
keyctl15 keyctl15
+keyctl16 keyctl16
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 852fee4eab..c351716d07 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -13,3 +13,4 @@
/keyctl13
/keyctl14
/keyctl15
+/keyctl16
diff --git a/testcases/kernel/syscalls/keyctl/keyctl16.c b/testcases/kernel/syscalls/keyctl/keyctl16.c
new file mode 100644
index 0000000000..76e6ab7511
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl16.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_GET_SECURITY`` truncated copy of :manpage:`keyctl(2)`.
+ *
+ * ``KEYCTL_GET_SECURITY`` returns the full length of the label, but unlike
+ * ``KEYCTL_DESCRIBE`` the kernel performs a truncated copy when the user
+ * buffer is too small.
+ *
+ * [Algorithm]
+ *
+ * - verify a one byte buffer receives exactly one byte while the full
+ * length is still returned
+ */
+
+#include "keyctl_common.h"
+
+#define KEY_DESC "ltpkeyctl16"
+#define PAYLOAD "payload"
+#define BUF_SIZE 128
+
+static key_serial_t key;
+static long sec_len;
+static char buf[BUF_SIZE];
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key = SAFE_NEW_USER_KEY(KEY_DESC, PAYLOAD, sizeof(PAYLOAD),
+ KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key, KEY_PERM_SET, 0, 0);
+
+ TEST(keyctl(KEYCTL_GET_SECURITY, key, (unsigned long)NULL, 0, 0));
+ if (TST_RET < 0)
+ tst_brk(TBROK | TTERRNO, "KEYCTL_GET_SECURITY failed");
+
+ sec_len = TST_RET;
+}
+
+static void run(void)
+{
+ size_t i;
+
+ memset(buf, 0xAA, sizeof(buf));
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_GET_SECURITY, key,
+ (unsigned long)buf, 1, 0), sec_len);
+ if (!TST_PASS)
+ return;
+
+ if (buf[0] == (char)0xAA) {
+ tst_res(TFAIL, "nothing was copied into the buffer");
+ return;
+ }
+
+ for (i = 1; i < sizeof(buf); i++) {
+ if (buf[i] != (char)0xAA) {
+ tst_res(TFAIL, "copy overran the buffer at offset %zu",
+ i);
+ return;
+ }
+ }
+
+ tst_res(TPASS, "exactly one byte copied, full length %ld returned",
+ sec_len);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 11/36] keyctl17: Negative tests for KEYCTL_GET_SECURITY
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (9 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 10/36] keyctl16: Test KEYCTL_GET_SECURITY truncated copy Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-16 14:03 ` [LTP] [PATCH v3 12/36] keyctl18: Test basic KEYCTL_MOVE Petr Vorel
` (25 subsequent siblings)
36 siblings, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test error conditions of KEYCTL_GET_SECURITY using a parameterized
tcase table: verify ENOKEY on a bogus key id and ENOKEY when View
permission is missing (due to the kernel request-key auth token
fallback path).
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl17.c | 55 +++++++++++++++++++++
3 files changed, 57 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl17.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 210552fec1..aba31b2c27 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -734,6 +734,7 @@ keyctl13 keyctl13
keyctl14 keyctl14
keyctl15 keyctl15
keyctl16 keyctl16
+keyctl17 keyctl17
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index c351716d07..dddb45f856 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -14,3 +14,4 @@
/keyctl14
/keyctl15
/keyctl16
+/keyctl17
diff --git a/testcases/kernel/syscalls/keyctl/keyctl17.c b/testcases/kernel/syscalls/keyctl/keyctl17.c
new file mode 100644
index 0000000000..77e8fd6abe
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl17.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Negative test cases for ``KEYCTL_GET_SECURITY`` of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - get_security with bogus key id fails with ``ENOKEY``
+ * - get_security without View permission fails with ``ENOKEY`` (the kernel
+ * falls back to looking for an auth token and returns its ``ENOKEY``)
+ */
+
+#include "keyctl_common.h"
+
+#define BUF_SIZE 128
+
+static key_serial_t key_no_view;
+static key_serial_t bogus_id = INT32_MAX;
+static char buf[BUF_SIZE];
+
+static struct tcase {
+ key_serial_t *keyid;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ { &bogus_id, ENOKEY, "bogus key id" },
+ { &key_no_view, ENOKEY, "key without View permission" },
+};
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key_no_view = SAFE_NEW_USER_KEY("k_no_view", "payload", 7, KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key_no_view, KEY_PERM_NO_VIEW, 0, 0);
+}
+
+static void verify_negative(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ TST_EXP_FAIL2(keyctl(KEYCTL_GET_SECURITY, (unsigned long)*tc->keyid,
+ (unsigned long)buf, sizeof(buf), 0),
+ tc->exp_errno,
+ "KEYCTL_GET_SECURITY with %s", tc->desc);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test = verify_negative,
+ .tcnt = ARRAY_SIZE(tcases),
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 12/36] keyctl18: Test basic KEYCTL_MOVE
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (10 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 11/36] keyctl17: Negative tests for KEYCTL_GET_SECURITY Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 9:51 ` Li Wang
2026-09-17 14:37 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 13/36] keyctl19: Test KEYCTL_MOVE with same source and destination Petr Vorel
` (24 subsequent siblings)
36 siblings, 2 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test basic moving of a key between two keyrings with KEYCTL_MOVE:
verify the key is moved to the destination and no longer found in
the source keyring.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel:
* Use SAFE_NEW_RING(), SAFE_NEW_USER_KEY(), keyctl() instead of
search_ring()
* Remove keyctl(KEYCTL_UNLINK, ...) check (Cyril)
]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
NOTE: I found on VM with 6.17.0-rc5-4.gc548b9b-default that keyctl15.c
fails:
keyctl15.c:46: TFAIL: empty label is not NUL terminated
That might be a reason why Andrea did not test it on failure
(modification asked by Cyril).
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl18.c | 51 +++++++++++++++++++++
3 files changed, 53 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl18.c
diff --git a/runtest/syscalls b/runtest/syscalls
index aba31b2c27..12923a4df2 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -735,6 +735,7 @@ keyctl14 keyctl14
keyctl15 keyctl15
keyctl16 keyctl16
keyctl17 keyctl17
+keyctl18 keyctl18
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index dddb45f856..808cd2d231 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -15,3 +15,4 @@
/keyctl15
/keyctl16
/keyctl17
+/keyctl18
diff --git a/testcases/kernel/syscalls/keyctl/keyctl18.c b/testcases/kernel/syscalls/keyctl/keyctl18.c
new file mode 100644
index 0000000000..25f99cc476
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl18.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test basic ``KEYCTL_MOVE`` of :manpage:`keyctl(2)`, added in Linux 5.3.
+ *
+ * [Algorithm]
+ *
+ * Move a key between two keyrings, verify it can be found only in the
+ * destination afterwards.
+ */
+
+#include "keyctl_common.h"
+
+#define RING_A_DESC "ltpkeyctl18_a"
+#define RING_B_DESC "ltpkeyctl18_b"
+#define KEY_DESC "k"
+#define PAYLOAD "payload"
+
+static key_serial_t ring_a, ring_b;
+static key_serial_t key;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ ring_a = SAFE_NEW_RING(RING_A_DESC);
+ ring_b = SAFE_NEW_RING(RING_B_DESC);
+ key = SAFE_NEW_USER_KEY(KEY_DESC, PAYLOAD, sizeof(PAYLOAD), ring_a);
+}
+
+static void run(void)
+{
+ SAFE_KEYCTL(KEYCTL_LINK, key, ring_a, 0, 0);
+ TST_EXP_PASS(keyctl(KEYCTL_MOVE, key, ring_a, ring_b, 0));
+ if (!TST_PASS)
+ return;
+
+ TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring_b, "user", KEY_DESC), key);
+
+ TST_EXP_FAIL2(keyctl(KEYCTL_SEARCH, ring_a, "user", KEY_DESC), ENOKEY,
+ "key no longer found in the source keyring");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "5.3",
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 12/36] keyctl18: Test basic KEYCTL_MOVE
2026-09-16 14:03 ` [LTP] [PATCH v3 12/36] keyctl18: Test basic KEYCTL_MOVE Petr Vorel
@ 2026-09-17 9:51 ` Li Wang
2026-09-17 14:37 ` Cyril Hrubis
1 sibling, 0 replies; 79+ messages in thread
From: Li Wang @ 2026-09-17 9:51 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
> +static void run(void)
> +{
> + SAFE_KEYCTL(KEYCTL_LINK, key, ring_a, 0, 0);
> + TST_EXP_PASS(keyctl(KEYCTL_MOVE, key, ring_a, ring_b, 0));
> + if (!TST_PASS)
> + return;
> +
> + TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring_b, "user", KEY_DESC), key);
> +
> + TST_EXP_FAIL2(keyctl(KEYCTL_SEARCH, ring_a, "user", KEY_DESC), ENOKEY,
> + "key no longer found in the source keyring");
> +}
To fix the KEYCTL_SEARCH args number:
--- a/testcases/kernel/syscalls/keyctl/keyctl18.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl18.c
@@ -38,9 +38,9 @@ static void run(void)
if (!TST_PASS)
return;
- TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring_b, "user", KEY_DESC), key);
+ TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring_b, "user", KEY_DESC, 0), key);
- TST_EXP_FAIL2(keyctl(KEYCTL_SEARCH, ring_a, "user", KEY_DESC), ENOKEY,
+ TST_EXP_FAIL2(keyctl(KEYCTL_SEARCH, ring_a, "user", KEY_DESC, 0), ENOKEY,
"key no longer found in the source keyring");
}
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 12/36] keyctl18: Test basic KEYCTL_MOVE
2026-09-16 14:03 ` [LTP] [PATCH v3 12/36] keyctl18: Test basic KEYCTL_MOVE Petr Vorel
2026-09-17 9:51 ` Li Wang
@ 2026-09-17 14:37 ` Cyril Hrubis
1 sibling, 0 replies; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-17 14:37 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
With the fix from Li:
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 13/36] keyctl19: Test KEYCTL_MOVE with same source and destination
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (11 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 12/36] keyctl18: Test basic KEYCTL_MOVE Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 9:37 ` Li Wang
2026-09-16 14:03 ` [LTP] [PATCH v3 14/36] keyctl20: Test KEYCTL_MOVE displacement Petr Vorel
` (23 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_MOVE when the source keyring equals the destination
keyring: verify the operation succeeds as a no-op and the key
remains linked in the keyring.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_RING(), SAFE_NEW_USER_KEY(), keyctl() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl19.c | 43 +++++++++++++++++++++
3 files changed, 45 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl19.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 12923a4df2..affa47e957 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -736,6 +736,7 @@ keyctl15 keyctl15
keyctl16 keyctl16
keyctl17 keyctl17
keyctl18 keyctl18
+keyctl19 keyctl19
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 808cd2d231..f321079233 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -16,3 +16,4 @@
/keyctl16
/keyctl17
/keyctl18
+/keyctl19
diff --git a/testcases/kernel/syscalls/keyctl/keyctl19.c b/testcases/kernel/syscalls/keyctl/keyctl19.c
new file mode 100644
index 0000000000..ba58ceede0
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl19.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_MOVE`` of :manpage:`keyctl(2)` with same source and destination.
+ *
+ * [Algorithm]
+ *
+ * - move a key where the source keyring equals the destination keyring,
+ * verify it is a successful no-op
+ */
+
+#include "keyctl_common.h"
+
+#define RING_DESC "ltpkeyctl19"
+#define KEY_DESC "k"
+#define PAYLOAD "payload"
+
+static key_serial_t ring;
+static key_serial_t key;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ ring = SAFE_NEW_RING(RING_DESC);
+ key = SAFE_NEW_USER_KEY(KEY_DESC, PAYLOAD, sizeof(PAYLOAD), ring);
+}
+
+static void run(void)
+{
+ TST_EXP_PASS(keyctl(KEYCTL_MOVE, key, ring, ring, 0));
+
+ TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring, "user", KEY_DESC), key);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "5.3",
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 13/36] keyctl19: Test KEYCTL_MOVE with same source and destination
2026-09-16 14:03 ` [LTP] [PATCH v3 13/36] keyctl19: Test KEYCTL_MOVE with same source and destination Petr Vorel
@ 2026-09-17 9:37 ` Li Wang
0 siblings, 0 replies; 79+ messages in thread
From: Li Wang @ 2026-09-17 9:37 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
> +static void run(void)
> +{
> + TST_EXP_PASS(keyctl(KEYCTL_MOVE, key, ring, ring, 0));
> +
> + TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring, "user", KEY_DESC), key);
This line should be:
TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring, "user", KEY_DESC, 0), key);
Otherwise test failed:
keyctl19.c:36: TFAIL: keyctl(KEYCTL_SEARCH, ring, "user", KEY_DESC) (-1) != key (966511877)
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 14/36] keyctl20: Test KEYCTL_MOVE displacement
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (12 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 13/36] keyctl19: Test KEYCTL_MOVE with same source and destination Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-17 9:38 ` Li Wang
2026-09-16 14:03 ` [LTP] [PATCH v3 15/36] keyctl21: Negative and boundary tests for KEYCTL_MOVE Petr Vorel
` (22 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_MOVE displacement behavior: verify moving a key without
KEYCTL_MOVE_EXCL into a destination holding a matching key displaces
the existing key.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel:
* Use SAFE_NEW_RING(), SAFE_NEW_USER_KEY(), keyctl() instead of
search_ring()
* Remove keyctl(KEYCTL_UNLINK, ...) check (Cyril) ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl20.c | 51 +++++++++++++++++++++
3 files changed, 53 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl20.c
diff --git a/runtest/syscalls b/runtest/syscalls
index affa47e957..63a16dd5a3 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -737,6 +737,7 @@ keyctl16 keyctl16
keyctl17 keyctl17
keyctl18 keyctl18
keyctl19 keyctl19
+keyctl20 keyctl20
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index f321079233..acddfa79ec 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -17,3 +17,4 @@
/keyctl17
/keyctl18
/keyctl19
+/keyctl20
diff --git a/testcases/kernel/syscalls/keyctl/keyctl20.c b/testcases/kernel/syscalls/keyctl/keyctl20.c
new file mode 100644
index 0000000000..31f1c25ae0
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl20.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_MOVE`` displacement of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - move a key without ``KEYCTL_MOVE_EXCL`` into a destination keyring that
+ * already contains a matching key, verify it displaces the existing key
+ */
+
+#include "keyctl_common.h"
+
+#define RING_A_DESC "ltpkeyctl20_a"
+#define RING_B_DESC "ltpkeyctl20_b"
+#define KEY_DESC "k"
+#define PAYLOAD "payload"
+
+static key_serial_t ring_a, ring_b;
+static key_serial_t key_a, key_excl;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ ring_a = SAFE_NEW_RING(RING_A_DESC);
+ ring_b = SAFE_NEW_RING(RING_B_DESC);
+
+ key_a = SAFE_NEW_USER_KEY(KEY_DESC, PAYLOAD, sizeof(PAYLOAD), ring_a);
+ key_excl = SAFE_NEW_USER_KEY(KEY_DESC, PAYLOAD, sizeof(PAYLOAD), ring_b);
+
+ /* Keep key_excl in session keyring so displacement does not destroy it */
+ SAFE_KEYCTL(KEYCTL_LINK, key_excl, KEY_SPEC_SESSION_KEYRING, 0, 0);
+}
+
+static void run(void)
+{
+ SAFE_KEYCTL(KEYCTL_LINK, key_a, ring_a, 0, 0);
+ TST_EXP_PASS(keyctl(KEYCTL_MOVE, key_a, ring_a, ring_b, 0));
+
+ TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring_b, "user", KEY_DESC), key_a);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "5.3",
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 14/36] keyctl20: Test KEYCTL_MOVE displacement
2026-09-16 14:03 ` [LTP] [PATCH v3 14/36] keyctl20: Test KEYCTL_MOVE displacement Petr Vorel
@ 2026-09-17 9:38 ` Li Wang
0 siblings, 0 replies; 79+ messages in thread
From: Li Wang @ 2026-09-17 9:38 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
> +static void run(void)
> +{
> + SAFE_KEYCTL(KEYCTL_LINK, key_a, ring_a, 0, 0);
> + TST_EXP_PASS(keyctl(KEYCTL_MOVE, key_a, ring_a, ring_b, 0));
> +
> + TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring_b, "user", KEY_DESC), key_a);
TST_EXP_EQ_LI(keyctl(KEYCTL_SEARCH, ring_b, "user", KEY_DESC, 0), key_a);
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 15/36] keyctl21: Negative and boundary tests for KEYCTL_MOVE
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (13 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 14/36] keyctl20: Test KEYCTL_MOVE displacement Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 11:24 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 16/36] keyctl22: Test KEYCTL_RESTRICT_KEYRING reject-all Petr Vorel
` (21 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test error and boundary conditions of KEYCTL_MOVE using a
parameterized tcase table: KEYCTL_MOVE_EXCL (EEXIST), unknown flag
bits (EINVAL), bogus IDs (ENOKEY), non-keyrings (ENOTDIR), unlinked
key (ENOENT), keyring cycle (EDEADLK), and destination without
Write permission (EACCES).
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_RING(), SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl21.c | 111 ++++++++++++++++++++
3 files changed, 113 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl21.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 63a16dd5a3..460d43850e 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -738,6 +738,7 @@ keyctl17 keyctl17
keyctl18 keyctl18
keyctl19 keyctl19
keyctl20 keyctl20
+keyctl21 keyctl21
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index acddfa79ec..e8c71e79e6 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -18,3 +18,4 @@
/keyctl18
/keyctl19
/keyctl20
+/keyctl21
diff --git a/testcases/kernel/syscalls/keyctl/keyctl21.c b/testcases/kernel/syscalls/keyctl/keyctl21.c
new file mode 100644
index 0000000000..a0578ea5b6
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl21.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Negative and boundary test cases for ``KEYCTL_MOVE`` of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - ``KEYCTL_MOVE_EXCL`` fails with ``EEXIST`` when the destination already
+ * holds a matching key
+ * - unknown flag bits are rejected with ``EINVAL``
+ * - bogus key or keyring ids fail with ``ENOKEY``
+ * - a plain key used as source or destination keyring fails with ``ENOTDIR``
+ * - moving a key that is not linked in the source fails with ``ENOENT``
+ * - moving a keyring into itself fails with ``EDEADLK`` from the keyring
+ * cycle detection
+ * - moving into a keyring without Write permission fails with ``EACCES``
+ */
+
+#include "keyctl_common.h"
+
+#define RING_A_DESC "ltpkeyctl21_a"
+#define RING_B_DESC "ltpkeyctl21_b"
+#define RING_C_DESC "ltpkeyctl21_c"
+#define KEY_A_DESC "ka"
+#define KEY_B_DESC "kb"
+#define PAYLOAD "payload"
+
+static key_serial_t ring_a, ring_b, ring_c, ring_no_write;
+static key_serial_t key_a, key_b, key_excl;
+static key_serial_t bogus_id = INT32_MAX;
+
+static struct tcase {
+ key_serial_t *keyid;
+ key_serial_t *from;
+ key_serial_t *to;
+ unsigned int flags;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ { &key_a, &ring_a, &ring_b, KEYCTL_MOVE_EXCL,
+ EEXIST, "KEYCTL_MOVE_EXCL on existing key" },
+
+ { &key_a, &ring_a, &ring_b, 0x2,
+ EINVAL, "unknown flag bits" },
+
+ { &bogus_id, &ring_a, &ring_b, 0,
+ ENOKEY, "bogus key id" },
+
+ { &key_a, &bogus_id, &ring_b, 0,
+ ENOKEY, "bogus source keyring" },
+
+ { &key_a, &ring_a, &bogus_id, 0,
+ ENOKEY, "bogus destination keyring" },
+
+ { &key_a, &key_b, &ring_b, 0,
+ ENOTDIR, "plain key as source keyring" },
+
+ { &key_a, &ring_a, &key_b, 0,
+ ENOTDIR, "plain key as destination keyring" },
+
+ { &key_b, &ring_a, &ring_b, 0,
+ ENOENT, "key not linked in the source keyring" },
+
+ { &ring_c, &ring_b, &ring_c, 0,
+ EDEADLK, "keyring into itself" },
+
+ { &key_a, &ring_a, &ring_no_write, 0,
+ EACCES, "destination without Write permission" },
+};
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ ring_a = SAFE_NEW_RING(RING_A_DESC);
+ ring_b = SAFE_NEW_RING(RING_B_DESC);
+ ring_c = SAFE_NEW_RING(RING_C_DESC);
+ ring_no_write = SAFE_NEW_RING("ltpkeyctl21_nowrite");
+ SAFE_KEYCTL(KEYCTL_SETPERM, ring_no_write, KEY_PERM_NO_WRITE, 0, 0);
+
+ key_a = SAFE_NEW_USER_KEY(KEY_A_DESC, PAYLOAD, sizeof(PAYLOAD), ring_a);
+ key_b = SAFE_NEW_USER_KEY(KEY_B_DESC, PAYLOAD, sizeof(PAYLOAD), ring_b);
+ key_excl = SAFE_NEW_USER_KEY(KEY_A_DESC, PAYLOAD, sizeof(PAYLOAD), ring_b);
+
+ /* Keep key_excl in session keyring */
+ SAFE_KEYCTL(KEYCTL_LINK, key_excl, KEY_SPEC_SESSION_KEYRING, 0, 0);
+
+ /* Link ring_c into ring_b for cycle test */
+ SAFE_KEYCTL(KEYCTL_LINK, ring_c, ring_b, 0, 0);
+}
+
+static void verify_negative(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ TST_EXP_FAIL(keyctl(KEYCTL_MOVE, (unsigned long)*tc->keyid,
+ (unsigned long)*tc->from, (unsigned long)*tc->to,
+ tc->flags),
+ tc->exp_errno,
+ "KEYCTL_MOVE with %s", tc->desc);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test = verify_negative,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "5.3",
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 16/36] keyctl22: Test KEYCTL_RESTRICT_KEYRING reject-all
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (14 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 15/36] keyctl21: Negative and boundary tests for KEYCTL_MOVE Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 11:29 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 17/36] lib: tst_test: Move the iterations to struct tst_test Petr Vorel
` (20 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_RESTRICT_KEYRING reject-all restriction: verify that
restricting a keyring with NULL type and NULL restriction succeeds,
and subsequent link and add_key attempts fail with EPERM.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_RING(), SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl22.c | 54 +++++++++++++++++++++
3 files changed, 56 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl22.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 460d43850e..d33b24167a 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -739,6 +739,7 @@ keyctl18 keyctl18
keyctl19 keyctl19
keyctl20 keyctl20
keyctl21 keyctl21
+keyctl22 keyctl22
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index e8c71e79e6..82a74e4a38 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -19,3 +19,4 @@
/keyctl19
/keyctl20
/keyctl21
+/keyctl22
diff --git a/testcases/kernel/syscalls/keyctl/keyctl22.c b/testcases/kernel/syscalls/keyctl/keyctl22.c
new file mode 100644
index 0000000000..79e9c3cd42
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl22.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_RESTRICT_KEYRING`` reject-all of :manpage:`keyctl(2)`,
+ * added in Linux 4.12.
+ *
+ * [Algorithm]
+ *
+ * - restrict a keyring with ``NULL`` type and ``NULL`` restriction (reject all links),
+ * verify subsequent links and add_key fail with ``EPERM``
+ */
+
+#include "keyctl_common.h"
+
+#define PAYLOAD "payload"
+
+static key_serial_t ring_reject;
+static key_serial_t user_key;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ ring_reject = SAFE_NEW_RING("ltpkeyctl22_reject");
+ user_key = SAFE_NEW_USER_KEY("k", PAYLOAD, sizeof(PAYLOAD),
+ KEY_SPEC_PROCESS_KEYRING);
+}
+
+static void run(void)
+{
+ TEST(keyctl(KEYCTL_RESTRICT_KEYRING, ring_reject, 0, 0, 0));
+ if (TST_RET == 0)
+ tst_res(TPASS, "KEYCTL_RESTRICT_KEYRING with NULL type and restriction passed");
+ else if (TST_RET == -1 && TST_ERR == EEXIST)
+ tst_res(TPASS, "KEYCTL_RESTRICT_KEYRING reject-all already active");
+ else
+ tst_res(TFAIL | TTERRNO, "KEYCTL_RESTRICT_KEYRING reject-all failed");
+
+ TST_EXP_FAIL(keyctl(KEYCTL_LINK, user_key, ring_reject, 0, 0), EPERM,
+ "KEYCTL_LINK on reject-all restricted keyring");
+
+ TST_EXP_FAIL2(add_key("user", "k_rej", PAYLOAD, sizeof(PAYLOAD),
+ ring_reject), EPERM,
+ "add_key on reject-all restricted keyring");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.12",
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 17/36] lib: tst_test: Move the iterations to struct tst_test
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (15 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 16/36] keyctl22: Test KEYCTL_RESTRICT_KEYRING reject-all Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-16 14:03 ` [LTP] [PATCH v3 18/36] keyctl23: Test KEYCTL_RESTRICT_KEYRING builtin_trusted Petr Vorel
` (19 subsequent siblings)
36 siblings, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Cyril Hrubis <chrubis@suse.cz>
This allows us to set the default number of iterations in the tst_test
structure.
Link: https://lore.kernel.org/ltp/20260624091900.4107041-9-chrubis@suse.cz/
Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
include/tst_test.h | 4 ++++
lib/tst_test.c | 8 +++++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/include/tst_test.h b/include/tst_test.h
index 53f58180f6..80b46f9b1e 100644
--- a/include/tst_test.h
+++ b/include/tst_test.h
@@ -479,6 +479,9 @@ struct tst_fs {
* probabilistic or fuzzy synchronization tests).
* If not set, a default minimum of 1 second is enforced.
*
+ * @iterations: The default value for the number of test iterations, i.e. the
+ * -i command line parameter.
+ *
* @setup: Setup callback is called once at the start of the test in order to
* prepare the test environment.
*
@@ -609,6 +612,7 @@ struct tst_fs {
int timeout;
int runtime;
int min_runtime;
+ unsigned int iterations;
void (*setup)(void);
void (*cleanup)(void);
diff --git a/lib/tst_test.c b/lib/tst_test.c
index f3f72141b0..2b38d0063d 100644
--- a/lib/tst_test.c
+++ b/lib/tst_test.c
@@ -64,7 +64,6 @@ const char *TCID __attribute__((weak));
struct tst_test *tst_test;
static const char *tcid;
-static int iterations = 1;
static float duration = -1;
static float timeout_mul = -1;
static int reproducible_output;
@@ -834,7 +833,7 @@ static void parse_opts(int argc, char *argv[])
print_test_tags();
exit(0);
case 'i':
- iterations = SAFE_STRTOL(optarg, 0, INT_MAX);
+ tst_test->iterations = SAFE_STRTOL(optarg, 0, UINT_MAX);
break;
case 'I':
if (tst_test->runtime > 0)
@@ -1502,6 +1501,9 @@ static void do_setup(int argc, char *argv[])
}
}
+ if (tst_test->iterations == 0)
+ tst_test->iterations = 1;
+
if (tst_test->mount_device)
tst_test->format_device = 1;
@@ -1788,7 +1790,7 @@ static void testrun(void)
for (;;) {
cont = 0;
- if (i < (unsigned int)iterations) {
+ if (i < tst_test->iterations) {
i++;
cont = 1;
}
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 18/36] keyctl23: Test KEYCTL_RESTRICT_KEYRING builtin_trusted
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (16 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 17/36] lib: tst_test: Move the iterations to struct tst_test Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 11:51 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 19/36] keyctl24: Negative tests for KEYCTL_RESTRICT_KEYRING Petr Vorel
` (18 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_RESTRICT_KEYRING builtin_trusted restriction: verify that
restricting a keyring with asymmetric builtin_trusted allows only
trusted asymmetric keys, rejecting user keys with EOPNOTSUPP and
untrusted certs with ENOKEY.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
[ pvorel:
* check asym. with !(TST_RET == -1 && TST_ERR == ENOKEY) instead of
(TST_RET != -1 || TST_ERR != ENODEV);
* Move check to is_asym_supported()
* Use tst_brk() on TCONF (Cyril) ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl23.c | 134 ++++++++++++++++++
.../kernel/syscalls/keyctl/keyctl_common.h | 9 ++
4 files changed, 145 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl23.c
diff --git a/runtest/syscalls b/runtest/syscalls
index d33b24167a..50708a00cf 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -740,6 +740,7 @@ keyctl19 keyctl19
keyctl20 keyctl20
keyctl21 keyctl21
keyctl22 keyctl22
+keyctl23 keyctl23
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 82a74e4a38..803e4e94c3 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -20,3 +20,4 @@
/keyctl20
/keyctl21
/keyctl22
+/keyctl23
diff --git a/testcases/kernel/syscalls/keyctl/keyctl23.c b/testcases/kernel/syscalls/keyctl/keyctl23.c
new file mode 100644
index 0000000000..af9218975b
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl23.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_RESTRICT_KEYRING`` builtin_trusted of :manpage:`keyctl(2)`.
+ *
+ * Requires root (CAP_SYS_MODULE) to load the ``x509_key_parser`` module.
+ *
+ * [Algorithm]
+ *
+ * - restrict a keyring with ``asymmetric`` and ``builtin_trusted``, verify
+ * linking a user key fails with ``EOPNOTSUPP`` and adding an untrusted
+ * cert fails with ``ENOKEY``
+ */
+
+#include "keyctl_common.h"
+#include "tst_module.h"
+
+#define PAYLOAD "payload"
+
+/*
+ * Self-signed RSA-2048 X.509 certificate in DER format generated using:
+ * openssl req -x509 -newkey rsa:2048 -subj "/CN=ltp-keyctl23-untrusted" \
+ * -days 36500 -nodes -batch -outform der
+ *
+ * Used only as an untrusted certificate to verify that add_key() on a
+ * keyring restricted with builtin_trusted rejects it with ENOKEY.
+ */
+static const unsigned char untrusted_cert[] = {
+ 0x30, 0x82, 0x03, 0x25, 0x30, 0x82, 0x02, 0x0d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x52,
+ 0xad, 0xef, 0x01, 0xca, 0xbb, 0x64, 0x17, 0xa7, 0x1a, 0xa7, 0xcb, 0x2f, 0x82, 0x44, 0x6e, 0xec,
+ 0x5a, 0x2e, 0x2c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x21, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x6c,
+ 0x74, 0x70, 0x2d, 0x6b, 0x65, 0x79, 0x63, 0x74, 0x6c, 0x32, 0x33, 0x2d, 0x75, 0x6e, 0x74, 0x72,
+ 0x75, 0x73, 0x74, 0x65, 0x64, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x39, 0x30, 0x32, 0x30,
+ 0x39, 0x32, 0x33, 0x34, 0x39, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x32, 0x36, 0x30, 0x38, 0x30, 0x39,
+ 0x30, 0x39, 0x32, 0x33, 0x34, 0x39, 0x5a, 0x30, 0x21, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x0c, 0x16, 0x6c, 0x74, 0x70, 0x2d, 0x6b, 0x65, 0x79, 0x63, 0x74, 0x6c, 0x32, 0x33,
+ 0x2d, 0x75, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd5, 0xee, 0x8d, 0xec, 0x85,
+ 0x8e, 0x29, 0xc7, 0xe7, 0xf8, 0x3f, 0xed, 0xc8, 0x82, 0xb2, 0x17, 0x95, 0xf4, 0xe0, 0x99, 0x02,
+ 0x84, 0xc5, 0xb3, 0x46, 0x62, 0x8c, 0x8a, 0xd3, 0x89, 0xd5, 0x62, 0x25, 0xa7, 0xc8, 0x92, 0xcc,
+ 0xc5, 0x64, 0x20, 0x80, 0xb7, 0xf3, 0xc2, 0x40, 0xdc, 0xf0, 0xf0, 0xd8, 0x85, 0x5f, 0x58, 0x61,
+ 0x77, 0xd6, 0xd5, 0x3a, 0x32, 0xec, 0x81, 0x15, 0x25, 0xb4, 0x08, 0x21, 0x6d, 0xf3, 0xd6, 0x80,
+ 0xa6, 0x91, 0x5a, 0x53, 0x9e, 0x54, 0x49, 0x5b, 0x91, 0x6b, 0x74, 0x0b, 0xb5, 0x99, 0xd5, 0x49,
+ 0x46, 0x41, 0x56, 0x67, 0xb4, 0xed, 0x17, 0x82, 0x96, 0x03, 0x40, 0xd7, 0x0d, 0x0a, 0x00, 0x95,
+ 0x3c, 0xb7, 0x75, 0x9e, 0x61, 0xab, 0xe9, 0x10, 0x4a, 0xa9, 0x90, 0x21, 0xd2, 0xb4, 0x3d, 0xd0,
+ 0x83, 0x48, 0x0c, 0x59, 0xa9, 0xd7, 0xbe, 0x7b, 0x4c, 0x75, 0xf0, 0xd1, 0x8a, 0x29, 0x1c, 0x06,
+ 0x35, 0x29, 0x6d, 0x3c, 0x6e, 0xb9, 0xce, 0x11, 0xa9, 0x1b, 0x4d, 0xf7, 0xfd, 0x6d, 0x2e, 0x02,
+ 0x7f, 0xbe, 0x45, 0xb7, 0x11, 0xae, 0x1d, 0xbb, 0x70, 0x02, 0xae, 0xc1, 0xb3, 0x31, 0x3d, 0x99,
+ 0xd9, 0x70, 0x01, 0xbd, 0xea, 0xd3, 0x0d, 0x04, 0xe0, 0x2f, 0xac, 0x79, 0xe4, 0xb2, 0x0c, 0x96,
+ 0xba, 0x66, 0x9e, 0xcf, 0x72, 0x13, 0xa3, 0x37, 0x44, 0x03, 0x2d, 0xe9, 0x5c, 0x71, 0x6f, 0x35,
+ 0x71, 0xf8, 0xdc, 0x58, 0xa3, 0x1f, 0x57, 0x88, 0x59, 0x79, 0xe6, 0x7e, 0x37, 0x9b, 0xc9, 0xa3,
+ 0x36, 0x03, 0x5c, 0xcb, 0x30, 0x92, 0x5e, 0x9e, 0x43, 0x48, 0xa2, 0x3e, 0x7f, 0xdc, 0xb8, 0xe3,
+ 0x6a, 0xe6, 0x8c, 0x18, 0xb2, 0x42, 0x4c, 0xbb, 0x2d, 0x6a, 0x6c, 0x5f, 0xd1, 0xc1, 0xd5, 0x33,
+ 0x3b, 0xdb, 0x8c, 0x3c, 0xa2, 0xec, 0xaa, 0xed, 0xce, 0xe1, 0xd1, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd3,
+ 0x8d, 0xd1, 0xe4, 0x77, 0x4e, 0xe2, 0xb2, 0xb6, 0xab, 0x31, 0x58, 0x69, 0x7b, 0x27, 0x31, 0xce,
+ 0x00, 0xcd, 0x60, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0xd3, 0x8d, 0xd1, 0xe4, 0x77, 0x4e, 0xe2, 0xb2, 0xb6, 0xab, 0x31, 0x58, 0x69, 0x7b, 0x27, 0x31,
+ 0xce, 0x00, 0xcd, 0x60, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+ 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x1e, 0xb9, 0x52, 0x16, 0xf2, 0xef, 0xca,
+ 0xbc, 0x35, 0x93, 0xb4, 0x38, 0xb8, 0xab, 0xfe, 0x73, 0x1a, 0x06, 0x50, 0x99, 0x58, 0xc4, 0xa8,
+ 0xf4, 0x26, 0xb1, 0xe1, 0x8e, 0x0b, 0xd3, 0xe7, 0xa8, 0x8d, 0x1f, 0xa0, 0x79, 0x4c, 0x9f, 0xdd,
+ 0x3a, 0xf0, 0xb7, 0xf2, 0x18, 0xfc, 0x99, 0x11, 0x45, 0x8f, 0xeb, 0xc9, 0xf2, 0x48, 0x2e, 0x4a,
+ 0x7b, 0x24, 0x37, 0xa4, 0xbc, 0x52, 0x96, 0x80, 0x76, 0x46, 0x59, 0x27, 0xb5, 0xa0, 0x07, 0x5b,
+ 0x6c, 0x38, 0x5c, 0xde, 0x95, 0x76, 0xfc, 0x21, 0xb8, 0x1e, 0x7e, 0x13, 0x3e, 0x59, 0x95, 0xf9,
+ 0x39, 0xdb, 0xd5, 0x41, 0x3d, 0x8d, 0xfd, 0x4c, 0x1a, 0x4b, 0xdd, 0x41, 0x3b, 0x27, 0x58, 0xf8,
+ 0x72, 0xa3, 0x70, 0x97, 0xc6, 0xb9, 0x0e, 0x4e, 0x3c, 0x08, 0xba, 0x2f, 0xa9, 0x55, 0x6d, 0x23,
+ 0xdd, 0xc4, 0x0a, 0x43, 0xad, 0x20, 0x75, 0x0d, 0xea, 0xbc, 0x49, 0x6c, 0xd2, 0x87, 0x59, 0x46,
+ 0x72, 0x3e, 0x77, 0x9b, 0x29, 0x63, 0x38, 0x0a, 0x2f, 0x61, 0xcc, 0xda, 0xd0, 0x21, 0x47, 0x6f,
+ 0x9f, 0x19, 0x26, 0x0c, 0xbb, 0x77, 0x22, 0x8d, 0xc7, 0x65, 0x01, 0x25, 0x4b, 0x69, 0x38, 0xae,
+ 0x6e, 0x16, 0x4f, 0x70, 0x35, 0xab, 0xea, 0x76, 0xe4, 0x37, 0xe4, 0x92, 0x6b, 0xf0, 0x6e, 0xc5,
+ 0x4c, 0xc1, 0x37, 0xc1, 0x28, 0xa6, 0x78, 0xc7, 0x90, 0xb4, 0xea, 0xbb, 0x8d, 0x12, 0xe1, 0x30,
+ 0xe1, 0x7b, 0x76, 0xc3, 0x65, 0xc3, 0x99, 0x7b, 0xb3, 0xb1, 0x9a, 0xe9, 0x73, 0xb2, 0x4d, 0x08,
+ 0x2a, 0xa4, 0x67, 0x42, 0xef, 0x7c, 0xf5, 0x67, 0x3e, 0xa4, 0x78, 0xe1, 0x04, 0x93, 0x5e, 0x1b,
+ 0xf9, 0xae, 0xe1, 0x5a, 0x7f, 0x42, 0x38, 0xb7, 0x93, 0xfb, 0x27, 0xff, 0x1c, 0x7e, 0xdd, 0x8a,
+ 0x71, 0x10, 0xcb, 0x65, 0xc9, 0xf2, 0x0f, 0x9e, 0x7d,
+};
+
+static key_serial_t ring_builtin;
+static key_serial_t user_key;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ tst_modprobe("x509_key_parser", NULL);
+
+ ring_builtin = SAFE_NEW_RING("ltpkeyctl23_builtin");
+
+ user_key = SAFE_NEW_USER_KEY("k", PAYLOAD, sizeof(PAYLOAD),
+ KEY_SPEC_PROCESS_KEYRING);
+
+ if (!is_asym_supported(ring_builtin))
+ tst_brk(TCONF, "asymmetric key type not supported");
+}
+
+static void run(void)
+{
+ TEST(keyctl(KEYCTL_RESTRICT_KEYRING, ring_builtin,
+ (unsigned long)"asymmetric",
+ (unsigned long)"builtin_trusted", 0));
+
+ if (TST_RET == -1 && TST_ERR == EOPNOTSUPP)
+ tst_brk(TCONF, "builtin_trusted restriction not supported");
+
+ if (TST_RET == 0)
+ tst_res(TPASS, "KEYCTL_RESTRICT_KEYRING builtin_trusted passed");
+ else if (TST_RET == -1 && TST_ERR == EEXIST)
+ tst_res(TPASS, "KEYCTL_RESTRICT_KEYRING builtin_trusted already active");
+ else
+ tst_res(TFAIL | TTERRNO, "KEYCTL_RESTRICT_KEYRING builtin_trusted failed");
+
+ TST_EXP_FAIL(keyctl(KEYCTL_LINK, user_key, ring_builtin, 0, 0),
+ EOPNOTSUPP,
+ "KEYCTL_LINK of non-asymmetric key on builtin_trusted restricted keyring");
+
+ TST_EXP_FAIL2(add_key("asymmetric", "cert", untrusted_cert,
+ sizeof(untrusted_cert), ring_builtin), ENOKEY,
+ "add_key of untrusted cert on builtin_trusted restricted keyring");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.12",
+ .needs_root = 1,
+ .iterations = 2,
+};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl_common.h b/testcases/kernel/syscalls/keyctl/keyctl_common.h
index 1063163bc1..1465824334 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl_common.h
+++ b/testcases/kernel/syscalls/keyctl/keyctl_common.h
@@ -7,6 +7,7 @@
#define KEYCTL_COMMON_H__
#include <stdint.h>
+#include <stdbool.h>
#include <string.h>
#include "tst_test.h"
@@ -30,4 +31,12 @@
#define SAFE_NEW_USER_KEY(desc, payload, plen, ring) \
safe_add_key(__FILE__, __LINE__, "user", (desc), (payload), (plen), (ring))
+static inline bool is_asym_supported(key_serial_t ring_builtin)
+{
+ TEST(keyctl(KEYCTL_RESTRICT_KEYRING, ring_builtin,
+ (unsigned long)"asymmetric", (unsigned long)"bogus", 0));
+
+ return !(TST_RET == -1 && TST_ERR == ENOKEY);
+}
+
#endif /* KEYCTL_COMMON_H__ */
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 19/36] keyctl24: Negative tests for KEYCTL_RESTRICT_KEYRING
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (17 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 18/36] keyctl23: Test KEYCTL_RESTRICT_KEYRING builtin_trusted Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 12:08 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 20/36] keyctl25: Test KEYCTL_DH_COMPUTE shared secret computation Petr Vorel
` (17 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test error conditions of KEYCTL_RESTRICT_KEYRING using a parameterized
tcase table: invalid type/restriction combinations (EINVAL), non-keyrings
(ENOTDIR), unknown key type (ENOKEY), key type without lookup (ENOENT),
invalid restriction string (EINVAL), bogus key serial (ENOKEY), already
restricted (EEXIST), self-chain cycle (EDEADLK), and missing Setattr
(EACCES).
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel:
* check asym. with !(TST_RET == -1 && TST_ERR == ENOKEY) instead of
(TST_RET != -1 || TST_ERR != ENODEV)
* Use is_asym_supported(), SAFE_NEW_RING(), SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl24.c | 171 ++++++++++++++++++++
3 files changed, 173 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl24.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 50708a00cf..6ee6ec56a8 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -741,6 +741,7 @@ keyctl20 keyctl20
keyctl21 keyctl21
keyctl22 keyctl22
keyctl23 keyctl23
+keyctl24 keyctl24
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 803e4e94c3..767ccf61ac 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -21,3 +21,4 @@
/keyctl21
/keyctl22
/keyctl23
+/keyctl24
diff --git a/testcases/kernel/syscalls/keyctl/keyctl24.c b/testcases/kernel/syscalls/keyctl/keyctl24.c
new file mode 100644
index 0000000000..541f697f52
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl24.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Negative test cases for ``KEYCTL_RESTRICT_KEYRING`` of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - restrict with ``NULL`` type and non-NULL restriction fails with ``EINVAL``
+ * - restrict with non-NULL type and ``NULL`` restriction fails with ``EINVAL``
+ * - restrict on a non-keyring key fails with ``ENOTDIR``
+ * - restrict with unknown key type fails with ``ENOKEY``
+ * - restrict with key type having no restriction lookup fails with ``ENOENT``
+ * - restrict with asymmetric type and invalid restriction string fails with
+ * ``EINVAL``
+ * - restrict with asymmetric type and bogus key serial fails with ``ENOKEY``
+ * - restrict an already restricted keyring fails with ``EEXIST``
+ * - restrict with self-referencing key_or_keyring chain fails with ``EDEADLK``
+ * - restrict without Setattr permission fails with ``EACCES``
+ */
+
+#include <stdio.h>
+
+#include "keyctl_common.h"
+
+static key_serial_t ring_reject, ring_no_setattr;
+static key_serial_t user_key;
+static int asym_supported;
+
+/*
+ * A tcase with .id = NULL asks verify_negative() to allocate a fresh
+ * unrestricted keyring for the case and unlink it afterwards, so that a
+ * false-positive result cannot restrict a ring shared with later cases.
+ * .self_cycle asks for a "key_or_keyring:<fresh>:chain" restriction string
+ * pointing back at that fresh ring, needed for the EDEADLK check.
+ */
+static struct tcase {
+ key_serial_t *id;
+ int self_cycle;
+ const char *type;
+ const char *restriction;
+ int exp_errno;
+ int needs_asym;
+ const char *desc;
+} tcases[] = {
+ {
+ .restriction = "builtin_trusted",
+ .exp_errno = EINVAL,
+ .desc = "NULL type and non-NULL restriction",
+ },
+ {
+ .type = "asymmetric",
+ .exp_errno = EINVAL,
+ .desc = "non-NULL type and NULL restriction",
+ },
+ {
+ .id = &user_key,
+ .exp_errno = ENOTDIR,
+ .desc = "non-keyring key",
+ },
+ {
+ .type = "nosuchtype",
+ .restriction = "builtin_trusted",
+ .exp_errno = ENOKEY,
+ .desc = "unknown key type",
+ },
+ {
+ .type = "user",
+ .restriction = "builtin_trusted",
+ .exp_errno = ENOENT,
+ .desc = "key type having no lookup_restriction",
+ },
+ {
+ .type = "asymmetric",
+ .restriction = "bogus",
+ .exp_errno = EINVAL,
+ .needs_asym = 1,
+ .desc = "asymmetric with invalid restriction string",
+ },
+ {
+ .type = "asymmetric",
+ .restriction = "key_or_keyring:2147483647",
+ .exp_errno = ENOKEY,
+ .needs_asym = 1,
+ .desc = "asymmetric with bogus key serial",
+ },
+ {
+ .id = &ring_reject,
+ .exp_errno = EEXIST,
+ .desc = "already restricted keyring",
+ },
+ {
+ .self_cycle = 1,
+ .type = "asymmetric",
+ .exp_errno = EDEADLK,
+ .needs_asym = 1,
+ .desc = "self-referencing key_or_keyring chain",
+ },
+ {
+ .id = &ring_no_setattr,
+ .exp_errno = EACCES,
+ .desc = "keyring without Setattr permission",
+ },
+};
+
+static void setup(void)
+{
+ key_serial_t probe_ring;
+
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ ring_reject = SAFE_NEW_RING("ltpkeyctl24_reject");
+ ring_no_setattr = SAFE_NEW_RING("ltpkeyctl24_no_setattr");
+ SAFE_KEYCTL(KEYCTL_SETPERM, ring_no_setattr, KEY_PERM_NO_SETATTR, 0, 0);
+
+ /* Permanently restrict ring_reject with reject-all for EEXIST test */
+ SAFE_KEYCTL(KEYCTL_RESTRICT_KEYRING, ring_reject, 0, 0, 0);
+
+ user_key = SAFE_NEW_USER_KEY("k", "payload", 7, KEY_SPEC_PROCESS_KEYRING);
+
+ /* Probe asymmetric support on a throwaway ring so we cannot poison
+ * any ring reused later by the tcase table.
+ */
+ probe_ring = SAFE_NEW_RING("ltpkeyctl24_probe");
+ asym_supported = is_asym_supported(probe_ring);
+ keyctl(KEYCTL_UNLINK, probe_ring, KEY_SPEC_PROCESS_KEYRING, 0, 0);
+}
+
+static void verify_negative(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+ key_serial_t id, fresh_ring = 0;
+ const char *restriction = tc->restriction;
+ char cycle_buf[64];
+
+ if (tc->needs_asym && !asym_supported) {
+ tst_res(TCONF, "asymmetric key type not supported");
+ return;
+ }
+
+ if (tc->id) {
+ id = *tc->id;
+ } else {
+ fresh_ring = SAFE_NEW_RING("ltpkeyctl24_fresh");
+ id = fresh_ring;
+ if (tc->self_cycle) {
+ snprintf(cycle_buf, sizeof(cycle_buf),
+ "key_or_keyring:%d:chain", fresh_ring);
+ restriction = cycle_buf;
+ }
+ }
+
+ TST_EXP_FAIL(keyctl(KEYCTL_RESTRICT_KEYRING, (unsigned long)id,
+ (unsigned long)tc->type,
+ (unsigned long)restriction, 0),
+ tc->exp_errno,
+ "KEYCTL_RESTRICT_KEYRING with %s", tc->desc);
+
+ if (fresh_ring)
+ keyctl(KEYCTL_UNLINK, fresh_ring, KEY_SPEC_PROCESS_KEYRING,
+ 0, 0);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test = verify_negative,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "4.12",
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 20/36] keyctl25: Test KEYCTL_DH_COMPUTE shared secret computation
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (18 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 19/36] keyctl24: Negative tests for KEYCTL_RESTRICT_KEYRING Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 12:14 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 21/36] keyctl26: Test KEYCTL_DH_COMPUTE size query Petr Vorel
` (16 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_DH_COMPUTE shared secret computation: verify that
computing a 256-byte DH shared secret with RFC 7919 FFDHE-2048
parameters matches the precomputed mathematical value.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl25.c | 66 +++++++++++++++++
.../kernel/syscalls/keyctl/keyctl_dh_data.h | 74 +++++++++++++++++++
4 files changed, 142 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl25.c
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl_dh_data.h
diff --git a/runtest/syscalls b/runtest/syscalls
index 6ee6ec56a8..dfe01c8e0e 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -742,6 +742,7 @@ keyctl21 keyctl21
keyctl22 keyctl22
keyctl23 keyctl23
keyctl24 keyctl24
+keyctl25 keyctl25
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 767ccf61ac..4cf7725587 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -22,3 +22,4 @@
/keyctl22
/keyctl23
/keyctl24
+/keyctl25
diff --git a/testcases/kernel/syscalls/keyctl/keyctl25.c b/testcases/kernel/syscalls/keyctl/keyctl25.c
new file mode 100644
index 0000000000..59b9bf9c1d
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl25.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_DH_COMPUTE`` shared secret computation of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - compute DH shared secret using RFC 7919 FFDHE-2048 parameters and
+ * verify the 256-byte result matches the expected secret
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_dh_data.h"
+
+static struct keyctl_dh_params *dh_params;
+static unsigned char out_buf[256];
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ dh_params->priv = SAFE_NEW_USER_KEY("dh_priv", dh_priv, sizeof(dh_priv),
+ KEY_SPEC_PROCESS_KEYRING);
+ dh_params->prime = SAFE_NEW_USER_KEY("dh_prime", dh_prime, sizeof(dh_prime),
+ KEY_SPEC_PROCESS_KEYRING);
+ dh_params->base = SAFE_NEW_USER_KEY("dh_base", dh_base, sizeof(dh_base),
+ KEY_SPEC_PROCESS_KEYRING);
+}
+
+static void run(void)
+{
+ memset(out_buf, 0, sizeof(out_buf));
+
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_DH_COMPUTE, (unsigned long)dh_params,
+ (unsigned long)out_buf,
+ sizeof(dh_expected_secret), 0),
+ (long)sizeof(dh_expected_secret));
+ if (!TST_PASS)
+ return;
+
+ if (memcmp(out_buf, dh_expected_secret, sizeof(dh_expected_secret))) {
+ tst_res(TFAIL, "computed secret does not match expected value");
+ return;
+ }
+
+ tst_res(TPASS, "KEYCTL_DH_COMPUTE computed expected shared secret");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.7",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_KEY_DH_OPERATIONS=y",
+ "CONFIG_CRYPTO_DH",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&dh_params, .size = sizeof(*dh_params)},
+ {},
+ },
+};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl_dh_data.h b/testcases/kernel/syscalls/keyctl/keyctl_dh_data.h
new file mode 100644
index 0000000000..bc1432dc30
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl_dh_data.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ *
+ * Static test vectors for KEYCTL_DH_COMPUTE tests (keyctl25..keyctl28).
+ */
+
+#ifndef KEYCTL_DH_DATA_H__
+#define KEYCTL_DH_DATA_H__
+
+/* RFC 7919 2048-bit FFDHE Group parameters (ffdhe2048) */
+static const unsigned char dh_prime[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34,
+ 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74,
+ 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd,
+ 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37,
+ 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
+ 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed,
+ 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6,
+ 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d, 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05,
+ 0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f,
+ 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, 0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb,
+ 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d, 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04,
+ 0xf1, 0x74, 0x6c, 0x08, 0xca, 0x18, 0x21, 0x7c, 0x32, 0x90, 0x5e, 0x46, 0x2e, 0x36, 0xce, 0x3b,
+ 0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03, 0x9b, 0x27, 0x83, 0xa2, 0xec, 0x07, 0xa2, 0x8f,
+ 0xb5, 0xc5, 0x5d, 0xf0, 0x6f, 0x4c, 0x52, 0xc9, 0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7c, 0xea, 0x95, 0x6a, 0xe5, 0x15, 0xd2, 0x26, 0x18, 0x98, 0xfa, 0x05, 0x10,
+ 0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xac, 0xaa, 0x68, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+static const unsigned char dh_priv[] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+};
+
+static const unsigned char dh_base[] = {
+ 0xdd, 0x5d, 0x87, 0xa6, 0xf9, 0xdf, 0x57, 0xf1, 0x3d, 0xf2, 0xc6, 0x58, 0xe5, 0x01, 0xab, 0xd7,
+ 0x2a, 0xdb, 0xa3, 0x48, 0x63, 0x61, 0x3b, 0xd1, 0x67, 0x69, 0xee, 0xf9, 0x55, 0x25, 0x8e, 0x36,
+ 0x11, 0xee, 0x8e, 0xc5, 0x42, 0xa4, 0x26, 0xe3, 0x75, 0xc6, 0xb4, 0xd8, 0x3b, 0x71, 0x7c, 0x97,
+ 0xf8, 0x85, 0x04, 0xb4, 0x3a, 0xcc, 0x5d, 0xf0, 0x3a, 0x49, 0x04, 0xe8, 0x8d, 0x26, 0x19, 0xdf,
+ 0xb7, 0xfb, 0x3c, 0xda, 0x68, 0xbc, 0x13, 0x6c, 0x46, 0x8d, 0xfe, 0xdf, 0x1c, 0x5a, 0x5b, 0x73,
+ 0x04, 0x64, 0x08, 0x86, 0x6f, 0xec, 0x89, 0x49, 0xbe, 0xb5, 0x87, 0xa0, 0xa4, 0xb6, 0xe6, 0xc0,
+ 0xde, 0xf5, 0xf2, 0x44, 0x05, 0x38, 0x51, 0x84, 0xa6, 0x9e, 0x9d, 0xce, 0x42, 0x08, 0xf3, 0x63,
+ 0xad, 0xb0, 0xe1, 0xce, 0x88, 0x18, 0x63, 0xeb, 0x8d, 0x82, 0xd4, 0xae, 0xad, 0x5e, 0x1c, 0x19,
+ 0x50, 0x47, 0xd7, 0x0d, 0x9b, 0xdc, 0x44, 0x7b, 0xda, 0x02, 0x76, 0x84, 0xb4, 0x35, 0x1d, 0x98,
+ 0x50, 0x3f, 0xee, 0x1b, 0xcf, 0x82, 0x7f, 0xfd, 0x07, 0x50, 0x17, 0x01, 0xc7, 0xf3, 0x91, 0x24,
+ 0x22, 0xdd, 0x2f, 0x42, 0xb2, 0x6c, 0xf4, 0x0a, 0xdd, 0xe0, 0x7d, 0x63, 0xe2, 0x35, 0xf4, 0x2f,
+ 0x65, 0x21, 0x40, 0x2a, 0x90, 0xdd, 0x2c, 0xea, 0x4a, 0x2e, 0x17, 0x76, 0x40, 0x74, 0x2d, 0x3c,
+ 0xac, 0x85, 0x3e, 0x96, 0xfa, 0x49, 0x44, 0x13, 0xfe, 0xe9, 0x45, 0x97, 0x2b, 0x24, 0x23, 0xa0,
+ 0xf5, 0x1b, 0xec, 0xf2, 0x85, 0x28, 0xc9, 0xdb, 0x92, 0x60, 0x02, 0xc5, 0x0f, 0xfe, 0x2b, 0x1a,
+ 0x97, 0xc9, 0x78, 0xcf, 0x48, 0x8b, 0xa2, 0x9b, 0xbb, 0x47, 0x2e, 0x7e, 0x63, 0x28, 0x2d, 0xdd,
+ 0x32, 0x0a, 0x15, 0xa0, 0x72, 0xd8, 0x17, 0x60, 0x75, 0x20, 0x4f, 0x7d, 0xed, 0x29, 0x35, 0x61,
+};
+
+static const unsigned char dh_expected_secret[] = {
+ 0x61, 0xfc, 0x0d, 0x4d, 0x01, 0xce, 0xe1, 0x52, 0x34, 0x0f, 0x52, 0xb4, 0x53, 0x28, 0xaa, 0x11,
+ 0xd8, 0x6e, 0x92, 0xce, 0x8e, 0x8f, 0x7b, 0xa2, 0x91, 0x80, 0xf6, 0x2d, 0x99, 0x9b, 0xc7, 0x71,
+ 0x4c, 0xbb, 0x05, 0xef, 0xde, 0x22, 0xbd, 0xdf, 0x6f, 0x8d, 0xbb, 0x00, 0xdf, 0x4e, 0xfa, 0x1c,
+ 0x14, 0xea, 0x54, 0x20, 0xac, 0xec, 0x51, 0xcd, 0xbd, 0xd0, 0x63, 0xfc, 0x35, 0x7b, 0xd9, 0xab,
+ 0x36, 0x7f, 0x1b, 0x67, 0xc3, 0xb1, 0x51, 0x4e, 0x2d, 0x19, 0x05, 0x50, 0xbe, 0x1d, 0x44, 0x51,
+ 0x5f, 0xfe, 0x65, 0xf8, 0xf6, 0x12, 0xad, 0x6c, 0xc5, 0x84, 0x96, 0xd9, 0xc3, 0xc9, 0x39, 0x7d,
+ 0x87, 0x98, 0xa7, 0x8e, 0x52, 0x4d, 0x1f, 0x26, 0xbe, 0x62, 0x14, 0xf4, 0x66, 0xcf, 0x9a, 0x90,
+ 0x4d, 0x28, 0xdd, 0x29, 0x11, 0x6e, 0x51, 0x0c, 0x7b, 0x18, 0x1e, 0xac, 0x55, 0x49, 0xce, 0x1d,
+ 0xef, 0xcc, 0x6c, 0xa2, 0x0e, 0x80, 0xd3, 0x0d, 0x24, 0xc0, 0x77, 0x68, 0x87, 0xf8, 0xa3, 0x05,
+ 0x0f, 0x8d, 0xaa, 0x58, 0x6b, 0xbb, 0x6b, 0xd0, 0x76, 0xea, 0x87, 0x5c, 0xc3, 0x3e, 0xef, 0x19,
+ 0x66, 0x9e, 0xc7, 0xd4, 0x4e, 0x85, 0xdf, 0x06, 0x61, 0x0b, 0x94, 0x9c, 0xd3, 0x58, 0x23, 0xa7,
+ 0xb1, 0xf6, 0x36, 0xaf, 0x6b, 0x4c, 0xf1, 0x88, 0x40, 0xd4, 0x5f, 0x6e, 0x9d, 0x1f, 0xa7, 0x3c,
+ 0x8b, 0xc2, 0x71, 0xba, 0x87, 0xcd, 0xc2, 0x9b, 0x33, 0xcf, 0x18, 0xee, 0x59, 0x8e, 0xf6, 0x6c,
+ 0x76, 0xcc, 0xed, 0xcc, 0x09, 0xfe, 0xe1, 0xf8, 0xce, 0x5c, 0x78, 0xb3, 0xb9, 0xe3, 0xf5, 0x29,
+ 0x14, 0xaa, 0x67, 0xd0, 0xb5, 0xcb, 0x7a, 0x7e, 0xd1, 0x2e, 0x83, 0x97, 0xf1, 0x6b, 0xfb, 0xe4,
+ 0xfb, 0xeb, 0xdd, 0x18, 0x54, 0x0d, 0x4c, 0xa7, 0x65, 0xc1, 0x0c, 0x11, 0xad, 0xea, 0x83, 0x9f,
+};
+
+#endif /* KEYCTL_DH_DATA_H__ */
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 21/36] keyctl26: Test KEYCTL_DH_COMPUTE size query
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (19 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 20/36] keyctl25: Test KEYCTL_DH_COMPUTE shared secret computation Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 12:16 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 22/36] keyctl27: Test KEYCTL_DH_COMPUTE KDF key derivation Petr Vorel
` (15 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_DH_COMPUTE buffer size query: verify that calling
with buflen 0 returns the required output buffer size (256)
without writing to userspace.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl26.c | 53 +++++++++++++++++++++
3 files changed, 55 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl26.c
diff --git a/runtest/syscalls b/runtest/syscalls
index dfe01c8e0e..7485996ec0 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -743,6 +743,7 @@ keyctl22 keyctl22
keyctl23 keyctl23
keyctl24 keyctl24
keyctl25 keyctl25
+keyctl26 keyctl26
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 4cf7725587..dd282b7ced 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -23,3 +23,4 @@
/keyctl23
/keyctl24
/keyctl25
+/keyctl26
diff --git a/testcases/kernel/syscalls/keyctl/keyctl26.c b/testcases/kernel/syscalls/keyctl/keyctl26.c
new file mode 100644
index 0000000000..bdd852fb4c
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl26.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_DH_COMPUTE`` size query of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - verify calling ``KEYCTL_DH_COMPUTE`` with ``buflen = 0`` returns required
+ * buffer size (256) without writing
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_dh_data.h"
+
+static struct keyctl_dh_params *dh_params;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ dh_params->priv = SAFE_NEW_USER_KEY("dh_priv", dh_priv, sizeof(dh_priv),
+ KEY_SPEC_PROCESS_KEYRING);
+ dh_params->prime = SAFE_NEW_USER_KEY("dh_prime", dh_prime, sizeof(dh_prime),
+ KEY_SPEC_PROCESS_KEYRING);
+ dh_params->base = SAFE_NEW_USER_KEY("dh_base", dh_base, sizeof(dh_base),
+ KEY_SPEC_PROCESS_KEYRING);
+}
+
+static void run(void)
+{
+ TST_EXP_VAL(keyctl(KEYCTL_DH_COMPUTE, (unsigned long)dh_params,
+ (unsigned long)NULL, 0, 0),
+ (long)sizeof(dh_expected_secret));
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.7",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_KEY_DH_OPERATIONS=y",
+ "CONFIG_CRYPTO_DH",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&dh_params, .size = sizeof(*dh_params)},
+ {},
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 22/36] keyctl27: Test KEYCTL_DH_COMPUTE KDF key derivation
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (20 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 21/36] keyctl26: Test KEYCTL_DH_COMPUTE size query Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-16 14:03 ` [LTP] [PATCH v3 23/36] keyctl28: Negative and boundary tests for KEYCTL_DH_COMPUTE Petr Vorel
` (14 subsequent siblings)
36 siblings, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_DH_COMPUTE SP800-56A KDF key derivation: verify that
deriving a key using SHA-256 and otherinfo matches the precomputed
mathematical test vector.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl27.c | 78 +++++++++++++++++++
.../kernel/syscalls/keyctl/keyctl_dh_data.h | 5 ++
4 files changed, 85 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl27.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 7485996ec0..a90138137f 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -744,6 +744,7 @@ keyctl23 keyctl23
keyctl24 keyctl24
keyctl25 keyctl25
keyctl26 keyctl26
+keyctl27 keyctl27
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index dd282b7ced..720ba1de65 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -24,3 +24,4 @@
/keyctl24
/keyctl25
/keyctl26
+/keyctl27
diff --git a/testcases/kernel/syscalls/keyctl/keyctl27.c b/testcases/kernel/syscalls/keyctl/keyctl27.c
new file mode 100644
index 0000000000..bf697b1fab
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl27.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_DH_COMPUTE`` KDF key derivation of :manpage:`keyctl(2)`.
+ *
+ * The KDF extension to ``KEYCTL_DH_COMPUTE`` (SP800-56A) landed in Linux 4.12.
+ *
+ * [Algorithm]
+ *
+ * - derive key with SP800-56A KDF (SHA-256 + otherinfo), verify derived
+ * key matches expected 32-byte value
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_dh_data.h"
+
+#define KDF_OTHERINFO "LTP-KDF-TEST-INFO"
+
+static struct keyctl_dh_params *dh_params;
+static struct keyctl_kdf_params *kdf_params;
+static unsigned char out_buf[32];
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ dh_params->priv = SAFE_NEW_USER_KEY("dh_priv", dh_priv, sizeof(dh_priv),
+ KEY_SPEC_PROCESS_KEYRING);
+ dh_params->prime = SAFE_NEW_USER_KEY("dh_prime", dh_prime, sizeof(dh_prime),
+ KEY_SPEC_PROCESS_KEYRING);
+ dh_params->base = SAFE_NEW_USER_KEY("dh_base", dh_base, sizeof(dh_base),
+ KEY_SPEC_PROCESS_KEYRING);
+}
+
+static void run(void)
+{
+ memset(kdf_params, 0, sizeof(*kdf_params));
+ kdf_params->hashname = "sha256";
+ kdf_params->otherinfo = (char *)KDF_OTHERINFO;
+ kdf_params->otherinfolen = strlen(KDF_OTHERINFO);
+
+ memset(out_buf, 0, sizeof(out_buf));
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_DH_COMPUTE, (unsigned long)dh_params,
+ (unsigned long)out_buf,
+ sizeof(dh_kdf_expected),
+ (unsigned long)kdf_params),
+ (long)sizeof(dh_kdf_expected));
+ if (!TST_PASS)
+ return;
+
+ if (memcmp(out_buf, dh_kdf_expected, sizeof(dh_kdf_expected))) {
+ tst_res(TFAIL, "derived KDF key does not match expected value");
+ return;
+ }
+
+ tst_res(TPASS, "KEYCTL_DH_COMPUTE with KDF derived expected key");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.12",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_KEY_DH_OPERATIONS=y",
+ "CONFIG_CRYPTO_DH",
+ "CONFIG_CRYPTO_SHA256",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&dh_params, .size = sizeof(*dh_params)},
+ {&kdf_params, .size = sizeof(*kdf_params)},
+ {},
+ },
+};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl_dh_data.h b/testcases/kernel/syscalls/keyctl/keyctl_dh_data.h
index bc1432dc30..7ac7876a06 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl_dh_data.h
+++ b/testcases/kernel/syscalls/keyctl/keyctl_dh_data.h
@@ -71,4 +71,9 @@ static const unsigned char dh_expected_secret[] = {
0xfb, 0xeb, 0xdd, 0x18, 0x54, 0x0d, 0x4c, 0xa7, 0x65, 0xc1, 0x0c, 0x11, 0xad, 0xea, 0x83, 0x9f,
};
+static const unsigned char dh_kdf_expected[] = {
+ 0x66, 0x39, 0xec, 0x41, 0x31, 0x33, 0xe6, 0xc0, 0x61, 0x67, 0x28, 0x51, 0x61, 0xf7, 0x8c, 0xd7,
+ 0xc0, 0x55, 0xc9, 0xcc, 0x83, 0x46, 0xf3, 0xaa, 0x62, 0xed, 0xca, 0x90, 0x99, 0x2d, 0xc4, 0x07,
+};
+
#endif /* KEYCTL_DH_DATA_H__ */
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 23/36] keyctl28: Negative and boundary tests for KEYCTL_DH_COMPUTE
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (21 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 22/36] keyctl27: Test KEYCTL_DH_COMPUTE KDF key derivation Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-16 14:03 ` [LTP] [PATCH v3 24/36] lapi/keyctl.h: Add fallback definitions for public key ops Petr Vorel
` (13 subsequent siblings)
36 siblings, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test error and boundary conditions of KEYCTL_DH_COMPUTE using a
parameterized tcase table: buffer smaller than secret (EOVERFLOW),
bogus prime key (ENOKEY), non-user key (EOPNOTSUPP), NULL buffer
(EINVAL), non-zero __spare (EINVAL), buflen > 1024 (EMSGSIZE),
otherinfolen > 64 (EMSGSIZE), and unknown KDF hash name (ENOENT).
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl28.c | 140 ++++++++++++++++++++
3 files changed, 142 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl28.c
diff --git a/runtest/syscalls b/runtest/syscalls
index a90138137f..6594dccb2d 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -745,6 +745,7 @@ keyctl24 keyctl24
keyctl25 keyctl25
keyctl26 keyctl26
keyctl27 keyctl27
+keyctl28 keyctl28
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 720ba1de65..139e480b39 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -25,3 +25,4 @@
/keyctl25
/keyctl26
/keyctl27
+/keyctl28
diff --git a/testcases/kernel/syscalls/keyctl/keyctl28.c b/testcases/kernel/syscalls/keyctl/keyctl28.c
new file mode 100644
index 0000000000..4c7f6be17e
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl28.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Negative and boundary test cases for ``KEYCTL_DH_COMPUTE`` of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - verify ``EOVERFLOW`` when buffer is smaller than secret size (255 < 256)
+ * - verify ``ENOKEY`` when prime key id does not exist
+ * - verify ``EOPNOTSUPP`` when prime key is not of "user" type
+ * - verify ``EINVAL`` when buffer is ``NULL`` with non-zero buflen
+ * - verify ``EINVAL`` when KDF ``__spare`` field contains non-zero data
+ * - verify ``EMSGSIZE`` when KDF requested output length exceeds 1024
+ * - verify ``EMSGSIZE`` when KDF otherinfo length exceeds 64
+ * - verify ``ENOENT`` when KDF hash algorithm name is unknown
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_dh_data.h"
+
+static struct keyctl_dh_params *dh_params;
+static struct keyctl_dh_params *dh_bogus_prime;
+static struct keyctl_dh_params *dh_nonuser_prime;
+
+static struct keyctl_kdf_params *kdf_valid;
+static struct keyctl_kdf_params *kdf_spare_nonzero;
+static struct keyctl_kdf_params *kdf_oi_toolarge;
+static struct keyctl_kdf_params *kdf_unknown_hash;
+
+static unsigned char out_buf[1025];
+
+static struct tcase {
+ struct keyctl_dh_params **params;
+ void *buffer;
+ size_t buflen;
+ struct keyctl_kdf_params **kdf;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ { &dh_params, out_buf, 255, NULL,
+ EOVERFLOW, "buffer smaller than secret size (255 < 256)" },
+
+ { &dh_bogus_prime, out_buf, 256, NULL,
+ ENOKEY, "bogus prime key ID" },
+
+ { &dh_nonuser_prime, out_buf, 256, NULL,
+ EOPNOTSUPP, "non-user key as prime parameter" },
+
+ { &dh_params, NULL, 256, NULL,
+ EINVAL, "NULL buffer with non-zero buflen" },
+
+ { &dh_params, out_buf, 32, &kdf_spare_nonzero,
+ EINVAL, "KDF non-zero __spare field" },
+
+ { &dh_params, out_buf, 1025, &kdf_valid,
+ EMSGSIZE, "KDF output length > 1024" },
+
+ { &dh_params, out_buf, 32, &kdf_oi_toolarge,
+ EMSGSIZE, "KDF otherinfolen > 64" },
+
+ { &dh_params, out_buf, 32, &kdf_unknown_hash,
+ ENOENT, "unknown KDF hash algorithm name" },
+};
+
+static void setup(void)
+{
+ key_serial_t key_priv, key_prime, key_base;
+
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key_priv = SAFE_NEW_USER_KEY("dh_priv", dh_priv, sizeof(dh_priv),
+ KEY_SPEC_PROCESS_KEYRING);
+ key_prime = SAFE_NEW_USER_KEY("dh_prime", dh_prime, sizeof(dh_prime),
+ KEY_SPEC_PROCESS_KEYRING);
+ key_base = SAFE_NEW_USER_KEY("dh_base", dh_base, sizeof(dh_base),
+ KEY_SPEC_PROCESS_KEYRING);
+
+ dh_params->priv = key_priv;
+ dh_params->prime = key_prime;
+ dh_params->base = key_base;
+
+ *dh_bogus_prime = *dh_params;
+ dh_bogus_prime->prime = INT32_MAX;
+
+ *dh_nonuser_prime = *dh_params;
+ dh_nonuser_prime->prime = KEY_SPEC_PROCESS_KEYRING;
+
+ kdf_valid->hashname = "sha256";
+ kdf_valid->otherinfo = "info";
+ kdf_valid->otherinfolen = 4;
+
+ *kdf_spare_nonzero = *kdf_valid;
+ kdf_spare_nonzero->__spare[0] = 1;
+
+ *kdf_oi_toolarge = *kdf_valid;
+ kdf_oi_toolarge->otherinfolen = 65;
+
+ *kdf_unknown_hash = *kdf_valid;
+ kdf_unknown_hash->hashname = "sha9000";
+}
+
+static void verify_negative(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+ struct keyctl_dh_params *p = *tc->params;
+ struct keyctl_kdf_params *kdf = tc->kdf ? *tc->kdf : NULL;
+
+ TST_EXP_FAIL2(keyctl(KEYCTL_DH_COMPUTE, (unsigned long)p,
+ (unsigned long)tc->buffer, tc->buflen,
+ (unsigned long)kdf),
+ tc->exp_errno,
+ "KEYCTL_DH_COMPUTE with %s", tc->desc);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test = verify_negative,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "4.12",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_KEY_DH_OPERATIONS=y",
+ "CONFIG_CRYPTO_DH",
+ "CONFIG_CRYPTO_SHA256",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&dh_params, .size = sizeof(*dh_params)},
+ {&dh_bogus_prime, .size = sizeof(*dh_bogus_prime)},
+ {&dh_nonuser_prime, .size = sizeof(*dh_nonuser_prime)},
+ {&kdf_valid, .size = sizeof(*kdf_valid)},
+ {&kdf_spare_nonzero, .size = sizeof(*kdf_spare_nonzero)},
+ {&kdf_oi_toolarge, .size = sizeof(*kdf_oi_toolarge)},
+ {&kdf_unknown_hash, .size = sizeof(*kdf_unknown_hash)},
+ {},
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 24/36] lapi/keyctl.h: Add fallback definitions for public key ops
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (22 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 23/36] keyctl28: Negative and boundary tests for KEYCTL_DH_COMPUTE Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 12:31 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 25/36] keyctl29: Test KEYCTL_PKEY_QUERY on public key Petr Vorel
` (12 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add fallback definitions for KEYCTL_PKEY_QUERY, KEYCTL_PKEY_ENCRYPT,
KEYCTL_PKEY_DECRYPT, KEYCTL_PKEY_SIGN, KEYCTL_PKEY_VERIFY, and
KEYCTL_SUPPORTS_*, as well as fallback structs keyctl_pkey_query
and keyctl_pkey_params when built without linux/keyctl.h.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
include/lapi/keyctl.h | 56 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/include/lapi/keyctl.h b/include/lapi/keyctl.h
index 4ba797bf9c..fdb68d1725 100644
--- a/include/lapi/keyctl.h
+++ b/include/lapi/keyctl.h
@@ -78,6 +78,30 @@ struct keyctl_kdf_params {
};
#endif
+#ifndef HAVE_STRUCT_KEYCTL_PKEY_QUERY
+struct keyctl_pkey_query {
+ uint32_t supported_ops;
+ uint32_t key_size;
+ uint16_t max_data_size;
+ uint16_t max_sig_size;
+ uint16_t max_enc_size;
+ uint16_t max_dec_size;
+ uint32_t __spare[10];
+};
+#endif
+
+#ifndef HAVE_STRUCT_KEYCTL_PKEY_PARAMS
+struct keyctl_pkey_params {
+ int32_t key_id;
+ uint32_t in_len;
+ union {
+ uint32_t out_len;
+ uint32_t in2_len;
+ };
+ uint32_t __spare[7];
+};
+#endif
+
/* special process keyring shortcut IDs */
#ifndef KEY_SPEC_THREAD_KEYRING
# define KEY_SPEC_THREAD_KEYRING -1
@@ -202,6 +226,33 @@ struct keyctl_kdf_params {
# define KEYCTL_MOVE_EXCL 0x00000001 /* do not displace from the to-keyring */
#endif
+#ifndef KEYCTL_PKEY_QUERY
+# define KEYCTL_PKEY_QUERY 24
+#endif
+
+#ifndef KEYCTL_PKEY_ENCRYPT
+# define KEYCTL_PKEY_ENCRYPT 25
+#endif
+
+#ifndef KEYCTL_PKEY_DECRYPT
+# define KEYCTL_PKEY_DECRYPT 26
+#endif
+
+#ifndef KEYCTL_PKEY_SIGN
+# define KEYCTL_PKEY_SIGN 27
+#endif
+
+#ifndef KEYCTL_PKEY_VERIFY
+# define KEYCTL_PKEY_VERIFY 28
+#endif
+
+#ifndef KEYCTL_SUPPORTS_ENCRYPT
+# define KEYCTL_SUPPORTS_ENCRYPT 0x01
+# define KEYCTL_SUPPORTS_DECRYPT 0x02
+# define KEYCTL_SUPPORTS_SIGN 0x04
+# define KEYCTL_SUPPORTS_VERIFY 0x08
+#endif
+
/* key permissions */
#ifndef KEY_POS_VIEW
# define KEY_POS_VIEW 0x01000000
@@ -262,6 +313,11 @@ static inline long safe_keyctl(const char *file, const int lineno,
case KEYCTL_GET_SECURITY:
case KEYCTL_GET_PERSISTENT:
case KEYCTL_DH_COMPUTE:
+ case KEYCTL_PKEY_QUERY:
+ case KEYCTL_PKEY_ENCRYPT:
+ case KEYCTL_PKEY_DECRYPT:
+ case KEYCTL_PKEY_SIGN:
+ case KEYCTL_PKEY_VERIFY:
if (rval < 0)
failure = 1;
break;
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 25/36] keyctl29: Test KEYCTL_PKEY_QUERY on public key
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (23 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 24/36] lapi/keyctl.h: Add fallback definitions for public key ops Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 14:42 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 26/36] keyctl30: Test KEYCTL_PKEY_QUERY on private key Petr Vorel
` (11 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_PKEY_QUERY operation on an RSA-2048 X.509 public key
certificate: verify key_size is 2048, supported_ops contains
ENCRYPT and VERIFY, and max_enc_size/max_sig_size are 256.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl29.c | 90 +++++++++++++++++++
.../kernel/syscalls/keyctl/keyctl_common.h | 20 +++++
.../kernel/syscalls/keyctl/keyctl_pkey_data.h | 68 ++++++++++++++
5 files changed, 180 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl29.c
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl_pkey_data.h
diff --git a/runtest/syscalls b/runtest/syscalls
index 6594dccb2d..c41321b407 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -746,6 +746,7 @@ keyctl25 keyctl25
keyctl26 keyctl26
keyctl27 keyctl27
keyctl28 keyctl28
+keyctl29 keyctl29
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 139e480b39..91310b0018 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -26,3 +26,4 @@
/keyctl26
/keyctl27
/keyctl28
+/keyctl29
diff --git a/testcases/kernel/syscalls/keyctl/keyctl29.c b/testcases/kernel/syscalls/keyctl/keyctl29.c
new file mode 100644
index 0000000000..8fee5fb082
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl29.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_PKEY_QUERY`` on public key of :manpage:`keyctl(2)`.
+ *
+ * ``KEYCTL_PKEY_QUERY`` queries the parameters, operations, and buffer
+ * size limits of an asymmetric public or private key.
+ *
+ * Requires root (CAP_SYS_MODULE) to load the ``x509_key_parser`` module.
+ *
+ * [Algorithm]
+ *
+ * - query an RSA-2048 X.509 public key certificate
+ * - verify ``key_size`` is 2048 bits
+ * - verify ``supported_ops`` contains ``KEYCTL_SUPPORTS_ENCRYPT`` and
+ * ``KEYCTL_SUPPORTS_VERIFY``
+ * - verify ``max_enc_size`` is 256 bytes
+ * - verify ``max_sig_size`` is 256 bytes
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_pkey_data.h"
+#include "tst_module.h"
+
+static key_serial_t cert_key;
+static struct keyctl_pkey_query *query_buf;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ tst_modprobe("x509_key_parser", NULL);
+
+ cert_key = add_asymmetric_key_or_tconf("cert", rsa2048_cert,
+ sizeof(rsa2048_cert),
+ "CONFIG_X509_CERTIFICATE_PARSER");
+}
+
+static void run(void)
+{
+ memset(query_buf, 0, sizeof(*query_buf));
+
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_PKEY_QUERY, (unsigned long)cert_key,
+ 0, (unsigned long)"enc=pkcs1",
+ (unsigned long)query_buf), 0);
+ if (!TST_PASS)
+ return;
+
+ TST_EXP_EQ_LU_SILENT(query_buf->key_size, 2048);
+ if (!TST_PASS)
+ return;
+
+ TST_EXP_EXPR(query_buf->supported_ops & KEYCTL_SUPPORTS_ENCRYPT,
+ "KEYCTL_PKEY_QUERY supports ENCRYPT");
+
+ TST_EXP_EXPR(query_buf->supported_ops & KEYCTL_SUPPORTS_VERIFY,
+ "KEYCTL_PKEY_QUERY supports VERIFY");
+
+ TST_EXP_EQ_LU_SILENT(query_buf->max_enc_size, 256);
+ if (!TST_PASS)
+ return;
+
+ TST_EXP_EQ_LU_SILENT(query_buf->max_sig_size, 256);
+ if (!TST_PASS)
+ return;
+
+ tst_res(TPASS, "KEYCTL_PKEY_QUERY on X.509 cert returned valid parameters");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.20",
+ .needs_root = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_ASYMMETRIC_KEY_TYPE=y",
+ "CONFIG_X509_CERTIFICATE_PARSER",
+ "CONFIG_CRYPTO_RSA",
+ "CONFIG_CRYPTO_SHA256",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&query_buf, .size = sizeof(*query_buf)},
+ {},
+ },
+};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl_common.h b/testcases/kernel/syscalls/keyctl/keyctl_common.h
index 1465824334..95e3d173a1 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl_common.h
+++ b/testcases/kernel/syscalls/keyctl/keyctl_common.h
@@ -39,4 +39,24 @@ static inline bool is_asym_supported(key_serial_t ring_builtin)
return !(TST_RET == -1 && TST_ERR == ENOKEY);
}
+static inline key_serial_t add_asymmetric_key_or_tconf(const char *desc,
+ const void *payload,
+ size_t plen,
+ const char *parser_kconfig)
+{
+ TEST(add_key("asymmetric", desc, payload, plen, KEY_SPEC_PROCESS_KEYRING));
+ if (TST_RET >= 0)
+ return TST_RET;
+
+ if (TST_ERR == ENODEV)
+ tst_brk(TCONF, "kernel does not support asymmetric keys");
+ if (TST_ERR == EBADMSG)
+ tst_brk(TCONF, "missing asymmetric parser (%s)", parser_kconfig);
+ if (TST_ERR == ENOENT)
+ tst_brk(TCONF, "missing crypto RSA / SHA256 algorithms");
+
+ tst_brk(TBROK | TTERRNO, "failed to add asymmetric key '%s'", desc);
+ return -1;
+}
+
#endif /* KEYCTL_COMMON_H__ */
diff --git a/testcases/kernel/syscalls/keyctl/keyctl_pkey_data.h b/testcases/kernel/syscalls/keyctl/keyctl_pkey_data.h
new file mode 100644
index 0000000000..f5e55d94e0
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl_pkey_data.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ *
+ * Static test vectors for KEYCTL_PKEY_* tests (keyctl29..keyctl33).
+ */
+
+#ifndef KEYCTL_PKEY_DATA_H__
+#define KEYCTL_PKEY_DATA_H__
+
+/*
+ * RSA-2048 self-signed X.509 certificate in DER format generated using:
+ * openssl req -x509 -newkey rsa:2048 -subj "/CN=ltp-keyctl-pkey" -days 36500 -nodes -batch -outform der
+ */
+static const unsigned char rsa2048_cert[] = {
+ 0x30, 0x82, 0x03, 0x17, 0x30, 0x82, 0x01, 0xff, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x52,
+ 0xd4, 0x3e, 0xcb, 0x8a, 0x14, 0xa8, 0x5b, 0x02, 0x72, 0x3b, 0x64, 0xf9, 0x9d, 0x52, 0xa3, 0xca,
+ 0x61, 0x08, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x6c,
+ 0x74, 0x70, 0x2d, 0x6b, 0x65, 0x79, 0x63, 0x74, 0x6c, 0x2d, 0x70, 0x6b, 0x65, 0x79, 0x30, 0x20,
+ 0x17, 0x0d, 0x32, 0x36, 0x30, 0x39, 0x30, 0x31, 0x30, 0x39, 0x31, 0x31, 0x32, 0x36, 0x5a, 0x18,
+ 0x0f, 0x32, 0x31, 0x32, 0x36, 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, 0x31, 0x31, 0x32, 0x36, 0x5a,
+ 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x6c, 0x74, 0x70,
+ 0x2d, 0x6b, 0x65, 0x79, 0x63, 0x74, 0x6c, 0x2d, 0x70, 0x6b, 0x65, 0x79, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd3, 0x97, 0x61,
+ 0x14, 0x08, 0xb7, 0xca, 0x73, 0x54, 0xd0, 0x39, 0xb9, 0xaf, 0x62, 0x12, 0xcc, 0x90, 0xde, 0x86,
+ 0xeb, 0x13, 0x91, 0x06, 0x83, 0xf3, 0x41, 0x48, 0xd7, 0xf7, 0xc5, 0x50, 0x26, 0x1f, 0x2d, 0x53,
+ 0x09, 0x43, 0x59, 0x25, 0x81, 0x04, 0x98, 0x84, 0x4c, 0x10, 0x32, 0xee, 0x63, 0x60, 0xde, 0x1a,
+ 0x76, 0x63, 0xc3, 0x5d, 0x79, 0x12, 0xf2, 0xbf, 0x33, 0xd6, 0x4c, 0xf2, 0x47, 0x56, 0x03, 0x41,
+ 0x51, 0x74, 0x7f, 0x7d, 0x80, 0x64, 0x32, 0x1c, 0x1c, 0x19, 0xac, 0x12, 0x08, 0xd6, 0xd2, 0x27,
+ 0x21, 0x6c, 0xda, 0x40, 0xea, 0x3b, 0x9c, 0x7f, 0xa8, 0xee, 0x86, 0x0a, 0x18, 0xca, 0xc3, 0xb6,
+ 0x6a, 0xe8, 0x90, 0xcc, 0xaf, 0x44, 0x1c, 0x03, 0xdd, 0x57, 0xfc, 0x67, 0xba, 0xae, 0x5b, 0x7b,
+ 0x3e, 0xc3, 0xda, 0xcc, 0xcf, 0x96, 0x90, 0xad, 0x72, 0x4d, 0x44, 0x7d, 0x46, 0xa5, 0x7c, 0x83,
+ 0x4b, 0x74, 0x5d, 0x16, 0x20, 0x33, 0x4b, 0x8a, 0xdf, 0x8b, 0x14, 0x21, 0x6f, 0xbb, 0xb3, 0xd9,
+ 0x97, 0xef, 0xd2, 0xbf, 0x4f, 0x41, 0x01, 0x86, 0x69, 0xa0, 0xe6, 0xce, 0x7b, 0xdd, 0xb9, 0x5c,
+ 0x35, 0xce, 0x2f, 0x0c, 0x5d, 0x23, 0x60, 0x71, 0xd7, 0x09, 0x05, 0x1c, 0x70, 0xb4, 0x02, 0xaf,
+ 0x75, 0xb6, 0xcd, 0x2f, 0xbf, 0xba, 0xd0, 0x35, 0xc6, 0xd0, 0x09, 0x50, 0xcf, 0xf9, 0xd9, 0xe8,
+ 0xdc, 0x3b, 0xca, 0x19, 0x45, 0x63, 0x1c, 0x88, 0xc9, 0x4c, 0xa7, 0x09, 0xe6, 0x2c, 0x7e, 0x81,
+ 0xd0, 0x06, 0xe4, 0x37, 0xb9, 0x42, 0xc9, 0x3b, 0x5c, 0xb5, 0x70, 0xc4, 0xb5, 0x20, 0x14, 0xa1,
+ 0x51, 0x37, 0xf2, 0x58, 0xa8, 0x9c, 0x11, 0xc1, 0x70, 0xe6, 0xb0, 0x45, 0xf3, 0xc5, 0x23, 0xe7,
+ 0xee, 0xa7, 0x9d, 0x9b, 0x2b, 0x81, 0xef, 0xeb, 0x63, 0xf2, 0x93, 0x15, 0x21, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0x19, 0x69, 0xa7, 0x0c, 0x58, 0xc5, 0xd7, 0xb3, 0x0b, 0x26, 0xce, 0x2a, 0x34, 0x65, 0xae,
+ 0xa7, 0xad, 0xf6, 0xab, 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0x19, 0x69, 0xa7, 0x0c, 0x58, 0xc5, 0xd7, 0xb3, 0x0b, 0x26, 0xce, 0x2a, 0x34, 0x65,
+ 0xae, 0xa7, 0xad, 0xf6, 0xab, 0x74, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+ 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x8a, 0x1b, 0x54, 0x91,
+ 0xbb, 0xf6, 0xd9, 0xc5, 0x09, 0x4c, 0x9f, 0xd2, 0x64, 0xaf, 0xcf, 0x4e, 0x45, 0xda, 0xc6, 0x31,
+ 0x0f, 0x55, 0x7d, 0xe7, 0x83, 0xa1, 0xfe, 0x51, 0x42, 0xda, 0xb4, 0x8b, 0xba, 0xf7, 0x15, 0xae,
+ 0xde, 0xf3, 0x05, 0x44, 0xb7, 0xc2, 0x40, 0x03, 0x33, 0x88, 0x2b, 0x32, 0xee, 0x13, 0x3b, 0x50,
+ 0xb4, 0x38, 0x32, 0x3b, 0xa6, 0xdf, 0x58, 0x6a, 0x46, 0x48, 0x0d, 0xbc, 0x4a, 0xbf, 0xce, 0xb5,
+ 0x98, 0x7f, 0x5c, 0xcb, 0x04, 0xa8, 0xbf, 0x7b, 0x28, 0x04, 0xcf, 0x3b, 0xaa, 0x4d, 0x16, 0xb8,
+ 0x5f, 0x0a, 0x60, 0xca, 0xde, 0xe1, 0x87, 0x1a, 0x40, 0xc1, 0x2c, 0x93, 0x29, 0x30, 0x79, 0x21,
+ 0xca, 0xa3, 0x58, 0xea, 0x8d, 0x93, 0x96, 0x17, 0x69, 0xa9, 0xaf, 0x16, 0xaf, 0x6f, 0x44, 0x6a,
+ 0x4e, 0x59, 0x9d, 0x4d, 0x8e, 0x69, 0x7a, 0x11, 0x62, 0xbc, 0x99, 0x7e, 0x8e, 0xa6, 0x70, 0x2a,
+ 0x7b, 0xbb, 0x33, 0xde, 0x81, 0x22, 0x6d, 0x7f, 0x18, 0xa6, 0x25, 0x1f, 0x84, 0x03, 0x9b, 0x8e,
+ 0x88, 0x1b, 0x5c, 0x08, 0xf8, 0xb1, 0xf1, 0x27, 0x39, 0xbb, 0x06, 0x6c, 0x54, 0xfa, 0xb9, 0x9c,
+ 0xe1, 0x5b, 0xff, 0xc1, 0xf2, 0x24, 0xf0, 0x79, 0xbd, 0xb1, 0x9f, 0xa5, 0xb8, 0x9c, 0x11, 0x96,
+ 0x6b, 0xa1, 0x05, 0x64, 0x41, 0x45, 0x56, 0xf3, 0x5b, 0x51, 0x5d, 0x7f, 0x5d, 0x50, 0x15, 0x48,
+ 0xd0, 0x68, 0x87, 0x8a, 0x39, 0x86, 0xae, 0x03, 0xdd, 0x2a, 0x7f, 0x48, 0x25, 0x7b, 0xde, 0xd4,
+ 0x8b, 0x3c, 0xba, 0x07, 0xc6, 0x53, 0xbb, 0x2b, 0x67, 0x98, 0x00, 0xc5, 0x5d, 0x38, 0xc0, 0xc4,
+ 0x51, 0x8e, 0x24, 0xc9, 0x85, 0x83, 0xb3, 0x16, 0x79, 0x7c, 0xcc, 0x76, 0xed, 0x02, 0x1f, 0x91,
+ 0x2c, 0xa7, 0x23, 0xae, 0x7b, 0xfd, 0xd5, 0x09, 0x09, 0x70, 0x28,
+};
+
+#endif /* KEYCTL_PKEY_DATA_H__ */
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 26/36] keyctl30: Test KEYCTL_PKEY_QUERY on private key
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (24 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 25/36] keyctl29: Test KEYCTL_PKEY_QUERY on public key Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 14:50 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 27/36] keyctl31: Test KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT Petr Vorel
` (10 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_PKEY_QUERY operation on an RSA-2048 PKCS#8 private key:
verify key_size is 2048, supported_ops contains DECRYPT and SIGN,
and max_dec_size/max_sig_size are 256.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl30.c | 86 +++++++++++++++++++
.../kernel/syscalls/keyctl/keyctl_pkey_data.h | 84 ++++++++++++++++++
4 files changed, 172 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl30.c
diff --git a/runtest/syscalls b/runtest/syscalls
index c41321b407..accdf2df9b 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -747,6 +747,7 @@ keyctl26 keyctl26
keyctl27 keyctl27
keyctl28 keyctl28
keyctl29 keyctl29
+keyctl30 keyctl30
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 91310b0018..d5b6955f33 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -27,3 +27,4 @@
/keyctl27
/keyctl28
/keyctl29
+/keyctl30
diff --git a/testcases/kernel/syscalls/keyctl/keyctl30.c b/testcases/kernel/syscalls/keyctl/keyctl30.c
new file mode 100644
index 0000000000..e46206ca93
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl30.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_PKEY_QUERY`` on private key of :manpage:`keyctl(2)`.
+ *
+ * Requires root (CAP_SYS_MODULE) to load the ``pkcs8_key_parser`` module.
+ *
+ * [Algorithm]
+ *
+ * - query an RSA-2048 PKCS#8 private key
+ * - verify ``key_size`` is 2048 bits
+ * - verify ``supported_ops`` contains ``KEYCTL_SUPPORTS_DECRYPT`` and
+ * ``KEYCTL_SUPPORTS_SIGN``
+ * - verify ``max_dec_size`` is 256 bytes
+ * - verify ``max_sig_size`` is 256 bytes
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_pkey_data.h"
+#include "tst_module.h"
+
+static key_serial_t priv_key;
+static struct keyctl_pkey_query *query_buf;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ tst_modprobe("pkcs8_key_parser", NULL);
+
+ priv_key = add_asymmetric_key_or_tconf("priv", rsa2048_pkcs8,
+ sizeof(rsa2048_pkcs8),
+ "CONFIG_PKCS8_PRIVATE_KEY_PARSER");
+}
+
+static void run(void)
+{
+ memset(query_buf, 0, sizeof(*query_buf));
+
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_PKEY_QUERY, (unsigned long)priv_key,
+ 0, (unsigned long)"enc=pkcs1",
+ (unsigned long)query_buf), 0);
+ if (!TST_PASS)
+ return;
+
+ TST_EXP_EQ_LU_SILENT(query_buf->key_size, 2048);
+ if (!TST_PASS)
+ return;
+
+ TST_EXP_EXPR(query_buf->supported_ops & KEYCTL_SUPPORTS_DECRYPT,
+ "KEYCTL_PKEY_QUERY supports DECRYPT");
+
+ TST_EXP_EXPR(query_buf->supported_ops & KEYCTL_SUPPORTS_SIGN,
+ "KEYCTL_PKEY_QUERY supports SIGN");
+
+ TST_EXP_EQ_LU_SILENT(query_buf->max_dec_size, 256);
+ if (!TST_PASS)
+ return;
+
+ TST_EXP_EQ_LU_SILENT(query_buf->max_sig_size, 256);
+ if (!TST_PASS)
+ return;
+
+ tst_res(TPASS, "KEYCTL_PKEY_QUERY on PKCS#8 private key returned valid parameters");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.20",
+ .needs_root = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_ASYMMETRIC_KEY_TYPE=y",
+ "CONFIG_PKCS8_PRIVATE_KEY_PARSER",
+ "CONFIG_CRYPTO_RSA",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&query_buf, .size = sizeof(*query_buf)},
+ {},
+ },
+};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl_pkey_data.h b/testcases/kernel/syscalls/keyctl/keyctl_pkey_data.h
index f5e55d94e0..75481b89a6 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl_pkey_data.h
+++ b/testcases/kernel/syscalls/keyctl/keyctl_pkey_data.h
@@ -65,4 +65,88 @@ static const unsigned char rsa2048_cert[] = {
0x2c, 0xa7, 0x23, 0xae, 0x7b, 0xfd, 0xd5, 0x09, 0x09, 0x70, 0x28,
};
+/*
+ * RSA-2048 unencrypted PKCS#8 private key in DER format generated using:
+ * openssl pkcs8 -topk8 -nocrypt -outform der
+ */
+static const unsigned char rsa2048_pkcs8[] = {
+ 0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xa8, 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01,
+ 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd3, 0x97, 0x61, 0x14, 0x08, 0xb7, 0xca, 0x73, 0x54, 0xd0,
+ 0x39, 0xb9, 0xaf, 0x62, 0x12, 0xcc, 0x90, 0xde, 0x86, 0xeb, 0x13, 0x91, 0x06, 0x83, 0xf3, 0x41,
+ 0x48, 0xd7, 0xf7, 0xc5, 0x50, 0x26, 0x1f, 0x2d, 0x53, 0x09, 0x43, 0x59, 0x25, 0x81, 0x04, 0x98,
+ 0x84, 0x4c, 0x10, 0x32, 0xee, 0x63, 0x60, 0xde, 0x1a, 0x76, 0x63, 0xc3, 0x5d, 0x79, 0x12, 0xf2,
+ 0xbf, 0x33, 0xd6, 0x4c, 0xf2, 0x47, 0x56, 0x03, 0x41, 0x51, 0x74, 0x7f, 0x7d, 0x80, 0x64, 0x32,
+ 0x1c, 0x1c, 0x19, 0xac, 0x12, 0x08, 0xd6, 0xd2, 0x27, 0x21, 0x6c, 0xda, 0x40, 0xea, 0x3b, 0x9c,
+ 0x7f, 0xa8, 0xee, 0x86, 0x0a, 0x18, 0xca, 0xc3, 0xb6, 0x6a, 0xe8, 0x90, 0xcc, 0xaf, 0x44, 0x1c,
+ 0x03, 0xdd, 0x57, 0xfc, 0x67, 0xba, 0xae, 0x5b, 0x7b, 0x3e, 0xc3, 0xda, 0xcc, 0xcf, 0x96, 0x90,
+ 0xad, 0x72, 0x4d, 0x44, 0x7d, 0x46, 0xa5, 0x7c, 0x83, 0x4b, 0x74, 0x5d, 0x16, 0x20, 0x33, 0x4b,
+ 0x8a, 0xdf, 0x8b, 0x14, 0x21, 0x6f, 0xbb, 0xb3, 0xd9, 0x97, 0xef, 0xd2, 0xbf, 0x4f, 0x41, 0x01,
+ 0x86, 0x69, 0xa0, 0xe6, 0xce, 0x7b, 0xdd, 0xb9, 0x5c, 0x35, 0xce, 0x2f, 0x0c, 0x5d, 0x23, 0x60,
+ 0x71, 0xd7, 0x09, 0x05, 0x1c, 0x70, 0xb4, 0x02, 0xaf, 0x75, 0xb6, 0xcd, 0x2f, 0xbf, 0xba, 0xd0,
+ 0x35, 0xc6, 0xd0, 0x09, 0x50, 0xcf, 0xf9, 0xd9, 0xe8, 0xdc, 0x3b, 0xca, 0x19, 0x45, 0x63, 0x1c,
+ 0x88, 0xc9, 0x4c, 0xa7, 0x09, 0xe6, 0x2c, 0x7e, 0x81, 0xd0, 0x06, 0xe4, 0x37, 0xb9, 0x42, 0xc9,
+ 0x3b, 0x5c, 0xb5, 0x70, 0xc4, 0xb5, 0x20, 0x14, 0xa1, 0x51, 0x37, 0xf2, 0x58, 0xa8, 0x9c, 0x11,
+ 0xc1, 0x70, 0xe6, 0xb0, 0x45, 0xf3, 0xc5, 0x23, 0xe7, 0xee, 0xa7, 0x9d, 0x9b, 0x2b, 0x81, 0xef,
+ 0xeb, 0x63, 0xf2, 0x93, 0x15, 0x21, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x52,
+ 0xb0, 0xba, 0x53, 0xa6, 0x04, 0x8d, 0xad, 0xfc, 0xdb, 0x53, 0x73, 0xe9, 0xc2, 0x9e, 0x2e, 0x2b,
+ 0xff, 0x8b, 0x22, 0x9b, 0x86, 0xf5, 0xd0, 0xe3, 0x64, 0x04, 0x1f, 0xc2, 0xc8, 0xed, 0xc5, 0xb8,
+ 0x31, 0x72, 0x5e, 0x10, 0x5f, 0xea, 0x74, 0x3d, 0x63, 0x8d, 0x70, 0x5c, 0x74, 0x4b, 0x0d, 0xb3,
+ 0x71, 0x99, 0x4d, 0xe3, 0x37, 0x1a, 0x74, 0x92, 0x9f, 0x23, 0x72, 0x12, 0xb2, 0x07, 0x8d, 0x31,
+ 0x64, 0x1c, 0x46, 0xc5, 0x0c, 0x7d, 0xf3, 0x8b, 0x34, 0xba, 0x1f, 0x91, 0x38, 0xd9, 0xe3, 0x72,
+ 0x70, 0xb6, 0xb2, 0x2d, 0x64, 0x2e, 0x32, 0x5c, 0x11, 0x91, 0x22, 0x67, 0xf5, 0x22, 0x45, 0x06,
+ 0x18, 0xee, 0x55, 0x61, 0x86, 0x15, 0x37, 0xf9, 0x9a, 0x29, 0x38, 0x7b, 0x86, 0x3c, 0xd3, 0x8c,
+ 0x08, 0x5c, 0x65, 0xef, 0x0c, 0xb7, 0x35, 0xf9, 0x55, 0x99, 0x33, 0x2e, 0x57, 0x31, 0xcd, 0x90,
+ 0x0e, 0x99, 0xcd, 0xb3, 0x5f, 0xb5, 0x7e, 0x16, 0x86, 0x73, 0x47, 0xc0, 0xab, 0x6b, 0x53, 0xa1,
+ 0x8f, 0x35, 0x34, 0xd3, 0x82, 0x28, 0x7c, 0x65, 0x8e, 0xa8, 0x02, 0xe2, 0xf3, 0x83, 0x6d, 0x54,
+ 0x43, 0x23, 0x45, 0x95, 0xf1, 0x74, 0xbc, 0xf1, 0x7d, 0x64, 0x16, 0xe5, 0x01, 0xc6, 0x5a, 0xbb,
+ 0x19, 0xfa, 0x54, 0x01, 0xa4, 0x26, 0x5a, 0x2f, 0xa4, 0x20, 0xb7, 0x4c, 0x61, 0x2c, 0x2a, 0x78,
+ 0xed, 0x2f, 0xcb, 0x67, 0x26, 0xf1, 0x6b, 0x0c, 0xe3, 0x8a, 0x27, 0x9e, 0x4f, 0x00, 0x06, 0x4e,
+ 0x1d, 0x58, 0x07, 0x0e, 0x1c, 0x0d, 0x0c, 0x8c, 0x3a, 0xa7, 0x1d, 0xbe, 0xb8, 0x16, 0xdf, 0xe1,
+ 0xb3, 0x13, 0x09, 0x6a, 0xe7, 0x50, 0x80, 0x2f, 0xa1, 0x38, 0x22, 0xae, 0x2d, 0x58, 0x52, 0x07,
+ 0x96, 0x10, 0x98, 0x71, 0xe1, 0xce, 0x26, 0x88, 0x4c, 0x5e, 0x11, 0x5f, 0x6c, 0xd2, 0x31, 0x02,
+ 0x81, 0x81, 0x00, 0xf3, 0x64, 0x07, 0x8c, 0x91, 0x3c, 0x5a, 0x48, 0x14, 0x4a, 0xc1, 0x4a, 0x1a,
+ 0x93, 0xe5, 0xb8, 0x3a, 0x3c, 0xfe, 0x41, 0x60, 0x49, 0x71, 0xcc, 0xee, 0xaf, 0x0e, 0xac, 0x0c,
+ 0x85, 0x51, 0x48, 0xf9, 0x36, 0xcf, 0x8c, 0xc5, 0x58, 0x48, 0xa2, 0x49, 0x46, 0xd1, 0x33, 0x92,
+ 0x8c, 0x40, 0xfa, 0xf0, 0x76, 0xc1, 0x88, 0x8f, 0x23, 0x06, 0x8b, 0x76, 0x15, 0x89, 0xc0, 0xcd,
+ 0x4b, 0x61, 0xd8, 0xc6, 0xa2, 0xcf, 0x9c, 0x04, 0x40, 0x3b, 0x7a, 0x24, 0xc1, 0x97, 0xb9, 0x36,
+ 0xa6, 0x8b, 0xff, 0xe7, 0xef, 0xa5, 0x56, 0x3c, 0x55, 0xbf, 0x6d, 0x74, 0x33, 0xeb, 0x67, 0xb3,
+ 0x4a, 0xfe, 0x81, 0xaa, 0xad, 0xd9, 0x43, 0x23, 0x59, 0xef, 0x51, 0x99, 0x2b, 0x58, 0xa6, 0xc1,
+ 0x9c, 0x09, 0x5c, 0x88, 0xa0, 0x71, 0x1c, 0x1e, 0x94, 0x39, 0xcd, 0x82, 0x7d, 0xea, 0x41, 0xa8,
+ 0x9e, 0x05, 0x17, 0x02, 0x81, 0x81, 0x00, 0xde, 0x8d, 0x9c, 0x20, 0xa1, 0x2f, 0x47, 0x3d, 0xac,
+ 0x5f, 0x15, 0xce, 0x55, 0x52, 0x6a, 0x2f, 0x3d, 0xa0, 0xb0, 0x84, 0x92, 0x6c, 0xd6, 0x0f, 0x3c,
+ 0x2e, 0x96, 0xc0, 0x26, 0x16, 0xa9, 0x0c, 0xc0, 0xec, 0x06, 0x50, 0xe7, 0x58, 0x1d, 0xfb, 0xcc,
+ 0x9a, 0x64, 0x2f, 0x1b, 0x3a, 0x69, 0xb5, 0x51, 0xca, 0xf7, 0x2e, 0xa5, 0x01, 0x1e, 0xc9, 0x23,
+ 0x85, 0x88, 0x86, 0x9e, 0x95, 0x8c, 0x03, 0xfb, 0xaf, 0x46, 0x6c, 0x7c, 0x9a, 0x4b, 0x00, 0xb7,
+ 0x27, 0x18, 0x73, 0xea, 0x1d, 0xc6, 0x55, 0x1d, 0x4c, 0xca, 0x70, 0xb1, 0xb2, 0x76, 0x21, 0x92,
+ 0xf0, 0x6f, 0xa8, 0x81, 0x82, 0x6f, 0x52, 0x70, 0x36, 0xe0, 0x66, 0x0f, 0x4f, 0x7d, 0xda, 0xf2,
+ 0xbb, 0xca, 0xaa, 0x2d, 0x3c, 0x27, 0x2a, 0xc4, 0xa6, 0x16, 0x0a, 0xec, 0x91, 0x46, 0xbc, 0x7d,
+ 0x32, 0x87, 0xd0, 0x3b, 0x80, 0x8a, 0x87, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x07, 0x6d, 0x2c, 0x72,
+ 0x75, 0xc5, 0xcd, 0xbe, 0x05, 0x00, 0x79, 0x4a, 0x36, 0x37, 0x97, 0x07, 0x62, 0xce, 0x5b, 0x49,
+ 0xcd, 0xef, 0x51, 0x04, 0x4e, 0x3f, 0xca, 0xb5, 0x33, 0xc9, 0xba, 0xaa, 0xd1, 0xa6, 0xa5, 0xf5,
+ 0x4f, 0x6d, 0x29, 0x2d, 0xef, 0x61, 0x0f, 0xdf, 0x3e, 0x12, 0x1f, 0xe1, 0xdf, 0x02, 0x2c, 0x68,
+ 0xa4, 0xc0, 0x72, 0x6c, 0x55, 0x51, 0xc1, 0x80, 0x5e, 0xf8, 0xb1, 0xed, 0xf4, 0x9b, 0x67, 0xf8,
+ 0x6d, 0xb2, 0xa9, 0xe9, 0x0e, 0x0b, 0x42, 0xee, 0x6b, 0xa8, 0x76, 0x5b, 0x11, 0x8b, 0xaf, 0xd8,
+ 0xce, 0x8f, 0x70, 0x49, 0x01, 0xc8, 0xe1, 0x82, 0xae, 0xed, 0xe1, 0xda, 0x0e, 0xda, 0xd9, 0xb2,
+ 0xfe, 0x53, 0x05, 0x33, 0xa6, 0x9d, 0x57, 0xeb, 0x24, 0x11, 0x0a, 0x76, 0xe5, 0x12, 0x91, 0x7a,
+ 0xa9, 0x56, 0xa9, 0xaa, 0xaf, 0xf4, 0x4d, 0x39, 0x62, 0x80, 0xad, 0x02, 0x81, 0x81, 0x00, 0xc6,
+ 0x20, 0x7b, 0xa5, 0xf0, 0xd9, 0x0e, 0x2b, 0x31, 0x91, 0x54, 0xf0, 0x63, 0xb5, 0x03, 0x23, 0x1b,
+ 0x52, 0x3a, 0xd3, 0x4b, 0x27, 0xe9, 0x49, 0x96, 0xe2, 0x43, 0x02, 0xbc, 0xe5, 0xdf, 0x89, 0xa3,
+ 0x16, 0x7c, 0x68, 0xfa, 0x0b, 0xd0, 0x65, 0xa2, 0x38, 0xb0, 0x87, 0xdf, 0x4d, 0x99, 0x5d, 0xfa,
+ 0x7b, 0x1e, 0xa3, 0x3f, 0xf2, 0x47, 0x5d, 0xf9, 0x69, 0x9f, 0xa9, 0x78, 0xf4, 0xd9, 0xb9, 0x92,
+ 0x0e, 0xf0, 0x3b, 0x14, 0x92, 0xa7, 0xc2, 0xf3, 0x4a, 0xb2, 0xd2, 0x3e, 0xd2, 0x53, 0x06, 0xe3,
+ 0x16, 0xc2, 0x02, 0xa1, 0xaf, 0xa6, 0xcb, 0x2c, 0xed, 0x2f, 0xfa, 0x6b, 0x91, 0x9b, 0x59, 0x60,
+ 0xdc, 0xf9, 0xd8, 0xe2, 0x38, 0x7a, 0x6a, 0xb9, 0x3d, 0xc5, 0xa6, 0xca, 0xae, 0x8a, 0x8f, 0xe0,
+ 0x91, 0x9b, 0x7e, 0x0e, 0x2d, 0x27, 0x34, 0x16, 0xa1, 0x2d, 0x97, 0x8b, 0xe1, 0x5b, 0x71, 0x02,
+ 0x81, 0x80, 0x34, 0xb5, 0x23, 0xd0, 0x7f, 0xa5, 0x1f, 0x3f, 0xa2, 0xfc, 0xb8, 0x50, 0x5f, 0x16,
+ 0x76, 0x65, 0x67, 0x48, 0x62, 0xbe, 0xf8, 0x98, 0x07, 0x5c, 0xa9, 0xc2, 0x79, 0x59, 0xda, 0xa0,
+ 0xb8, 0x1b, 0x50, 0x73, 0xd6, 0x74, 0x17, 0xba, 0x09, 0xdb, 0x08, 0xc9, 0xfb, 0xe5, 0x2c, 0xe5,
+ 0xea, 0xde, 0x32, 0x1a, 0x51, 0xdf, 0xb4, 0xa8, 0x4e, 0xb5, 0x93, 0x2d, 0x58, 0x90, 0x36, 0xaa,
+ 0xa4, 0x12, 0x53, 0x54, 0x3d, 0xb0, 0xbc, 0x52, 0xb3, 0x9a, 0x0b, 0x6e, 0x73, 0xb2, 0x57, 0x58,
+ 0xbe, 0xb8, 0xfc, 0xa0, 0xaa, 0x02, 0x69, 0xea, 0xc4, 0x1b, 0xe4, 0x3e, 0x42, 0xf0, 0xf8, 0x2d,
+ 0xa2, 0xb3, 0xa9, 0x3e, 0x57, 0xfe, 0x1a, 0xe9, 0xa6, 0xca, 0x05, 0x7f, 0x9b, 0x60, 0xd7, 0x28,
+ 0x4a, 0x6a, 0xd7, 0xf4, 0xe4, 0xa1, 0x5d, 0x5c, 0x4f, 0xed, 0xd3, 0xaa, 0xb7, 0xb9, 0xfc, 0x87,
+ 0xcd, 0xc5,
+};
+
#endif /* KEYCTL_PKEY_DATA_H__ */
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 26/36] keyctl30: Test KEYCTL_PKEY_QUERY on private key
2026-09-16 14:03 ` [LTP] [PATCH v3 26/36] keyctl30: Test KEYCTL_PKEY_QUERY on private key Petr Vorel
@ 2026-09-18 14:50 ` Cyril Hrubis
2026-09-18 16:55 ` Petr Vorel
0 siblings, 1 reply; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-18 14:50 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
> +static void run(void)
> +{
> + memset(query_buf, 0, sizeof(*query_buf));
> +
> + TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_PKEY_QUERY, (unsigned long)priv_key,
> + 0, (unsigned long)"enc=pkcs1",
> + (unsigned long)query_buf), 0);
> + if (!TST_PASS)
> + return;
Here as well, TST_EXP_PASS()?
Otherwise:
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 26/36] keyctl30: Test KEYCTL_PKEY_QUERY on private key
2026-09-18 14:50 ` Cyril Hrubis
@ 2026-09-18 16:55 ` Petr Vorel
0 siblings, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-18 16:55 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
Hi Cyril,
> Hi!
> > +static void run(void)
> > +{
> > + memset(query_buf, 0, sizeof(*query_buf));
> > +
> > + TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_PKEY_QUERY, (unsigned long)priv_key,
> > + 0, (unsigned long)"enc=pkcs1",
> > + (unsigned long)query_buf), 0);
> > + if (!TST_PASS)
> > + return;
> Here as well, TST_EXP_PASS()?
> Otherwise:
> Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Fixed and merged up to here.
The rest will have to wait till Monday or after release.
(I'd prefer to finish merging up to keyctl37.c on Monday if we both have time).
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 27/36] keyctl31: Test KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (25 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 26/36] keyctl30: Test KEYCTL_PKEY_QUERY on private key Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 15:17 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 28/36] keyctl32: Test KEYCTL_PKEY_SIGN and VERIFY Petr Vorel
` (9 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test public key encryption and private key decryption with
KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT: encrypt a 32-byte
plaintext using an RSA-2048 X.509 public key with enc=pkcs1,
decrypt with the matching PKCS#8 private key, and verify the
decrypted output matches the original plaintext.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl31.c | 110 ++++++++++++++++++++
3 files changed, 112 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl31.c
diff --git a/runtest/syscalls b/runtest/syscalls
index accdf2df9b..a8c3486cb5 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -748,6 +748,7 @@ keyctl27 keyctl27
keyctl28 keyctl28
keyctl29 keyctl29
keyctl30 keyctl30
+keyctl31 keyctl31
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index d5b6955f33..025dc27fc9 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -28,3 +28,4 @@
/keyctl28
/keyctl29
/keyctl30
+/keyctl31
diff --git a/testcases/kernel/syscalls/keyctl/keyctl31.c b/testcases/kernel/syscalls/keyctl/keyctl31.c
new file mode 100644
index 0000000000..c1e6723ac8
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl31.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_PKEY_ENCRYPT`` and ``KEYCTL_PKEY_DECRYPT`` of :manpage:`keyctl(2)`.
+ *
+ * ``KEYCTL_PKEY_ENCRYPT`` encrypts a data blob using an asymmetric public key
+ * and ``KEYCTL_PKEY_DECRYPT`` decrypts the encrypted blob using the matching
+ * private key.
+ *
+ * Requires root (CAP_SYS_MODULE) to load the ``x509_key_parser`` and
+ * ``pkcs8_key_parser`` modules.
+ *
+ * [Algorithm]
+ *
+ * - encrypt a 32-byte plaintext using an RSA-2048 X.509 public key with ``enc=pkcs1``
+ * - decrypt the 256-byte ciphertext using the matching PKCS#8 private key
+ * - verify the decrypted output matches the original 32-byte plaintext
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_pkey_data.h"
+#include "tst_module.h"
+
+#define CIPHERTEXT_SIZE 256
+
+static const char plaintext[] = "LTP_PKEY_ENCRYPT_DECRYPT_TEST_32";
+#define PLAINTEXT_SIZE (sizeof(plaintext) - 1)
+static unsigned char ciphertext[CIPHERTEXT_SIZE];
+static unsigned char decrypted[CIPHERTEXT_SIZE];
+
+static key_serial_t cert_key, priv_key;
+static struct keyctl_pkey_params *enc_params;
+static struct keyctl_pkey_params *dec_params;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ tst_modprobe("x509_key_parser", NULL);
+ tst_modprobe("pkcs8_key_parser", NULL);
+
+ cert_key = add_asymmetric_key_or_tconf("cert", rsa2048_cert,
+ sizeof(rsa2048_cert),
+ "CONFIG_X509_CERTIFICATE_PARSER");
+ priv_key = add_asymmetric_key_or_tconf("priv", rsa2048_pkcs8,
+ sizeof(rsa2048_pkcs8),
+ "CONFIG_PKCS8_PRIVATE_KEY_PARSER");
+}
+
+static void run(void)
+{
+ memset(ciphertext, 0, sizeof(ciphertext));
+ memset(decrypted, 0, sizeof(decrypted));
+
+ memset(enc_params, 0, sizeof(*enc_params));
+ enc_params->key_id = cert_key;
+ enc_params->in_len = PLAINTEXT_SIZE;
+ enc_params->out_len = CIPHERTEXT_SIZE;
+
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_PKEY_ENCRYPT, (unsigned long)enc_params,
+ (unsigned long)"enc=pkcs1",
+ (unsigned long)plaintext,
+ (unsigned long)ciphertext),
+ CIPHERTEXT_SIZE);
+ if (!TST_PASS)
+ return;
+
+ memset(dec_params, 0, sizeof(*dec_params));
+ dec_params->key_id = priv_key;
+ dec_params->in_len = CIPHERTEXT_SIZE;
+ dec_params->out_len = CIPHERTEXT_SIZE;
+
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_PKEY_DECRYPT, (unsigned long)dec_params,
+ (unsigned long)"enc=pkcs1",
+ (unsigned long)ciphertext,
+ (unsigned long)decrypted),
+ PLAINTEXT_SIZE);
+ if (!TST_PASS)
+ return;
+
+ if (memcmp(plaintext, decrypted, PLAINTEXT_SIZE)) {
+ tst_res(TFAIL, "decrypted text does not match original plaintext");
+ return;
+ }
+
+ tst_res(TPASS, "KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT roundtrip succeeded");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.20",
+ .needs_root = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_ASYMMETRIC_KEY_TYPE=y",
+ "CONFIG_X509_CERTIFICATE_PARSER",
+ "CONFIG_PKCS8_PRIVATE_KEY_PARSER",
+ "CONFIG_CRYPTO_RSA",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&enc_params, .size = sizeof(*enc_params)},
+ {&dec_params, .size = sizeof(*dec_params)},
+ {},
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 27/36] keyctl31: Test KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT
2026-09-16 14:03 ` [LTP] [PATCH v3 27/36] keyctl31: Test KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT Petr Vorel
@ 2026-09-18 15:17 ` Cyril Hrubis
2026-09-18 15:53 ` Petr Vorel
2026-09-18 17:01 ` Petr Vorel
0 siblings, 2 replies; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-18 15:17 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
> diff --git a/testcases/kernel/syscalls/keyctl/keyctl31.c b/testcases/kernel/syscalls/keyctl/keyctl31.c
> new file mode 100644
> index 0000000000..c1e6723ac8
> --- /dev/null
> +++ b/testcases/kernel/syscalls/keyctl/keyctl31.c
> @@ -0,0 +1,110 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
> + */
> +
> +/*\
> + * Test ``KEYCTL_PKEY_ENCRYPT`` and ``KEYCTL_PKEY_DECRYPT`` of :manpage:`keyctl(2)`.
> + *
> + * ``KEYCTL_PKEY_ENCRYPT`` encrypts a data blob using an asymmetric public key
> + * and ``KEYCTL_PKEY_DECRYPT`` decrypts the encrypted blob using the matching
> + * private key.
> + *
> + * Requires root (CAP_SYS_MODULE) to load the ``x509_key_parser`` and
> + * ``pkcs8_key_parser`` modules.
> + *
> + * [Algorithm]
> + *
> + * - encrypt a 32-byte plaintext using an RSA-2048 X.509 public key with ``enc=pkcs1``
> + * - decrypt the 256-byte ciphertext using the matching PKCS#8 private key
> + * - verify the decrypted output matches the original 32-byte plaintext
> + */
> +
> +#include "keyctl_common.h"
> +#include "keyctl_pkey_data.h"
> +#include "tst_module.h"
> +
> +#define CIPHERTEXT_SIZE 256
> +
> +static const char plaintext[] = "LTP_PKEY_ENCRYPT_DECRYPT_TEST_32";
> +#define PLAINTEXT_SIZE (sizeof(plaintext) - 1)
> +static unsigned char ciphertext[CIPHERTEXT_SIZE];
> +static unsigned char decrypted[CIPHERTEXT_SIZE];
Shouldn't these two be in the guarded buffers as well? I would say that
it's pretty much important that the kernel does not touch anything
outside of these arrays during encryption/decryption.
Otherwise:
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [LTP] [PATCH v3 27/36] keyctl31: Test KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT
2026-09-18 15:17 ` Cyril Hrubis
@ 2026-09-18 15:53 ` Petr Vorel
2026-09-18 17:01 ` Petr Vorel
1 sibling, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-18 15:53 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
Hi Cyril,
> Hi!
> > diff --git a/testcases/kernel/syscalls/keyctl/keyctl31.c b/testcases/kernel/syscalls/keyctl/keyctl31.c
> > new file mode 100644
> > index 0000000000..c1e6723ac8
> > --- /dev/null
> > +++ b/testcases/kernel/syscalls/keyctl/keyctl31.c
> > @@ -0,0 +1,110 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
> > + */
> > +
> > +/*\
> > + * Test ``KEYCTL_PKEY_ENCRYPT`` and ``KEYCTL_PKEY_DECRYPT`` of :manpage:`keyctl(2)`.
> > + *
> > + * ``KEYCTL_PKEY_ENCRYPT`` encrypts a data blob using an asymmetric public key
> > + * and ``KEYCTL_PKEY_DECRYPT`` decrypts the encrypted blob using the matching
> > + * private key.
> > + *
> > + * Requires root (CAP_SYS_MODULE) to load the ``x509_key_parser`` and
> > + * ``pkcs8_key_parser`` modules.
> > + *
> > + * [Algorithm]
> > + *
> > + * - encrypt a 32-byte plaintext using an RSA-2048 X.509 public key with ``enc=pkcs1``
> > + * - decrypt the 256-byte ciphertext using the matching PKCS#8 private key
> > + * - verify the decrypted output matches the original 32-byte plaintext
> > + */
> > +
> > +#include "keyctl_common.h"
> > +#include "keyctl_pkey_data.h"
> > +#include "tst_module.h"
> > +
> > +#define CIPHERTEXT_SIZE 256
> > +
> > +static const char plaintext[] = "LTP_PKEY_ENCRYPT_DECRYPT_TEST_32";
> > +#define PLAINTEXT_SIZE (sizeof(plaintext) - 1)
> > +static unsigned char ciphertext[CIPHERTEXT_SIZE];
> > +static unsigned char decrypted[CIPHERTEXT_SIZE];
> Shouldn't these two be in the guarded buffers as well? I would say that
> it's pretty much important that the kernel does not touch anything
> outside of these arrays during encryption/decryption.
Make sense to me, I'll amend.
Kind regards,
Petr
+++ testcases/kernel/syscalls/keyctl/keyctl31.c
@@ -103,6 +103,8 @@ static struct tst_test test = {
NULL
},
.bufs = (struct tst_buffers []) {
+ {&ciphertext, .size = sizeof(*ciphertext)},
+ {&decrypted, .size = sizeof(*decrypted)},
{&enc_params, .size = sizeof(*enc_params)},
{&dec_params, .size = sizeof(*dec_params)},
{},
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 27/36] keyctl31: Test KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT
2026-09-18 15:17 ` Cyril Hrubis
2026-09-18 15:53 ` Petr Vorel
@ 2026-09-18 17:01 ` Petr Vorel
1 sibling, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-18 17:01 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
Hi Cyril,
> > +static const char plaintext[] = "LTP_PKEY_ENCRYPT_DECRYPT_TEST_32";
> > +#define PLAINTEXT_SIZE (sizeof(plaintext) - 1)
> > +static unsigned char ciphertext[CIPHERTEXT_SIZE];
> > +static unsigned char decrypted[CIPHERTEXT_SIZE];
> Shouldn't these two be in the guarded buffers as well? I would say that
> it's pretty much important that the kernel does not touch anything
> outside of these arrays during encryption/decryption.
In the end I stopped here. To be honest I was not sure if array should be passed
with pointer (I suppose) or without to the struct tst_buffers. Because we don't
use it like this anywhere in the code.
Also, not only this keyctl31.c and keyctl36.c, but maybe also keyctl25.c and
keyctl27.c could be using it.
We have still few tests to merge keyctl31.c to keyctl37.c (the last 2 are really
on Andrea). Ideally you do the final changes. Feel free to use andrea/keyctl.v4
in my fork (that way you will not have to download the patches manually).
Kind regards,
Petr
> Otherwise:
> Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 28/36] keyctl32: Test KEYCTL_PKEY_SIGN and VERIFY
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (26 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 27/36] keyctl31: Test KEYCTL_PKEY_ENCRYPT and KEYCTL_PKEY_DECRYPT Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 15:25 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 29/36] keyctl33: Negative tests for KEYCTL_PKEY_* Petr Vorel
` (8 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test public key signature creation and verification with
KEYCTL_PKEY_SIGN and KEYCTL_PKEY_VERIFY: sign a 32-byte digest
using an RSA-2048 PKCS#8 private key with enc=pkcs1, verify
the 256-byte signature with the matching X.509 public key,
and verify that a mismatched digest fails with EKEYREJECTED.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl32.c | 121 ++++++++++++++++++++
3 files changed, 123 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl32.c
diff --git a/runtest/syscalls b/runtest/syscalls
index a8c3486cb5..9c74b3db82 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -749,6 +749,7 @@ keyctl28 keyctl28
keyctl29 keyctl29
keyctl30 keyctl30
keyctl31 keyctl31
+keyctl32 keyctl32
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 025dc27fc9..8b1627bee3 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -29,3 +29,4 @@
/keyctl29
/keyctl30
/keyctl31
+/keyctl32
diff --git a/testcases/kernel/syscalls/keyctl/keyctl32.c b/testcases/kernel/syscalls/keyctl/keyctl32.c
new file mode 100644
index 0000000000..4a00225f6f
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl32.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_PKEY_SIGN`` and ``KEYCTL_PKEY_VERIFY`` of :manpage:`keyctl(2)`.
+ *
+ * ``KEYCTL_PKEY_SIGN`` signs a digest using an asymmetric private key and
+ * ``KEYCTL_PKEY_VERIFY`` verifies the signature using the matching public key.
+ *
+ * Requires root (CAP_SYS_MODULE) to load the ``x509_key_parser`` and
+ * ``pkcs8_key_parser`` modules.
+ *
+ * [Algorithm]
+ *
+ * - sign a 32-byte digest using an RSA-2048 PKCS#8 private key with
+ * ``enc=pkcs1 hash=sha256``
+ * - verify the 256-byte signature using the matching X.509 public key
+ * - verify a mismatched digest fails verification with ``EKEYREJECTED``
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_pkey_data.h"
+#include "tst_module.h"
+
+#define DIGEST_SIZE 32
+#define SIG_SIZE 256
+
+static const unsigned char digest[DIGEST_SIZE] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+static unsigned char sig[SIG_SIZE];
+static unsigned char wrong_digest[DIGEST_SIZE];
+
+static key_serial_t cert_key, priv_key;
+static struct keyctl_pkey_params *sign_params;
+static struct keyctl_pkey_params *verify_params;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ tst_modprobe("x509_key_parser", NULL);
+ tst_modprobe("pkcs8_key_parser", NULL);
+
+ cert_key = add_asymmetric_key_or_tconf("cert", rsa2048_cert,
+ sizeof(rsa2048_cert),
+ "CONFIG_X509_CERTIFICATE_PARSER");
+ priv_key = add_asymmetric_key_or_tconf("priv", rsa2048_pkcs8,
+ sizeof(rsa2048_pkcs8),
+ "CONFIG_PKCS8_PRIVATE_KEY_PARSER");
+}
+
+static void run(void)
+{
+ memset(sig, 0, sizeof(sig));
+
+ memset(sign_params, 0, sizeof(*sign_params));
+ sign_params->key_id = priv_key;
+ sign_params->in_len = DIGEST_SIZE;
+ sign_params->out_len = SIG_SIZE;
+
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_PKEY_SIGN, (unsigned long)sign_params,
+ (unsigned long)"enc=pkcs1 hash=sha256",
+ (unsigned long)digest,
+ (unsigned long)sig),
+ SIG_SIZE);
+ if (!TST_PASS)
+ return;
+
+ memset(verify_params, 0, sizeof(*verify_params));
+ verify_params->key_id = cert_key;
+ verify_params->in_len = DIGEST_SIZE;
+ verify_params->in2_len = SIG_SIZE;
+
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_PKEY_VERIFY, (unsigned long)verify_params,
+ (unsigned long)"enc=pkcs1 hash=sha256",
+ (unsigned long)digest,
+ (unsigned long)sig),
+ 0);
+ if (!TST_PASS)
+ return;
+
+ tst_res(TPASS, "KEYCTL_PKEY_SIGN and KEYCTL_PKEY_VERIFY roundtrip succeeded");
+
+ memcpy(wrong_digest, digest, sizeof(wrong_digest));
+ wrong_digest[0] ^= 0xff;
+
+ TST_EXP_FAIL(keyctl(KEYCTL_PKEY_VERIFY, (unsigned long)verify_params,
+ (unsigned long)"enc=pkcs1 hash=sha256",
+ (unsigned long)wrong_digest,
+ (unsigned long)sig),
+ EKEYREJECTED,
+ "KEYCTL_PKEY_VERIFY with mismatched digest");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "4.20",
+ .needs_root = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_ASYMMETRIC_KEY_TYPE=y",
+ "CONFIG_X509_CERTIFICATE_PARSER",
+ "CONFIG_PKCS8_PRIVATE_KEY_PARSER",
+ "CONFIG_CRYPTO_RSA",
+ "CONFIG_CRYPTO_SHA256",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&sign_params, .size = sizeof(*sign_params)},
+ {&verify_params, .size = sizeof(*verify_params)},
+ {},
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 28/36] keyctl32: Test KEYCTL_PKEY_SIGN and VERIFY
2026-09-16 14:03 ` [LTP] [PATCH v3 28/36] keyctl32: Test KEYCTL_PKEY_SIGN and VERIFY Petr Vorel
@ 2026-09-18 15:25 ` Cyril Hrubis
0 siblings, 0 replies; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-18 15:25 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
> +/*\
> + * Test ``KEYCTL_PKEY_SIGN`` and ``KEYCTL_PKEY_VERIFY`` of :manpage:`keyctl(2)`.
> + *
> + * ``KEYCTL_PKEY_SIGN`` signs a digest using an asymmetric private key and
> + * ``KEYCTL_PKEY_VERIFY`` verifies the signature using the matching public key.
> + *
> + * Requires root (CAP_SYS_MODULE) to load the ``x509_key_parser`` and
> + * ``pkcs8_key_parser`` modules.
> + *
> + * [Algorithm]
> + *
> + * - sign a 32-byte digest using an RSA-2048 PKCS#8 private key with
> + * ``enc=pkcs1 hash=sha256``
> + * - verify the 256-byte signature using the matching X.509 public key
> + * - verify a mismatched digest fails verification with ``EKEYREJECTED``
> + */
> +
> +#include "keyctl_common.h"
> +#include "keyctl_pkey_data.h"
> +#include "tst_module.h"
> +
> +#define DIGEST_SIZE 32
> +#define SIG_SIZE 256
> +
> +static const unsigned char digest[DIGEST_SIZE] = {
> + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
> + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
> + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
> + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
> +};
> +
> +static unsigned char sig[SIG_SIZE];
> +static unsigned char wrong_digest[DIGEST_SIZE];
Here as well, these buffers should ideally be in the guarded buffers.
Otherwise:
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 29/36] keyctl33: Negative tests for KEYCTL_PKEY_*
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (27 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 28/36] keyctl32: Test KEYCTL_PKEY_SIGN and VERIFY Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 15:31 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 30/36] lapi/keyctl.h: Add capability fallback defines Petr Vorel
` (7 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add negative and boundary test cases for KEYCTL_PKEY_* operations
(QUERY, ENCRYPT, DECRYPT, SIGN, VERIFY), testing invalid key serials,
unsupported key types, invalid info strings, and buffer size limits.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl33.c | 247 ++++++++++++++++++++
3 files changed, 249 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl33.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 9c74b3db82..8b6dc16250 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -750,6 +750,7 @@ keyctl29 keyctl29
keyctl30 keyctl30
keyctl31 keyctl31
keyctl32 keyctl32
+keyctl33 keyctl33
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 8b1627bee3..0f209d7e07 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -30,3 +30,4 @@
/keyctl30
/keyctl31
/keyctl32
+/keyctl33
diff --git a/testcases/kernel/syscalls/keyctl/keyctl33.c b/testcases/kernel/syscalls/keyctl/keyctl33.c
new file mode 100644
index 0000000000..60404f2b16
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl33.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Negative and boundary test cases for ``KEYCTL_PKEY_*`` of :manpage:`keyctl(2)`.
+ *
+ * Requires root (CAP_SYS_MODULE) to load the ``x509_key_parser`` and
+ * ``pkcs8_key_parser`` modules.
+ *
+ * [Algorithm]
+ *
+ * - verify ``KEYCTL_PKEY_QUERY`` with non-zero ``arg3`` fails with ``EINVAL``
+ * - verify ``KEYCTL_PKEY_QUERY`` with bogus key serial fails with ``ENOKEY``
+ * - verify ``KEYCTL_PKEY_QUERY`` with non-asymmetric key fails with ``EOPNOTSUPP``
+ * - verify ``KEYCTL_PKEY_QUERY`` with invalid info string fails with ``EINVAL``
+ * - verify ``KEYCTL_PKEY_ENCRYPT`` with bogus key serial fails with ``ENOKEY``
+ * - verify ``KEYCTL_PKEY_ENCRYPT`` with non-asymmetric key fails with ``EOPNOTSUPP``
+ * - verify ``KEYCTL_PKEY_ENCRYPT`` with invalid info string fails with ``EINVAL``
+ * - verify ``KEYCTL_PKEY_ENCRYPT`` with ``in_len`` exceeding limit fails with ``EINVAL``
+ * - verify ``KEYCTL_PKEY_DECRYPT`` on public key certificate fails with ``EINVAL``
+ * - verify ``KEYCTL_PKEY_DECRYPT`` with ``in_len`` exceeding limit fails with ``EINVAL``
+ * - verify ``KEYCTL_PKEY_SIGN`` on public key certificate fails with ``EINVAL``
+ * - verify ``KEYCTL_PKEY_SIGN`` with ``in_len`` exceeding limit fails with ``EINVAL``
+ * - verify ``KEYCTL_PKEY_VERIFY`` with non-asymmetric key fails with ``EOPNOTSUPP``
+ * - verify ``KEYCTL_PKEY_VERIFY`` with ``in2_len`` exceeding limit fails with ``EINVAL``
+ */
+
+#include "keyctl_common.h"
+#include "keyctl_pkey_data.h"
+#include "tst_module.h"
+
+static key_serial_t cert_key, priv_key, user_key;
+static key_serial_t bogus_key = INT32_MAX;
+
+static struct keyctl_pkey_query *query_buf;
+static struct keyctl_pkey_params *params;
+
+static unsigned char in_buf[512];
+static unsigned char out_buf[512];
+
+static struct tcase {
+ int op;
+ key_serial_t *key;
+ unsigned long arg3;
+ const char *info;
+ uint32_t in_len;
+ uint32_t out_in2_len;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ {
+ .op = KEYCTL_PKEY_QUERY,
+ .key = &cert_key,
+ .arg3 = 1,
+ .info = "enc=pkcs1",
+ .exp_errno = EINVAL,
+ .desc = "PKEY_QUERY with non-zero arg3",
+ },
+ {
+ .op = KEYCTL_PKEY_QUERY,
+ .key = &bogus_key,
+ .info = "enc=pkcs1",
+ .exp_errno = ENOKEY,
+ .desc = "PKEY_QUERY with bogus key serial",
+ },
+ {
+ .op = KEYCTL_PKEY_QUERY,
+ .key = &user_key,
+ .info = "enc=pkcs1",
+ .exp_errno = EOPNOTSUPP,
+ .desc = "PKEY_QUERY with non-asymmetric key",
+ },
+ {
+ .op = KEYCTL_PKEY_QUERY,
+ .key = &cert_key,
+ .info = "bogus_opt",
+ .exp_errno = EINVAL,
+ .desc = "PKEY_QUERY with invalid info string",
+ },
+ {
+ .op = KEYCTL_PKEY_ENCRYPT,
+ .key = &bogus_key,
+ .info = "enc=pkcs1",
+ .in_len = 32,
+ .out_in2_len = 256,
+ .exp_errno = ENOKEY,
+ .desc = "PKEY_ENCRYPT with bogus key serial",
+ },
+ {
+ .op = KEYCTL_PKEY_ENCRYPT,
+ .key = &user_key,
+ .info = "enc=pkcs1",
+ .in_len = 32,
+ .out_in2_len = 256,
+ .exp_errno = EOPNOTSUPP,
+ .desc = "PKEY_ENCRYPT with non-asymmetric key",
+ },
+ {
+ .op = KEYCTL_PKEY_ENCRYPT,
+ .key = &cert_key,
+ .info = "invalid_info",
+ .in_len = 32,
+ .out_in2_len = 256,
+ .exp_errno = EINVAL,
+ .desc = "PKEY_ENCRYPT with invalid info string",
+ },
+ {
+ .op = KEYCTL_PKEY_ENCRYPT,
+ .key = &cert_key,
+ .info = "enc=pkcs1",
+ .in_len = 500,
+ .out_in2_len = 256,
+ .exp_errno = EINVAL,
+ .desc = "PKEY_ENCRYPT with in_len exceeding limit",
+ },
+ {
+ .op = KEYCTL_PKEY_DECRYPT,
+ .key = &cert_key,
+ .info = "enc=pkcs1",
+ .in_len = 256,
+ .out_in2_len = 256,
+ .exp_errno = EINVAL,
+ .desc = "PKEY_DECRYPT on public key certificate",
+ },
+ {
+ .op = KEYCTL_PKEY_DECRYPT,
+ .key = &priv_key,
+ .info = "enc=pkcs1",
+ .in_len = 500,
+ .out_in2_len = 256,
+ .exp_errno = EINVAL,
+ .desc = "PKEY_DECRYPT with in_len exceeding limit",
+ },
+ {
+ .op = KEYCTL_PKEY_SIGN,
+ .key = &cert_key,
+ .info = "enc=pkcs1 hash=sha256",
+ .in_len = 32,
+ .out_in2_len = 256,
+ .exp_errno = EINVAL,
+ .desc = "PKEY_SIGN on public key certificate",
+ },
+ {
+ .op = KEYCTL_PKEY_SIGN,
+ .key = &priv_key,
+ .info = "enc=pkcs1 hash=sha256",
+ .in_len = 500,
+ .out_in2_len = 256,
+ .exp_errno = EINVAL,
+ .desc = "PKEY_SIGN with in_len exceeding limit",
+ },
+ {
+ .op = KEYCTL_PKEY_VERIFY,
+ .key = &user_key,
+ .info = "enc=pkcs1 hash=sha256",
+ .in_len = 32,
+ .out_in2_len = 256,
+ .exp_errno = EOPNOTSUPP,
+ .desc = "PKEY_VERIFY with non-asymmetric key",
+ },
+ {
+ .op = KEYCTL_PKEY_VERIFY,
+ .key = &cert_key,
+ .info = "enc=pkcs1 hash=sha256",
+ .in_len = 32,
+ .out_in2_len = 500,
+ .exp_errno = EINVAL,
+ .desc = "PKEY_VERIFY with in2_len exceeding limit",
+ },
+};
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ tst_modprobe("x509_key_parser", NULL);
+ tst_modprobe("pkcs8_key_parser", NULL);
+
+ user_key = SAFE_NEW_USER_KEY("ltp_user", "data", 4,
+ KEY_SPEC_PROCESS_KEYRING);
+
+ cert_key = add_asymmetric_key_or_tconf("cert", rsa2048_cert,
+ sizeof(rsa2048_cert),
+ "CONFIG_X509_CERTIFICATE_PARSER");
+ priv_key = add_asymmetric_key_or_tconf("priv", rsa2048_pkcs8,
+ sizeof(rsa2048_pkcs8),
+ "CONFIG_PKCS8_PRIVATE_KEY_PARSER");
+}
+
+static void run(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ if (tc->op == KEYCTL_PKEY_QUERY) {
+ TST_EXP_FAIL(keyctl(KEYCTL_PKEY_QUERY, (unsigned long)*tc->key,
+ tc->arg3, (unsigned long)tc->info,
+ (unsigned long)query_buf),
+ tc->exp_errno,
+ "%s", tc->desc);
+ return;
+ }
+
+ memset(params, 0, sizeof(*params));
+ params->key_id = *tc->key;
+ params->in_len = tc->in_len;
+ params->out_len = tc->out_in2_len;
+
+ if (tc->op == KEYCTL_PKEY_VERIFY) {
+ TST_EXP_FAIL(keyctl(tc->op, (unsigned long)params,
+ (unsigned long)tc->info,
+ (unsigned long)in_buf,
+ (unsigned long)out_buf),
+ tc->exp_errno,
+ "%s", tc->desc);
+ } else {
+ TST_EXP_FAIL2(keyctl(tc->op, (unsigned long)params,
+ (unsigned long)tc->info,
+ (unsigned long)in_buf,
+ (unsigned long)out_buf),
+ tc->exp_errno,
+ "%s", tc->desc);
+ }
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "4.20",
+ .needs_root = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_ASYMMETRIC_KEY_TYPE=y",
+ "CONFIG_X509_CERTIFICATE_PARSER",
+ "CONFIG_PKCS8_PRIVATE_KEY_PARSER",
+ "CONFIG_CRYPTO_RSA",
+ "CONFIG_CRYPTO_SHA256",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&query_buf, .size = sizeof(*query_buf)},
+ {¶ms, .size = sizeof(*params)},
+ {},
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 29/36] keyctl33: Negative tests for KEYCTL_PKEY_*
2026-09-16 14:03 ` [LTP] [PATCH v3 29/36] keyctl33: Negative tests for KEYCTL_PKEY_* Petr Vorel
@ 2026-09-18 15:31 ` Cyril Hrubis
0 siblings, 0 replies; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-18 15:31 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
> +static void run(unsigned int n)
> +{
> + struct tcase *tc = &tcases[n];
> +
> + if (tc->op == KEYCTL_PKEY_QUERY) {
> + TST_EXP_FAIL(keyctl(KEYCTL_PKEY_QUERY, (unsigned long)*tc->key,
> + tc->arg3, (unsigned long)tc->info,
> + (unsigned long)query_buf),
> + tc->exp_errno,
> + "%s", tc->desc);
> + return;
> + }
> +
> + memset(params, 0, sizeof(*params));
> + params->key_id = *tc->key;
> + params->in_len = tc->in_len;
> + params->out_len = tc->out_in2_len;
> +
> + if (tc->op == KEYCTL_PKEY_VERIFY) {
> + TST_EXP_FAIL(keyctl(tc->op, (unsigned long)params,
> + (unsigned long)tc->info,
> + (unsigned long)in_buf,
> + (unsigned long)out_buf),
> + tc->exp_errno,
> + "%s", tc->desc);
> + } else {
> + TST_EXP_FAIL2(keyctl(tc->op, (unsigned long)params,
> + (unsigned long)tc->info,
> + (unsigned long)in_buf,
> + (unsigned long)out_buf),
> + tc->exp_errno,
> + "%s", tc->desc);
> + }
Well I would have coded this part a bit more tidily:
switch (tc->op) {
case KEYCTL_PKEY_QUERY:
verify_pkey_query(tc);
break;
case KEYCTL_PKEY_VERIFY:
verify_pkey_verify(tc);
break;
default:
verify_pkey(tc);
break;
}
And moved the code into separate functions, no functional changes, just
a bit nicer flow.
Otherwise:
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 30/36] lapi/keyctl.h: Add capability fallback defines
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (28 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 29/36] keyctl33: Negative tests for KEYCTL_PKEY_* Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 15:32 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 31/36] keyctl34: Test KEYCTL_CAPABILITIES flag retrieval Petr Vorel
` (6 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add fallback definitions for KEYCTL_CAPABILITIES, KEYCTL_CAPS0_*,
and KEYCTL_CAPS1_* constants, and update safe_keyctl to handle
KEYCTL_CAPABILITIES.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
include/lapi/keyctl.h | 49 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/include/lapi/keyctl.h b/include/lapi/keyctl.h
index fdb68d1725..473616bd51 100644
--- a/include/lapi/keyctl.h
+++ b/include/lapi/keyctl.h
@@ -226,6 +226,10 @@ struct keyctl_pkey_params {
# define KEYCTL_MOVE_EXCL 0x00000001 /* do not displace from the to-keyring */
#endif
+#ifndef KEYCTL_CAPABILITIES
+# define KEYCTL_CAPABILITIES 31
+#endif
+
#ifndef KEYCTL_PKEY_QUERY
# define KEYCTL_PKEY_QUERY 24
#endif
@@ -253,6 +257,50 @@ struct keyctl_pkey_params {
# define KEYCTL_SUPPORTS_VERIFY 0x08
#endif
+#ifndef KEYCTL_CAPS0_CAPABILITIES
+# define KEYCTL_CAPS0_CAPABILITIES 0x01
+#endif
+
+#ifndef KEYCTL_CAPS0_PERSISTENT_KEYRINGS
+# define KEYCTL_CAPS0_PERSISTENT_KEYRINGS 0x02
+#endif
+
+#ifndef KEYCTL_CAPS0_DIFFIE_HELLMAN
+# define KEYCTL_CAPS0_DIFFIE_HELLMAN 0x04
+#endif
+
+#ifndef KEYCTL_CAPS0_PUBLIC_KEY
+# define KEYCTL_CAPS0_PUBLIC_KEY 0x08
+#endif
+
+#ifndef KEYCTL_CAPS0_BIG_KEY
+# define KEYCTL_CAPS0_BIG_KEY 0x10
+#endif
+
+#ifndef KEYCTL_CAPS0_INVALIDATE
+# define KEYCTL_CAPS0_INVALIDATE 0x20
+#endif
+
+#ifndef KEYCTL_CAPS0_RESTRICT_KEYRING
+# define KEYCTL_CAPS0_RESTRICT_KEYRING 0x40
+#endif
+
+#ifndef KEYCTL_CAPS0_MOVE
+# define KEYCTL_CAPS0_MOVE 0x80
+#endif
+
+#ifndef KEYCTL_CAPS1_NS_KEYRING_NAME
+# define KEYCTL_CAPS1_NS_KEYRING_NAME 0x01
+#endif
+
+#ifndef KEYCTL_CAPS1_NS_KEY_TAG
+# define KEYCTL_CAPS1_NS_KEY_TAG 0x02
+#endif
+
+#ifndef KEYCTL_CAPS1_NOTIFICATIONS
+# define KEYCTL_CAPS1_NOTIFICATIONS 0x04
+#endif
+
/* key permissions */
#ifndef KEY_POS_VIEW
# define KEY_POS_VIEW 0x01000000
@@ -318,6 +366,7 @@ static inline long safe_keyctl(const char *file, const int lineno,
case KEYCTL_PKEY_DECRYPT:
case KEYCTL_PKEY_SIGN:
case KEYCTL_PKEY_VERIFY:
+ case KEYCTL_CAPABILITIES:
if (rval < 0)
failure = 1;
break;
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 31/36] keyctl34: Test KEYCTL_CAPABILITIES flag retrieval
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (29 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 30/36] lapi/keyctl.h: Add capability fallback defines Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 15:36 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 32/36] keyctl35: Test KEYCTL_CAPABILITIES size query Petr Vorel
` (5 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test keyrings subsystem capabilities retrieval with KEYCTL_CAPABILITIES
and verify standard capability bits (CAPABILITIES, INVALIDATE,
RESTRICT_KEYRING, MOVE, NS_KEYRING_NAME, NS_KEY_TAG).
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_KEYCTL() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl34.c | 61 +++++++++++++++++++++
3 files changed, 63 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl34.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 8b6dc16250..e5450ff173 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -751,6 +751,7 @@ keyctl30 keyctl30
keyctl31 keyctl31
keyctl32 keyctl32
keyctl33 keyctl33
+keyctl34 keyctl34
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 0f209d7e07..f2ce330d77 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -31,3 +31,4 @@
/keyctl31
/keyctl32
/keyctl33
+/keyctl34
diff --git a/testcases/kernel/syscalls/keyctl/keyctl34.c b/testcases/kernel/syscalls/keyctl/keyctl34.c
new file mode 100644
index 0000000000..3285aa467f
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl34.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_CAPABILITIES`` of :manpage:`keyctl(2)`, added in Linux 5.3.
+ *
+ * ``KEYCTL_CAPABILITIES`` retrieves the bitmask of features and capabilities
+ * supported by the keyrings subsystem in the running kernel.
+ *
+ * [Algorithm]
+ *
+ * - retrieve keyrings subsystem capabilities into a buffer
+ * - verify return value is at least 2 bytes
+ * - verify standard capability bits ``KEYCTL_CAPS0_CAPABILITIES``,
+ * ``KEYCTL_CAPS0_INVALIDATE``, ``KEYCTL_CAPS0_RESTRICT_KEYRING``,
+ * ``KEYCTL_CAPS0_MOVE``, ``KEYCTL_CAPS1_NS_KEYRING_NAME``, and
+ * ``KEYCTL_CAPS1_NS_KEY_TAG`` are set
+ */
+
+#include "keyctl_common.h"
+
+static unsigned char caps[8];
+
+static void run(void)
+{
+ int rc;
+
+ memset(caps, 0, sizeof(caps));
+
+ rc = SAFE_KEYCTL(KEYCTL_CAPABILITIES, (unsigned long)caps, sizeof(caps), 0, 0);
+
+ if (rc < 2) {
+ tst_res(TFAIL, "KEYCTL_CAPABILITIES returned %d, expected at least 2", rc);
+ return;
+ }
+
+ TST_EXP_EXPR(caps[0] & KEYCTL_CAPS0_CAPABILITIES,
+ "KEYCTL_CAPS0_CAPABILITIES is set");
+ TST_EXP_EXPR(caps[0] & KEYCTL_CAPS0_INVALIDATE,
+ "KEYCTL_CAPS0_INVALIDATE is set");
+ TST_EXP_EXPR(caps[0] & KEYCTL_CAPS0_RESTRICT_KEYRING,
+ "KEYCTL_CAPS0_RESTRICT_KEYRING is set");
+ TST_EXP_EXPR(caps[0] & KEYCTL_CAPS0_MOVE,
+ "KEYCTL_CAPS0_MOVE is set");
+
+ TST_EXP_EXPR(caps[1] & KEYCTL_CAPS1_NS_KEYRING_NAME,
+ "KEYCTL_CAPS1_NS_KEYRING_NAME is set");
+ TST_EXP_EXPR(caps[1] & KEYCTL_CAPS1_NS_KEY_TAG,
+ "KEYCTL_CAPS1_NS_KEY_TAG is set");
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .min_kver = "5.3",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ NULL
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 32/36] keyctl35: Test KEYCTL_CAPABILITIES size query
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (30 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 31/36] keyctl34: Test KEYCTL_CAPABILITIES flag retrieval Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 15:37 ` Cyril Hrubis
2026-09-16 14:03 ` [LTP] [PATCH v3 33/36] keyctl36: Test KEYCTL_CAPABILITIES buffer sizing Petr Vorel
` (4 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test that calling KEYCTL_CAPABILITIES with a NULL buffer and
buflen of 0 returns the total size in bytes of the keyrings
subsystem capability array without faulting.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_KEYCTL() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl35.c | 46 +++++++++++++++++++++
3 files changed, 48 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl35.c
diff --git a/runtest/syscalls b/runtest/syscalls
index e5450ff173..55299bd7c0 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -752,6 +752,7 @@ keyctl31 keyctl31
keyctl32 keyctl32
keyctl33 keyctl33
keyctl34 keyctl34
+keyctl35 keyctl35
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index f2ce330d77..58ebb452fa 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -32,3 +32,4 @@
/keyctl32
/keyctl33
/keyctl34
+/keyctl35
diff --git a/testcases/kernel/syscalls/keyctl/keyctl35.c b/testcases/kernel/syscalls/keyctl/keyctl35.c
new file mode 100644
index 0000000000..cc0054813e
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl35.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_CAPABILITIES`` size query of :manpage:`keyctl(2)`, added in Linux 5.3.
+ *
+ * [Algorithm]
+ *
+ * - call ``KEYCTL_CAPABILITIES`` with NULL buffer and ``buflen = 0``
+ * - verify the return value is at least 2 bytes
+ * - verify calling ``KEYCTL_CAPABILITIES`` with a valid buffer returns the
+ * same size
+ */
+
+#include "keyctl_common.h"
+
+static unsigned char buf[8];
+
+static void run(void)
+{
+ int size;
+
+ size = SAFE_KEYCTL(KEYCTL_CAPABILITIES, (unsigned long)NULL, 0, 0, 0);
+
+ if (size < 2) {
+ tst_res(TFAIL, "KEYCTL_CAPABILITIES size query returned %d, expected >= 2",
+ size);
+ return;
+ }
+
+ tst_res(TPASS, "KEYCTL_CAPABILITIES size query returned %d", size);
+
+ TST_EXP_VAL(keyctl(KEYCTL_CAPABILITIES, (unsigned long)buf, sizeof(buf), 0, 0),
+ size);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .min_kver = "5.3",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ NULL
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 33/36] keyctl36: Test KEYCTL_CAPABILITIES buffer sizing
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (31 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 32/36] keyctl35: Test KEYCTL_CAPABILITIES size query Petr Vorel
@ 2026-09-16 14:03 ` Petr Vorel
2026-09-18 15:44 ` Cyril Hrubis
2026-09-16 14:04 ` [LTP] [PATCH v3 34/36] keyctl37: Negative tests for KEYCTL_CAPABILITIES Petr Vorel
` (3 subsequent siblings)
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_CAPABILITIES with short buffer (verifying partial copy
without overrun) and oversized buffer (verifying trailing space is
zero-filled while returning the full capability length).
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_KEYCTL() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl36.c | 84 +++++++++++++++++++++
3 files changed, 86 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl36.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 55299bd7c0..f42303345e 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -753,6 +753,7 @@ keyctl32 keyctl32
keyctl33 keyctl33
keyctl34 keyctl34
keyctl35 keyctl35
+keyctl36 keyctl36
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 58ebb452fa..a4da8ae805 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -33,3 +33,4 @@
/keyctl33
/keyctl34
/keyctl35
+/keyctl36
diff --git a/testcases/kernel/syscalls/keyctl/keyctl36.c b/testcases/kernel/syscalls/keyctl/keyctl36.c
new file mode 100644
index 0000000000..4f0cb70378
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl36.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_CAPABILITIES`` buffer sizing and padding of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - verify a 1-byte buffer receives 1 byte while the full size is returned
+ * and canary bytes beyond 1 byte remain untouched
+ * - verify an oversized buffer is zero-filled beyond the capability size
+ */
+
+#include "keyctl_common.h"
+
+#define CANARY 0xaa
+#define OVERSIZE 16
+
+static long caps_len;
+static unsigned char short_buf[4];
+static unsigned char large_buf[OVERSIZE];
+
+static void setup(void)
+{
+ caps_len = SAFE_KEYCTL(KEYCTL_CAPABILITIES, (unsigned long)NULL, 0, 0, 0);
+}
+
+static void run(void)
+{
+ size_t i;
+ int zero_padded = 1;
+
+ memset(short_buf, CANARY, sizeof(short_buf));
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_CAPABILITIES,
+ (unsigned long)short_buf, 1, 0, 0),
+ caps_len);
+ if (!TST_PASS)
+ return;
+
+ if (short_buf[0] == CANARY) {
+ tst_res(TFAIL, "short buffer was not populated");
+ return;
+ }
+
+ for (i = 1; i < sizeof(short_buf); i++) {
+ if (short_buf[i] != CANARY) {
+ tst_res(TFAIL, "copy overran short buffer at offset %zu", i);
+ return;
+ }
+ }
+
+ tst_res(TPASS, "short buffer copied 1 byte without overrun");
+
+ memset(large_buf, CANARY, sizeof(large_buf));
+ TST_EXP_EQ_LI_SILENT(keyctl(KEYCTL_CAPABILITIES,
+ (unsigned long)large_buf, sizeof(large_buf), 0, 0),
+ caps_len);
+ if (!TST_PASS)
+ return;
+
+ for (i = caps_len; i < sizeof(large_buf); i++) {
+ if (large_buf[i] != 0) {
+ zero_padded = 0;
+ break;
+ }
+ }
+
+ if (!zero_padded)
+ tst_res(TFAIL, "oversized buffer was not zero-filled at offset %zu", i);
+ else
+ tst_res(TPASS, "oversized buffer zero-filled trailing space");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "5.3",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ NULL
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 34/36] keyctl37: Negative tests for KEYCTL_CAPABILITIES
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (32 preceding siblings ...)
2026-09-16 14:03 ` [LTP] [PATCH v3 33/36] keyctl36: Test KEYCTL_CAPABILITIES buffer sizing Petr Vorel
@ 2026-09-16 14:04 ` Petr Vorel
2026-09-16 14:04 ` [LTP] [PATCH v3 35/36] keyctl38: Test KEYCTL_WATCH_KEY add and remove Petr Vorel
` (2 subsequent siblings)
36 siblings, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:04 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add negative test cases for KEYCTL_CAPABILITIES verifying that
passing a NULL buffer with a non-zero length or an invalid buffer
pointer fails with EFAULT.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl37.c | 63 +++++++++++++++++++++
3 files changed, 65 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl37.c
diff --git a/runtest/syscalls b/runtest/syscalls
index f42303345e..e9a31a1947 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -754,6 +754,7 @@ keyctl33 keyctl33
keyctl34 keyctl34
keyctl35 keyctl35
keyctl36 keyctl36
+keyctl37 keyctl37
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index a4da8ae805..7ee6b90989 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -34,3 +34,4 @@
/keyctl34
/keyctl35
/keyctl36
+/keyctl37
diff --git a/testcases/kernel/syscalls/keyctl/keyctl37.c b/testcases/kernel/syscalls/keyctl/keyctl37.c
new file mode 100644
index 0000000000..08d1db03b8
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl37.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Negative test cases for ``KEYCTL_CAPABILITIES`` of :manpage:`keyctl(2)`.
+ *
+ * [Algorithm]
+ *
+ * - verify ``KEYCTL_CAPABILITIES`` with NULL buffer and ``buflen > 0`` fails with ``EFAULT``
+ * - verify ``KEYCTL_CAPABILITIES`` with invalid pointer fails with ``EFAULT``
+ */
+
+#include "keyctl_common.h"
+
+static void *bad_addr;
+
+static struct tcase {
+ void **buf;
+ size_t buflen;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ {
+ .buf = NULL,
+ .buflen = 1,
+ .exp_errno = EFAULT,
+ .desc = "NULL buffer with non-zero buflen",
+ },
+ {
+ .buf = &bad_addr,
+ .buflen = 1,
+ .exp_errno = EFAULT,
+ .desc = "invalid buffer pointer",
+ },
+};
+
+static void setup(void)
+{
+ bad_addr = tst_get_bad_addr(NULL);
+}
+
+static void run(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+ void *p = tc->buf ? *tc->buf : NULL;
+
+ TST_EXP_FAIL2(keyctl(KEYCTL_CAPABILITIES, (unsigned long)p, tc->buflen, 0, 0),
+ tc->exp_errno,
+ "%s", tc->desc);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "5.3",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ NULL
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* [LTP] [PATCH v3 35/36] keyctl38: Test KEYCTL_WATCH_KEY add and remove
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (33 preceding siblings ...)
2026-09-16 14:04 ` [LTP] [PATCH v3 34/36] keyctl37: Negative tests for KEYCTL_CAPABILITIES Petr Vorel
@ 2026-09-16 14:04 ` Petr Vorel
2026-09-18 15:53 ` Cyril Hrubis
2026-09-16 14:04 ` [LTP] [PATCH v3 36/36] keyctl39: Negative tests for KEYCTL_WATCH_KEY Petr Vorel
2026-09-17 10:11 ` [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Li Wang
36 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:04 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Test KEYCTL_WATCH_KEY by opening a watch queue notification pipe
and adding then removing watches on both a user key and the
session keyring.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl38.c | 91 +++++++++++++++++++++
3 files changed, 93 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl38.c
diff --git a/runtest/syscalls b/runtest/syscalls
index e9a31a1947..b5abadad87 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -755,6 +755,7 @@ keyctl34 keyctl34
keyctl35 keyctl35
keyctl36 keyctl36
keyctl37 keyctl37
+keyctl38 keyctl38
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index 7ee6b90989..c0a18dd77b 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -35,3 +35,4 @@
/keyctl35
/keyctl36
/keyctl37
+/keyctl38
diff --git a/testcases/kernel/syscalls/keyctl/keyctl38.c b/testcases/kernel/syscalls/keyctl/keyctl38.c
new file mode 100644
index 0000000000..4cf9a5b9f5
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl38.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test ``KEYCTL_WATCH_KEY`` of :manpage:`keyctl(2)`, added in Linux 5.8.
+ *
+ * ``KEYCTL_WATCH_KEY`` adds or removes a watch on a key or keyring to/from
+ * a watch queue notification pipe.
+ *
+ * [Algorithm]
+ *
+ * - open a notification pipe via :manpage:`pipe2()` with
+ * ``O_NOTIFICATION_PIPE``
+ * - add a watch on a key with ``watch_id = 1`` and verify success
+ * - remove the watch on the key with ``watch_id = -1`` and verify success
+ * - add a watch on a keyring with ``watch_id = 2`` and verify success
+ * - remove the watch on the keyring with ``watch_id = -1`` and verify success
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/resource.h>
+#include <unistd.h>
+#include "keyctl_common.h"
+#include "lapi/watch_queue.h"
+
+static key_serial_t key;
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key = SAFE_NEW_USER_KEY("ltpkeyctl38", "payload", 7,
+ KEY_SPEC_PROCESS_KEYRING);
+}
+
+static void run(void)
+{
+ int pipefd[2];
+
+ TEST(pipe2(pipefd, O_NOTIFICATION_PIPE));
+ if (TST_RET < 0) {
+ if (TST_ERR == ENOPKG)
+ tst_brk(TCONF | TTERRNO, "CONFIG_WATCH_QUEUE is not set");
+ if (TST_ERR == EINVAL)
+ tst_brk(TCONF | TTERRNO, "O_NOTIFICATION_PIPE is not supported");
+ tst_brk(TBROK | TTERRNO, "pipe2(O_NOTIFICATION_PIPE) failed");
+ }
+
+ SAFE_IOCTL(pipefd[0], IOC_WATCH_QUEUE_SET_SIZE, 256);
+
+ TST_EXP_PASS(keyctl(KEYCTL_WATCH_KEY, key, pipefd[0], 1),
+ "KEYCTL_WATCH_KEY add watch on key");
+
+ TST_EXP_PASS(keyctl(KEYCTL_WATCH_KEY, key, pipefd[0], -1),
+ "KEYCTL_WATCH_KEY remove watch on key");
+
+ TST_EXP_PASS(keyctl(KEYCTL_WATCH_KEY, KEY_SPEC_SESSION_KEYRING,
+ pipefd[0], 2),
+ "KEYCTL_WATCH_KEY add watch on session keyring");
+
+ TST_EXP_PASS(keyctl(KEYCTL_WATCH_KEY, KEY_SPEC_SESSION_KEYRING,
+ pipefd[0], -1),
+ "KEYCTL_WATCH_KEY remove watch on session keyring");
+
+ SAFE_CLOSE(pipefd[0]);
+ SAFE_CLOSE(pipefd[1]);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .min_kver = "5.8",
+ /*
+ * add_one_watch() charges per-user watches against RLIMIT_NOFILE,
+ * so raise the limit high enough to accommodate pre-existing
+ * watches on the calling user.
+ */
+ .ulimit = (const struct tst_ulimit_val []) {
+ {RLIMIT_NOFILE, 524288},
+ {}
+ },
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_KEY_NOTIFICATIONS=y",
+ "CONFIG_WATCH_QUEUE=y",
+ NULL
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 35/36] keyctl38: Test KEYCTL_WATCH_KEY add and remove
2026-09-16 14:04 ` [LTP] [PATCH v3 35/36] keyctl38: Test KEYCTL_WATCH_KEY add and remove Petr Vorel
@ 2026-09-18 15:53 ` Cyril Hrubis
0 siblings, 0 replies; 79+ messages in thread
From: Cyril Hrubis @ 2026-09-18 15:53 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
> +static void run(void)
> +{
> + int pipefd[2];
> +
> + TEST(pipe2(pipefd, O_NOTIFICATION_PIPE));
> + if (TST_RET < 0) {
> + if (TST_ERR == ENOPKG)
> + tst_brk(TCONF | TTERRNO, "CONFIG_WATCH_QUEUE is not set");
> + if (TST_ERR == EINVAL)
> + tst_brk(TCONF | TTERRNO, "O_NOTIFICATION_PIPE is not supported");
> + tst_brk(TBROK | TTERRNO, "pipe2(O_NOTIFICATION_PIPE) failed");
> + }
> +
> + SAFE_IOCTL(pipefd[0], IOC_WATCH_QUEUE_SET_SIZE, 256);
> +
> + TST_EXP_PASS(keyctl(KEYCTL_WATCH_KEY, key, pipefd[0], 1),
> + "KEYCTL_WATCH_KEY add watch on key");
> +
> + TST_EXP_PASS(keyctl(KEYCTL_WATCH_KEY, key, pipefd[0], -1),
> + "KEYCTL_WATCH_KEY remove watch on key");
> +
> + TST_EXP_PASS(keyctl(KEYCTL_WATCH_KEY, KEY_SPEC_SESSION_KEYRING,
> + pipefd[0], 2),
> + "KEYCTL_WATCH_KEY add watch on session keyring");
> +
> + TST_EXP_PASS(keyctl(KEYCTL_WATCH_KEY, KEY_SPEC_SESSION_KEYRING,
> + pipefd[0], -1),
> + "KEYCTL_WATCH_KEY remove watch on session keyring");
> +
> + SAFE_CLOSE(pipefd[0]);
> + SAFE_CLOSE(pipefd[1]);
I guess that this test is pretty much incomplete, we should actually do
something with the key, i.e. set key attributes and then check that the
notification pipe got the right event.
So I would skip the notification pipe tests for the release, there is
quite a lot of missing features here.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* [LTP] [PATCH v3 36/36] keyctl39: Negative tests for KEYCTL_WATCH_KEY
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (34 preceding siblings ...)
2026-09-16 14:04 ` [LTP] [PATCH v3 35/36] keyctl38: Test KEYCTL_WATCH_KEY add and remove Petr Vorel
@ 2026-09-16 14:04 ` Petr Vorel
2026-09-17 10:11 ` [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Li Wang
36 siblings, 0 replies; 79+ messages in thread
From: Petr Vorel @ 2026-09-16 14:04 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add negative test cases for KEYCTL_WATCH_KEY verifying invalid
watch_id values, bogus key ids, missing View permission, invalid
file descriptors, non-watch-queue pipes, and removal of watches
on unwatched keys.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
[ pvorel: use SAFE_NEW_USER_KEY() ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/keyctl/.gitignore | 1 +
testcases/kernel/syscalls/keyctl/keyctl39.c | 149 ++++++++++++++++++++
3 files changed, 151 insertions(+)
create mode 100644 testcases/kernel/syscalls/keyctl/keyctl39.c
diff --git a/runtest/syscalls b/runtest/syscalls
index b5abadad87..f721962f85 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -756,6 +756,7 @@ keyctl35 keyctl35
keyctl36 keyctl36
keyctl37 keyctl37
keyctl38 keyctl38
+keyctl39 keyctl39
kcmp01 kcmp01
kcmp02 kcmp02
diff --git a/testcases/kernel/syscalls/keyctl/.gitignore b/testcases/kernel/syscalls/keyctl/.gitignore
index c0a18dd77b..8de3d46c25 100644
--- a/testcases/kernel/syscalls/keyctl/.gitignore
+++ b/testcases/kernel/syscalls/keyctl/.gitignore
@@ -36,3 +36,4 @@
/keyctl36
/keyctl37
/keyctl38
+/keyctl39
diff --git a/testcases/kernel/syscalls/keyctl/keyctl39.c b/testcases/kernel/syscalls/keyctl/keyctl39.c
new file mode 100644
index 0000000000..3df17911ff
--- /dev/null
+++ b/testcases/kernel/syscalls/keyctl/keyctl39.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Negative test cases for ``KEYCTL_WATCH_KEY`` of :manpage:`keyctl(2)`.
+ *
+ * Verify ``KEYCTL_WATCH_KEY``
+ *
+ * - with ``watch_id < -1`` fails with ``EINVAL``
+ * - with ``watch_id > 255`` fails with ``EINVAL``
+ * - with bogus key id fails with ``ENOKEY``
+ * - without View permission fails with ``EACCES``
+ * - with invalid fd fails with ``EINVAL``
+ * - with non-watch-queue fd fails with ``EINVAL``
+ * - remove on unwatched key fails with ``EBADSLT``
+ */
+
+#define _GNU_SOURCE
+
+#include <unistd.h>
+#include "keyctl_common.h"
+#include "lapi/watch_queue.h"
+
+static key_serial_t key_valid;
+static key_serial_t key_no_view;
+static key_serial_t bogus_key = INT32_MAX;
+static int wqueue_pipefd[2] = {-1, -1};
+static int plain_pipefd[2] = {-1, -1};
+static int bad_fd = -1;
+
+static struct tcase {
+ key_serial_t *key;
+ int *fd;
+ int watch_id;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ {
+ .key = &key_valid,
+ .fd = &wqueue_pipefd[0],
+ .watch_id = -2,
+ .exp_errno = EINVAL,
+ .desc = "watch_id < -1",
+ },
+ {
+ .key = &key_valid,
+ .fd = &wqueue_pipefd[0],
+ .watch_id = 256,
+ .exp_errno = EINVAL,
+ .desc = "watch_id > 255",
+ },
+ {
+ .key = &bogus_key,
+ .fd = &wqueue_pipefd[0],
+ .watch_id = 1,
+ .exp_errno = ENOKEY,
+ .desc = "bogus key id",
+ },
+ {
+ .key = &key_no_view,
+ .fd = &wqueue_pipefd[0],
+ .watch_id = 1,
+ .exp_errno = EACCES,
+ .desc = "key without View permission",
+ },
+ {
+ .key = &key_valid,
+ .fd = &bad_fd,
+ .watch_id = 1,
+ .exp_errno = EINVAL,
+ .desc = "invalid fd",
+ },
+ {
+ .key = &key_valid,
+ .fd = &plain_pipefd[0],
+ .watch_id = 1,
+ .exp_errno = EINVAL,
+ .desc = "non-watch-queue fd",
+ },
+ {
+ .key = &key_valid,
+ .fd = &wqueue_pipefd[0],
+ .watch_id = -1,
+ .exp_errno = EBADSLT,
+ .desc = "remove watch on unwatched key",
+ },
+};
+
+static void setup(void)
+{
+ SAFE_KEYCTL(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
+
+ key_valid = SAFE_NEW_USER_KEY("ltpkeyctl39_valid", "data", 4,
+ KEY_SPEC_PROCESS_KEYRING);
+
+ key_no_view = SAFE_NEW_USER_KEY("ltpkeyctl39_noview", "data", 4,
+ KEY_SPEC_PROCESS_KEYRING);
+ SAFE_KEYCTL(KEYCTL_SETPERM, key_no_view, KEY_PERM_NO_VIEW, 0, 0);
+
+ TEST(pipe2(wqueue_pipefd, O_NOTIFICATION_PIPE));
+ if (TST_RET < 0) {
+ if (TST_ERR == ENOPKG)
+ tst_brk(TCONF | TTERRNO, "CONFIG_WATCH_QUEUE is not set");
+ if (TST_ERR == EINVAL)
+ tst_brk(TCONF | TTERRNO, "O_NOTIFICATION_PIPE is not supported");
+ tst_brk(TBROK | TTERRNO, "pipe2(O_NOTIFICATION_PIPE) failed");
+ }
+
+ SAFE_IOCTL(wqueue_pipefd[0], IOC_WATCH_QUEUE_SET_SIZE, 256);
+
+ SAFE_PIPE(plain_pipefd);
+}
+
+static void cleanup(void)
+{
+ if (wqueue_pipefd[0] != -1)
+ SAFE_CLOSE(wqueue_pipefd[0]);
+ if (wqueue_pipefd[1] != -1)
+ SAFE_CLOSE(wqueue_pipefd[1]);
+ if (plain_pipefd[0] != -1)
+ SAFE_CLOSE(plain_pipefd[0]);
+ if (plain_pipefd[1] != -1)
+ SAFE_CLOSE(plain_pipefd[1]);
+}
+
+static void run(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ TST_EXP_FAIL(keyctl(KEYCTL_WATCH_KEY, *tc->key, *tc->fd, tc->watch_id),
+ tc->exp_errno,
+ "%s", tc->desc);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "5.8",
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_KEYS=y",
+ "CONFIG_KEY_NOTIFICATIONS=y",
+ "CONFIG_WATCH_QUEUE=y",
+ NULL
+ },
+};
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall
2026-09-16 14:03 [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Petr Vorel
` (35 preceding siblings ...)
2026-09-16 14:04 ` [LTP] [PATCH v3 36/36] keyctl39: Negative tests for KEYCTL_WATCH_KEY Petr Vorel
@ 2026-09-17 10:11 ` Li Wang
2026-09-18 14:39 ` Petr Vorel
36 siblings, 1 reply; 79+ messages in thread
From: Li Wang @ 2026-09-17 10:11 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
For the patchset:
Tested-by: Li Wang <li.wang@linux.dev>
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread* Re: [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall
2026-09-17 10:11 ` [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall Li Wang
@ 2026-09-18 14:39 ` Petr Vorel
2026-09-19 0:18 ` Li Wang
0 siblings, 1 reply; 79+ messages in thread
From: Petr Vorel @ 2026-09-18 14:39 UTC (permalink / raw)
To: ltp, Cyril Hrubis, Andrea Cervesato, Li Wang
Hi Li,
> For the patchset:
> Tested-by: Li Wang <li.wang@linux.dev>
thanks for your testing (I also did some).
I'm going to apply fixes you suggested and merge.
Can I add your RBT before merge (whole patchset or please specify where add or
not add)? Obviously you did a lot of review on this patchset.
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [LTP] [PATCH v3 00/36] Improve coverage for keyctl() syscall
2026-09-18 14:39 ` Petr Vorel
@ 2026-09-19 0:18 ` Li Wang
0 siblings, 0 replies; 79+ messages in thread
From: Li Wang @ 2026-09-19 0:18 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Sent from my iPhone
> On 18 Sep 2026, at 22:39, Petr Vorel <pvorel@suse.cz> wrote:
>
> Hi Li,
>
>> For the patchset:
>
>> Tested-by: Li Wang <li.wang@linux.dev>
>
> thanks for your testing (I also did some).
>
> I'm going to apply fixes you suggested and merge.
>
> Can I add your RBT before merge (whole patchset or please specify where add or
> not add)? Obviously you did a lot of review on this patchset.
Sure. ACK for the whole patchset.
>
> Kind regards,
> Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 79+ messages in thread