All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
@ 2026-10-18  1:28 Pablo Alessandro Santos Hugen
  2026-10-19 17:11 ` Stephen Smalley
  2026-10-20 18:06 ` [PATCH v2] " Pablo Alessandro Santos Hugen
  0 siblings, 2 replies; 5+ messages in thread
From: Pablo Alessandro Santos Hugen @ 2026-10-18  1:28 UTC (permalink / raw)
  To: selinux

Since 32f07cc40c9b ("crypto: dh - disallow plain "dh" usage in
FIPS mode") landed in linux 5.18, plain "dh" is disallowed in
FIPS mode per SP800-56Arev3. As noted in the commit:

> This change will effectively render the
> keyctl(KEYCTL_DH_COMPUTE) syscall unusable in FIPS mode, but
> it has been brought up that this might even be a good thing
> ([1])."
>
> [1] https://lore.kernel.org/r/20211217055227.GA20698@gondor.apana.org.au

keyctl(KEYCTL_DH_COMPUTE) returns ENOENT in FIPS mode.

So, this patch treat ENOENT and ENOSYS as non-fatal in
keyctl.c (because the operation is unavailable, not denied by
policy). SELinux denials (EACCES) still exit 9. Skip
test_key_no_read_t in FIPS mode since KEYCTL_DH_COMPUTE is
the only operation requiring key { read }.

Fixes: 2d7aad8a1f8c ("selinux-testsuite: Add keys tests")
Signed-off-by: Pablo Alessandro Santos Hugen <phugen@redhat.com>
---
 tests/keys/keyctl.c       | 15 ++++++++++-----
 tests/keys/request_keys.c | 15 ++++++++++-----
 tests/keys/test           | 21 +++++++++++++++------
 3 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/tests/keys/keyctl.c b/tests/keys/keyctl.c
index e13c655..261c00a 100644
--- a/tests/keys/keyctl.c
+++ b/tests/keys/keyctl.c
@@ -142,12 +142,17 @@ int main(int argc, char *argv[])
 	/* Requires key { create read write } */
 	compute = keyctl(KEYCTL_DH_COMPUTE, &params, NULL, 0, 0);
 	if (compute < 0) {
-		fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
-			strerror(errno));
-		exit(9);
-	}
-	if (verbose)
+		if (errno == ENOENT || errno == ENOSYS) {
+			if (verbose)
+				printf("KEYCTL_DH_COMPUTE not available, skipping\n");
+		} else {
+			fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
+				strerror(errno));
+			exit(9);
+		}
+	} else if (verbose) {
 		printf("KEYCTL_DH_COMPUTE key ID size: %d\n", compute);
+	}
 
 	/* Requires key { write link } */
 	link = keyctl(KEYCTL_LINK, base, KEY_SPEC_PROCESS_KEYRING);
diff --git a/tests/keys/request_keys.c b/tests/keys/request_keys.c
index 43b20d9..7cf7cd0 100644
--- a/tests/keys/request_keys.c
+++ b/tests/keys/request_keys.c
@@ -127,12 +127,17 @@ int main(int argc, char **argv)
 	/* Requires key { read write } */
 	compute = keyctl(KEYCTL_DH_COMPUTE, &params, NULL, 0, 0);
 	if (compute < 0) {
-		fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
-			strerror(errno));
-		exit(8);
-	}
-	if (verbose)
+		if (errno == ENOENT || errno == ENOSYS) {
+			if (verbose)
+				printf("\tKEYCTL_DH_COMPUTE not available, skipping\n");
+		} else {
+			fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
+				strerror(errno));
+			exit(8);
+		}
+	} else if (verbose) {
 		printf("\tKEYCTL_DH_COMPUTE key ID size: %d\n", compute);
+	}
 
 	exit(0);
 }
diff --git a/tests/keys/test b/tests/keys/test
index 061bc62..9e50633 100755
--- a/tests/keys/test
+++ b/tests/keys/test
@@ -29,6 +29,9 @@ BEGIN {
         $test_link_53 = 1;
     }
 
+    # KEYCTL_DH_COMPUTE is disabled in FIPS mode
+    chomp( $fips = `cat /proc/sys/crypto/fips_enabled 2>/dev/null` );
+    $skip_dh = ( $fips eq "1" ) ? 1 : 0;
     plan tests => $test_count;
 }
 
@@ -51,8 +54,11 @@ ok( $result >> 8 eq 6 );
 $result = system "runcon -t test_key_no_view_t $basedir/keyctl $v 2>&1";
 ok( $result >> 8 eq 8 );
 
-$result = system "runcon -t test_key_no_read_t $basedir/keyctl $v 2>&1";
-ok( $result >> 8 eq 9 );
+SKIP: {
+    skip( "KEYCTL_DH_COMPUTE unavailable in FIPS mode", 1 ) if $skip_dh;
+    $result = system "runcon -t test_key_no_read_t $basedir/keyctl $v 2>&1";
+    ok( $result >> 8 eq 9 );
+}
 
 $result = system "runcon -t test_key_no_link_t $basedir/keyctl $v 2>&1";
 if ($test_link_53) {
@@ -101,9 +107,12 @@ $result = system(
 );
 ok( $result >> 8 eq 6 );
 
-$result = system(
-"runcon -t test_keyring_service_t $basedir/keyring_service $v test_request_keys_no_read_t $basedir/request_keys 2>&1"
-);
-ok( $result >> 8 eq 8 );
+SKIP: {
+    skip( "KEYCTL_DH_COMPUTE unavailable in FIPS mode", 1 ) if $skip_dh;
+    $result = system(
+    "runcon -t test_keyring_service_t $basedir/keyring_service $v test_request_keys_no_read_t $basedir/request_keys 2>&1"
+    );
+    ok( $result >> 8 eq 8 );
+}
 
 exit;
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
  2026-10-18  1:28 [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable Pablo Alessandro Santos Hugen
@ 2026-10-19 17:11 ` Stephen Smalley
  2026-10-20 18:03   ` Pablo Hugen
  2026-10-20 18:06 ` [PATCH v2] " Pablo Alessandro Santos Hugen
  1 sibling, 1 reply; 5+ messages in thread
From: Stephen Smalley @ 2026-10-19 17:11 UTC (permalink / raw)
  To: Pablo Alessandro Santos Hugen, Ondrej Mosnáček; +Cc: selinux

On Sat, Oct 17, 2026 at 9:29 PM Pablo Alessandro Santos Hugen
<phugen@redhat.com> wrote:
>
> Since 32f07cc40c9b ("crypto: dh - disallow plain "dh" usage in
> FIPS mode") landed in linux 5.18, plain "dh" is disallowed in
> FIPS mode per SP800-56Arev3. As noted in the commit:
>
> > This change will effectively render the
> > keyctl(KEYCTL_DH_COMPUTE) syscall unusable in FIPS mode, but
> > it has been brought up that this might even be a good thing
> > ([1])."
> >
> > [1] https://lore.kernel.org/r/20211217055227.GA20698@gondor.apana.org.au
>
> keyctl(KEYCTL_DH_COMPUTE) returns ENOENT in FIPS mode.
>
> So, this patch treat ENOENT and ENOSYS as non-fatal in
> keyctl.c (because the operation is unavailable, not denied by
> policy). SELinux denials (EACCES) still exit 9. Skip
> test_key_no_read_t in FIPS mode since KEYCTL_DH_COMPUTE is
> the only operation requiring key { read }.
>
> Fixes: 2d7aad8a1f8c ("selinux-testsuite: Add keys tests")
> Signed-off-by: Pablo Alessandro Santos Hugen <phugen@redhat.com>
> ---
>  tests/keys/keyctl.c       | 15 ++++++++++-----
>  tests/keys/request_keys.c | 15 ++++++++++-----
>  tests/keys/test           | 21 +++++++++++++++------
>  3 files changed, 35 insertions(+), 16 deletions(-)
>
> diff --git a/tests/keys/keyctl.c b/tests/keys/keyctl.c
> index e13c655..261c00a 100644
> --- a/tests/keys/keyctl.c
> +++ b/tests/keys/keyctl.c
> @@ -142,12 +142,17 @@ int main(int argc, char *argv[])
>         /* Requires key { create read write } */
>         compute = keyctl(KEYCTL_DH_COMPUTE, &params, NULL, 0, 0);
>         if (compute < 0) {
> -               fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
> -                       strerror(errno));
> -               exit(9);
> -       }
> -       if (verbose)
> +               if (errno == ENOENT || errno == ENOSYS) {

KEYCTL_DH_COMPUTE never returns ENOSYS; with !CONFIG_KEY_DH_OPERATIONS
the stub in security/keys/internal.h returns -EOPNOTSUPP, and the
sys_keyctl default case is also -EOPNOTSUPP. If you want to cover
kernels built with DH support, this should be EOPNOTSUPP instead (both
files).

> diff --git a/tests/keys/request_keys.c b/tests/keys/request_keys.c
> index 43b20d9..7cf7cd0 100644
> --- a/tests/keys/request_keys.c
> +++ b/tests/keys/request_keys.c
> @@ -127,12 +127,17 @@ int main(int argc, char **argv)
>         /* Requires key { read write } */
>         compute = keyctl(KEYCTL_DH_COMPUTE, &params, NULL, 0, 0);
>         if (compute < 0) {
> -               fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
> -                       strerror(errno));
> -               exit(8);
> -       }
> -       if (verbose)
> +               if (errno == ENOENT || errno == ENOSYS) {

Same comment as above.

> diff --git a/tests/keys/test b/tests/keys/test
> index 061bc62..9e50633 100755
> --- a/tests/keys/test
> +++ b/tests/keys/test
> @@ -51,8 +54,11 @@ ok( $result >> 8 eq 6 );
>  $result = system "runcon -t test_key_no_view_t $basedir/keyctl $v 2>&1";
>  ok( $result >> 8 eq 8 );
>
> -$result = system "runcon -t test_key_no_read_t $basedir/keyctl $v 2>&1";
> -ok( $result >> 8 eq 9 );
> +SKIP: {
> +    skip( "KEYCTL_DH_COMPUTE unavailable in FIPS mode", 1 ) if $skip_dh;
> +    $result = system "runcon -t test_key_no_read_t $basedir/keyctl $v 2>&1";
> +    ok( $result >> 8 eq 9 );
> +}

This SKIP block and the one below shouldn't be necessary. In
__keyctl_dh_compute() the three dh_data_from_key() calls each do
lookup_user_key(id, 0, KEY_NEED_READ) and run before
crypto_alloc_kpp("dh"). key_task_permission() for KEY_NEED_READ ends
with security_key_permission() as the final arbiter, so for
test_key_no_read_t the SELinux denial fires there, lookup_user_key()
returns -EACCES, and dh_data_from_key() squashes it to -ENOKEY. ENOKEY
isn't ENOENT or ENOSYS, so with just the C-side change the no_read_t
runs still exit 9 / 8 under FIPS exactly as they do today; the
FIPS-mode ENOENT is never reached when read is denied.

> -$result = system(
> -"runcon -t test_keyring_service_t $basedir/keyring_service $v test_request_keys_no_read_t $basedir/request_keys 2>&1"
> -);
> -ok( $result >> 8 eq 8 );
> +SKIP: {
> +    skip( "KEYCTL_DH_COMPUTE unavailable in FIPS mode", 1 ) if $skip_dh;
> +    $result = system(
> +    "runcon -t test_keyring_service_t $basedir/keyring_service $v test_request_keys_no_read_t $basedir/request_keys 2>&1"
> +    );
> +    ok( $result >> 8 eq 8 );
> +}

See above comment.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
  2026-10-19 17:11 ` Stephen Smalley
@ 2026-10-20 18:03   ` Pablo Hugen
  0 siblings, 0 replies; 5+ messages in thread
From: Pablo Hugen @ 2026-10-20 18:03 UTC (permalink / raw)
  To: Stephen Smalley, Pablo Alessandro Santos Hugen,
	Ondrej Mosnáček
  Cc: selinux, Ondrej Mosnáček

[-- Attachment #1: Type: text/plain, Size: 262 bytes --]

Thanks for the review Stephen. Both fixed in v2. 

I've validated the v2 patch against the RHEL kernel (which I also did in
the v1), and it seems solid: 

https://artifacts.osci.redhat.com/testing-farm/753a7e84-6b69-4c83-b39b-e7819005fbb6/

Best,
Pablo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
  2026-10-18  1:28 [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable Pablo Alessandro Santos Hugen
  2026-10-19 17:11 ` Stephen Smalley
@ 2026-10-20 18:06 ` Pablo Alessandro Santos Hugen
  2026-10-21 12:57   ` Stephen Smalley
  1 sibling, 1 reply; 5+ messages in thread
From: Pablo Alessandro Santos Hugen @ 2026-10-20 18:06 UTC (permalink / raw)
  To: selinux; +Cc: stephen.smalley.work, omosnacek

Since 32f07cc40c9b ("crypto: dh - disallow plain "dh" usage in
FIPS mode") landed in linux 5.18, plain "dh" is disallowed in
FIPS mode per SP800-56Arev3. keyctl(KEYCTL_DH_COMPUTE) returns
ENOENT in FIPS mode.

Treat ENOENT and EOPNOTSUPP as non-fatal in keyctl.c and
request_keys.c (the operation is unavailable, not denied by
policy). SELinux denials (EACCES) still exit 9/8.

Fixes: 2d7aad8a1f8c ("selinux-testsuite: Add keys tests")
Signed-off-by: Pablo Alessandro Santos Hugen <phugen@redhat.com>
---
Changes in v2 (Stephen Smalley):
 - Replace ENOSYS with EOPNOTSUPP — KEYCTL_DH_COMPUTE never
   returns ENOSYS; the !CONFIG_KEY_DH_OPERATIONS stub returns
   EOPNOTSUPP
 - Drop SKIP blocks in Perl test — SELinux denial fires before
   DH computation (EACCES -> ENOKEY), so no_read_t tests still
   pass under FIPS

 tests/keys/keyctl.c       | 15 ++++++++++-----
 tests/keys/request_keys.c | 15 ++++++++++-----
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/tests/keys/keyctl.c b/tests/keys/keyctl.c
index e13c655..5e98f11 100644
--- a/tests/keys/keyctl.c
+++ b/tests/keys/keyctl.c
@@ -142,12 +142,17 @@ int main(int argc, char *argv[])
 	/* Requires key { create read write } */
 	compute = keyctl(KEYCTL_DH_COMPUTE, &params, NULL, 0, 0);
 	if (compute < 0) {
-		fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
-			strerror(errno));
-		exit(9);
-	}
-	if (verbose)
+		if (errno == ENOENT || errno == EOPNOTSUPP) {
+			if (verbose)
+				printf("KEYCTL_DH_COMPUTE not available, skipping\n");
+		} else {
+			fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
+				strerror(errno));
+			exit(9);
+		}
+	} else if (verbose) {
 		printf("KEYCTL_DH_COMPUTE key ID size: %d\n", compute);
+	}
 
 	/* Requires key { write link } */
 	link = keyctl(KEYCTL_LINK, base, KEY_SPEC_PROCESS_KEYRING);
diff --git a/tests/keys/request_keys.c b/tests/keys/request_keys.c
index 43b20d9..291a522 100644
--- a/tests/keys/request_keys.c
+++ b/tests/keys/request_keys.c
@@ -127,12 +127,17 @@ int main(int argc, char **argv)
 	/* Requires key { read write } */
 	compute = keyctl(KEYCTL_DH_COMPUTE, &params, NULL, 0, 0);
 	if (compute < 0) {
-		fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
-			strerror(errno));
-		exit(8);
-	}
-	if (verbose)
+		if (errno == ENOENT || errno == EOPNOTSUPP) {
+			if (verbose)
+				printf("\tKEYCTL_DH_COMPUTE not available, skipping\n");
+		} else {
+			fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
+				strerror(errno));
+			exit(8);
+		}
+	} else if (verbose) {
 		printf("\tKEYCTL_DH_COMPUTE key ID size: %d\n", compute);
+	}
 
 	exit(0);
 }
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
  2026-10-20 18:06 ` [PATCH v2] " Pablo Alessandro Santos Hugen
@ 2026-10-21 12:57   ` Stephen Smalley
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Smalley @ 2026-10-21 12:57 UTC (permalink / raw)
  To: Pablo Alessandro Santos Hugen; +Cc: selinux, omosnacek

On Tue, Oct 20, 2026 at 2:07 PM Pablo Alessandro Santos Hugen
<phugen@redhat.com> wrote:
>
> Since 32f07cc40c9b ("crypto: dh - disallow plain "dh" usage in
> FIPS mode") landed in linux 5.18, plain "dh" is disallowed in
> FIPS mode per SP800-56Arev3. keyctl(KEYCTL_DH_COMPUTE) returns
> ENOENT in FIPS mode.
>
> Treat ENOENT and EOPNOTSUPP as non-fatal in keyctl.c and
> request_keys.c (the operation is unavailable, not denied by
> policy). SELinux denials (EACCES) still exit 9/8.
>
> Fixes: 2d7aad8a1f8c ("selinux-testsuite: Add keys tests")
> Signed-off-by: Pablo Alessandro Santos Hugen <phugen@redhat.com>

Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>

Note that this will skip this testing on FIPS-enabled hosts so it
won't be exercised if your testing infrastructure always enables FIPS;
that's ok with me but noting for the record.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-21 12:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-18  1:28 [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable Pablo Alessandro Santos Hugen
2026-10-19 17:11 ` Stephen Smalley
2026-10-20 18:03   ` Pablo Hugen
2026-10-20 18:06 ` [PATCH v2] " Pablo Alessandro Santos Hugen
2026-10-21 12:57   ` Stephen Smalley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.