mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] SafeSetID: use real GID for GID policy lookups
@ 2026-10-03 10:34 tjdqudcks0424
  2026-10-03 10:34 ` [PATCH 1/2] security: safesetid: use real GID for GID policy lookup tjdqudcks0424
  2026-10-03 10:34 ` [PATCH 2/2] selftests/safesetid: test GID policy with mismatched real IDs tjdqudcks0424
  0 siblings, 2 replies; 4+ messages in thread
From: tjdqudcks0424 @ 2026-10-03 10:34 UTC (permalink / raw)
  To: Micah Morton, Paul Moore, linux-security-module
  Cc: James Morris, Serge E . Hallyn, Thomas Cedeno, Shuah Khan,
	Christian Brauner, linux-kselftest, linux-kernel, security

From: Sung Byeongchan <tjdqudcks0424@naver.com>

SafeSetID GID policy enforcement first checks whether a policy applies to
the old real GID.  Its per-target helper then incorrectly constructs the
source lookup key from the old real UID.  When those numeric IDs differ,
the helper can miss the policy for the real GID and return the
unconstrained default.

The issue is present at Torvalds mainline commit
e767a4ea70a3992c37ed604157d32f0dfbf9b1e3.  In three clean QEMU boots, a
task with real UID 1000, real GID 2000 and only CAP_SETGID obtained
non-allowlisted GID 2002 despite a 2000:2001 policy.  The bypass covered
setgid(), setegid(), setregid(), setresgid(), setfsgid() and setgroups(),
including supplementary-group acquisition and access to a synthetic
group-protected resource.  The acquired group credentials also persisted
across exec.

This demonstrates a SafeSetID GID policy bypass and group privilege
expansion.  It does not demonstrate direct UID 0 elevation or a universal
local privilege escalation, and the CAP_SETGID prerequisite is explicit.
The security boundary is that SafeSetID was configured to constrain that
capability but failed to enforce its GID allowlist.

Patch 1 selects the old real UID for UID checks and the old real GID for
GID checks.  Patch 2 adds a focused regression test for mismatched real
IDs, covering both setresgid() and setgroups(), and records the SafeSetID
selftest path in MAINTAINERS.

The vulnerable and fixed kernels used identical debug configurations.
Across three clean boots per kernel, the vulnerable matrix reproduced all
tested forbidden transitions and the fixed matrix blocked all of them.
Allowed, existing-ID, no-policy, no-capability and UID-policy controls
behaved as expected.  The existing SafeSetID selftest passed on both, the
new regression test failed on the vulnerable kernel and passed on the
fixed kernel, and no KASAN, UBSAN, BUG, WARNING, Oops, panic, lockdep,
refcount, hung-task or kmemleak finding was observed.

A reproducer and the complete QEMU validation logs are available
privately on request. They are not included in this public posting.

This finding and patch preparation were assisted by OpenAI Codex.

Sung Byeongchan (2):
  security: safesetid: use real GID for GID policy lookup
  selftests/safesetid: test GID policy with mismatched real IDs

 MAINTAINERS                                   |   1 +
 security/safesetid/lsm.c                      |   8 +-
 tools/testing/selftests/safesetid/Makefile    |   4 +-
 .../safesetid/safesetid-gid-policy-test.c     | 252 ++++++++++++++++++
 .../safesetid/safesetid-gid-policy-test.sh    |  11 +
 5 files changed, 271 insertions(+), 5 deletions(-)
 create mode 100644 tools/testing/selftests/safesetid/safesetid-gid-policy-test.c
 create mode 100755 tools/testing/selftests/safesetid/safesetid-gid-policy-test.sh


base-commit: e767a4ea70a3992c37ed604157d32f0dfbf9b1e3
-- 
2.43.0


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

* [PATCH 1/2] security: safesetid: use real GID for GID policy lookup
  2026-10-03 10:34 [PATCH 0/2] SafeSetID: use real GID for GID policy lookups tjdqudcks0424
@ 2026-10-03 10:34 ` tjdqudcks0424
  2026-10-04 22:05   ` Serge E. Hallyn
  2026-10-03 10:34 ` [PATCH 2/2] selftests/safesetid: test GID policy with mismatched real IDs tjdqudcks0424
  1 sibling, 1 reply; 4+ messages in thread
From: tjdqudcks0424 @ 2026-10-03 10:34 UTC (permalink / raw)
  To: Micah Morton, Paul Moore, linux-security-module
  Cc: James Morris, Serge E . Hallyn, Thomas Cedeno, Shuah Khan,
	Christian Brauner, linux-kselftest, linux-kernel, security

From: Sung Byeongchan <tjdqudcks0424@naver.com>

SafeSetID policies constrain the ID transitions available to a task for
each source ID.  id_permitted_for_cred() always builds that source key
from the old real UID, even when it is checking a GID transition.  If the
real UID and real GID differ, the policy attached to the real GID is
therefore missed and the lookup can return the unconstrained default.

On current mainline, a test task with real UID 1000, real GID 2000 and
only CAP_SETGID obtained non-allowlisted GID 2002 despite a 2000:2001 GID
policy.  The bypass reproduced for setgid(), setegid(), setregid(),
setresgid(), setfsgid() and setgroups() across three clean QEMU boots,
and enabled access to a synthetic group-protected resource.  This shows
a SafeSetID GID policy bypass and group privilege expansion; it does not
show direct UID 0 elevation or a universal local privilege escalation.

Build the source key from the old real UID for UID policy checks and the
old real GID for GID policy checks.  In three fixed-kernel boots, all
tested non-allowlisted transitions were blocked while the allowed target,
existing-ID, no-policy and UID-policy controls, and the existing SafeSetID
selftest continued to pass.

Fixes: 5294bac97e12 ("LSM: SafeSetID: Add GID security policy handling")
Cc: stable@vger.kernel.org
Assisted-by: OpenAI Codex
Signed-off-by: Sung Byeongchan <tjdqudcks0424@naver.com>
---
 security/safesetid/lsm.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/security/safesetid/lsm.c b/security/safesetid/lsm.c
index d5fb949050dd8..18124fc499dbc 100644
--- a/security/safesetid/lsm.c
+++ b/security/safesetid/lsm.c
@@ -148,13 +148,16 @@ static int safesetid_security_capable(const struct cred *cred,
 static bool id_permitted_for_cred(const struct cred *old, kid_t new_id, enum setid_type new_type)
 {
 	bool permitted;
+	kid_t source_id;
 
 	/* If our old creds already had this ID in it, it's fine. */
 	if (new_type == UID) {
+		source_id.uid = old->uid;
 		if (uid_eq(new_id.uid, old->uid) || uid_eq(new_id.uid, old->euid) ||
 			uid_eq(new_id.uid, old->suid))
 			return true;
 	} else if (new_type == GID){
+		source_id.gid = old->gid;
 		if (gid_eq(new_id.gid, old->gid) || gid_eq(new_id.gid, old->egid) ||
 			gid_eq(new_id.gid, old->sgid))
 			return true;
@@ -162,11 +165,10 @@ static bool id_permitted_for_cred(const struct cred *old, kid_t new_id, enum set
 		return false;
 
 	/*
-	 * Transitions to new UIDs require a check against the policy of the old
-	 * RUID.
+	 * Transitions require a check against the policy of the old real ID.
 	 */
 	permitted =
-	    setid_policy_lookup((kid_t){.uid = old->uid}, new_id, new_type) != SIDPOL_CONSTRAINED;
+	    setid_policy_lookup(source_id, new_id, new_type) != SIDPOL_CONSTRAINED;
 
 	if (!permitted) {
 		if (new_type == UID) {
-- 
2.43.0


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

* [PATCH 2/2] selftests/safesetid: test GID policy with mismatched real IDs
  2026-10-03 10:34 [PATCH 0/2] SafeSetID: use real GID for GID policy lookups tjdqudcks0424
  2026-10-03 10:34 ` [PATCH 1/2] security: safesetid: use real GID for GID policy lookup tjdqudcks0424
@ 2026-10-03 10:34 ` tjdqudcks0424
  1 sibling, 0 replies; 4+ messages in thread
From: tjdqudcks0424 @ 2026-10-03 10:34 UTC (permalink / raw)
  To: Micah Morton, Paul Moore, linux-security-module
  Cc: James Morris, Serge E . Hallyn, Thomas Cedeno, Shuah Khan,
	Christian Brauner, linux-kselftest, linux-kernel, security

From: Sung Byeongchan <tjdqudcks0424@naver.com>

The existing test uses equal numeric UID and GID values, so it cannot
distinguish which real ID SafeSetID uses as the source of a GID policy
lookup.

Add isolated child-process cases with real UID 1000, real GID 2000 and a
2000:2001 GID policy.  Verify that 2001 is allowed and 2002 is rejected
for both setresgid() and setgroups().  Each child retains only CAP_SETGID
in its permitted and effective sets, and pidfd polling bounds every case
without timing the transition.

On an affected kernel, the forbidden transitions survive and make the
test fail.  With the fix, SafeSetID terminates those children and the test
passes.

Assisted-by: OpenAI Codex
Signed-off-by: Sung Byeongchan <tjdqudcks0424@naver.com>
---
 MAINTAINERS                                   |   1 +
 tools/testing/selftests/safesetid/Makefile    |   4 +-
 .../safesetid/safesetid-gid-policy-test.c     | 252 ++++++++++++++++++
 .../safesetid/safesetid-gid-policy-test.sh    |  11 +
 4 files changed, 266 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/safesetid/safesetid-gid-policy-test.c
 create mode 100755 tools/testing/selftests/safesetid/safesetid-gid-policy-test.sh

diff --git a/MAINTAINERS b/MAINTAINERS
index 7235a92ff879b..68b355ad33e0f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -24266,6 +24266,7 @@ M:	Micah Morton <mortonm@chromium.org>
 S:	Supported
 F:	Documentation/admin-guide/LSM/SafeSetID.rst
 F:	security/safesetid/
+F:	tools/testing/selftests/safesetid/
 
 SAMSUNG AUDIO (ASoC) DRIVERS
 M:	Sylwester Nawrocki <s.nawrocki@samsung.com>
diff --git a/tools/testing/selftests/safesetid/Makefile b/tools/testing/selftests/safesetid/Makefile
index e815bbf2d0f4a..1a4a6630858c0 100644
--- a/tools/testing/selftests/safesetid/Makefile
+++ b/tools/testing/selftests/safesetid/Makefile
@@ -3,7 +3,7 @@
 CFLAGS = -Wall -O2
 LDLIBS = -lcap
 
-TEST_PROGS := safesetid-test.sh
-TEST_GEN_FILES := safesetid-test
+TEST_PROGS := safesetid-test.sh safesetid-gid-policy-test.sh
+TEST_GEN_FILES := safesetid-test safesetid-gid-policy-test
 
 include ../lib.mk
diff --git a/tools/testing/selftests/safesetid/safesetid-gid-policy-test.c b/tools/testing/selftests/safesetid/safesetid-gid-policy-test.c
new file mode 100644
index 0000000000000..873d65627c494
--- /dev/null
+++ b/tools/testing/selftests/safesetid/safesetid-gid-policy-test.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <errno.h>
+#include <grp.h>
+#include <linux/capability.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define TEST_UID 1000
+#define POLICY_GID 2000
+#define ALLOWED_GID 2001
+#define FORBIDDEN_GID 2002
+
+#define GID_POLICY_FILE \
+	"/sys/kernel/security/safesetid/gid_allowlist_policy"
+#define GID_POLICY "2000:2001\n"
+
+enum test_operation {
+	OP_SETRESGID,
+	OP_SETGROUPS,
+};
+
+static int install_policy(void)
+{
+	FILE *policy;
+	int ret = 0;
+
+	policy = fopen(GID_POLICY_FILE, "w");
+	if (!policy) {
+		perror("fopen gid policy");
+		return -1;
+	}
+	if (fputs(GID_POLICY, policy) == EOF) {
+		perror("write gid policy");
+		ret = -1;
+	}
+	if (fclose(policy)) {
+		perror("close gid policy");
+		ret = -1;
+	}
+	return ret;
+}
+
+static int retain_only_setgid(void)
+{
+	cap_value_t cap = CAP_SETGID;
+	cap_t caps;
+	int ret = -1;
+
+	caps = cap_get_proc();
+	if (!caps) {
+		perror("cap_get_proc");
+		return -1;
+	}
+	if (cap_clear(caps) ||
+	    cap_set_flag(caps, CAP_PERMITTED, 1, &cap, CAP_SET) ||
+	    cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, CAP_SET) ||
+	    cap_set_proc(caps)) {
+		perror("retain CAP_SETGID");
+		goto out;
+	}
+	ret = 0;
+out:
+	cap_free(caps);
+	return ret;
+}
+
+static int check_child_credentials(void)
+{
+	struct __user_cap_header_struct header = {
+		.version = _LINUX_CAPABILITY_VERSION_3,
+	};
+	struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3] = {};
+	uint64_t effective, permitted, inheritable;
+	uid_t ruid, euid, suid;
+	gid_t rgid, egid, sgid;
+	gid_t groups[2];
+	uint64_t expected = 1ULL << CAP_SETGID;
+	int i, ngroups;
+
+	if (getresuid(&ruid, &euid, &suid) ||
+	    getresgid(&rgid, &egid, &sgid)) {
+		perror("getresuid/getresgid");
+		return -1;
+	}
+	if (ruid != TEST_UID || euid != TEST_UID || suid != TEST_UID ||
+	    rgid != POLICY_GID || egid != POLICY_GID || sgid != POLICY_GID) {
+		fprintf(stderr, "unexpected child IDs\n");
+		return -1;
+	}
+
+	ngroups = getgroups(2, groups);
+	if (ngroups != 1 || groups[0] != POLICY_GID) {
+		fprintf(stderr, "unexpected initial supplementary groups\n");
+		return -1;
+	}
+	if (syscall(SYS_capget, &header, data)) {
+		perror("capget");
+		return -1;
+	}
+	effective = data[0].effective | ((uint64_t)data[1].effective << 32);
+	permitted = data[0].permitted | ((uint64_t)data[1].permitted << 32);
+	inheritable = data[0].inheritable | ((uint64_t)data[1].inheritable << 32);
+	if (effective != expected || permitted != expected || inheritable) {
+		fprintf(stderr, "child does not hold only CAP_SETGID\n");
+		return -1;
+	}
+	for (i = 0; i <= CAP_LAST_CAP; i++) {
+		if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0) != 0) {
+			fprintf(stderr, "unexpected ambient capability %d\n", i);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int prepare_child(void)
+{
+	gid_t groups[] = { POLICY_GID };
+
+	if (setgroups(1, groups)) {
+		perror("initial setgroups");
+		return -1;
+	}
+	if (setresgid(POLICY_GID, POLICY_GID, POLICY_GID)) {
+		perror("setresgid policy source");
+		return -1;
+	}
+	if (prctl(PR_SET_KEEPCAPS, 1L)) {
+		perror("PR_SET_KEEPCAPS");
+		return -1;
+	}
+	if (setresuid(TEST_UID, TEST_UID, TEST_UID)) {
+		perror("setresuid test user");
+		return -1;
+	}
+	if (retain_only_setgid())
+		return -1;
+	return check_child_credentials();
+}
+
+static void run_child(enum test_operation operation, gid_t target)
+{
+	gid_t groups[] = { target };
+	int ret;
+
+	if (prepare_child())
+		_exit(2);
+
+	if (operation == OP_SETRESGID)
+		ret = setresgid(target, target, target);
+	else
+		ret = setgroups(1, groups);
+
+	if (ret) {
+		fprintf(stderr, "%s(%u) returned %s\n",
+			operation == OP_SETRESGID ? "setresgid" : "setgroups",
+			target, strerror(errno));
+		_exit(3);
+	}
+	_exit(0);
+}
+
+static int run_case(const char *name, enum test_operation operation,
+		    gid_t target, bool expect_kill)
+{
+	struct pollfd pollfd = {};
+	int status;
+	int pidfd;
+	pid_t child;
+
+	child = fork();
+	if (child < 0) {
+		perror("fork");
+		return -1;
+	}
+	if (!child)
+		run_child(operation, target);
+
+	pidfd = syscall(SYS_pidfd_open, child, 0);
+	if (pidfd < 0) {
+		perror("pidfd_open");
+		kill(child, SIGKILL);
+		waitpid(child, &status, 0);
+		return -1;
+	}
+	pollfd.fd = pidfd;
+	pollfd.events = POLLIN;
+	if (poll(&pollfd, 1, 5000) != 1) {
+		kill(child, SIGKILL);
+		waitpid(child, &status, 0);
+		close(pidfd);
+		fprintf(stderr, "not ok - %s (timeout)\n", name);
+		return -1;
+	}
+	close(pidfd);
+	if (waitpid(child, &status, 0) < 0) {
+		perror("waitpid");
+		return -1;
+	}
+
+	if (expect_kill) {
+		if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL) {
+			printf("ok - %s\n", name);
+			return 0;
+		}
+		fprintf(stderr, "not ok - %s (forbidden transition survived)\n",
+			name);
+		return -1;
+	}
+
+	if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+		printf("ok - %s\n", name);
+		return 0;
+	}
+	fprintf(stderr, "not ok - %s (allowed transition failed)\n", name);
+	return -1;
+}
+
+int main(void)
+{
+	int failures = 0;
+
+	if (getuid()) {
+		fprintf(stderr, "must be run as root\n");
+		return 4;
+	}
+	if (install_policy())
+		return 1;
+
+	failures += run_case("allowed GID transition", OP_SETRESGID,
+			     ALLOWED_GID, false) != 0;
+	failures += run_case("forbidden GID transition", OP_SETRESGID,
+			     FORBIDDEN_GID, true) != 0;
+	failures += run_case("allowed supplementary group", OP_SETGROUPS,
+			     ALLOWED_GID, false) != 0;
+	failures += run_case("forbidden supplementary group", OP_SETGROUPS,
+			     FORBIDDEN_GID, true) != 0;
+
+	return failures ? 1 : 0;
+}
diff --git a/tools/testing/selftests/safesetid/safesetid-gid-policy-test.sh b/tools/testing/selftests/safesetid/safesetid-gid-policy-test.sh
new file mode 100755
index 0000000000000..7318ad3403121
--- /dev/null
+++ b/tools/testing/selftests/safesetid/safesetid-gid-policy-test.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+ksft_skip=4
+
+if [ "$(id -u)" -ne 0 ]; then
+	echo "safesetid-gid-policy-test: must be run as root" >&2
+	exit "$ksft_skip"
+fi
+
+exec ./safesetid-gid-policy-test
-- 
2.43.0


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

* Re: [PATCH 1/2] security: safesetid: use real GID for GID policy lookup
  2026-10-03 10:34 ` [PATCH 1/2] security: safesetid: use real GID for GID policy lookup tjdqudcks0424
@ 2026-10-04 22:05   ` Serge E. Hallyn
  0 siblings, 0 replies; 4+ messages in thread
From: Serge E. Hallyn @ 2026-10-04 22:05 UTC (permalink / raw)
  To: tjdqudcks0424
  Cc: Micah Morton, Paul Moore, linux-security-module, James Morris,
	Thomas Cedeno, Shuah Khan, Christian Brauner, linux-kselftest,
	linux-kernel, security

On Sat, Oct 03, 2026 at 07:34:15PM +0900, tjdqudcks0424@naver.com wrote:
> From: Sung Byeongchan <tjdqudcks0424@naver.com>
> 
> SafeSetID policies constrain the ID transitions available to a task for
> each source ID.  id_permitted_for_cred() always builds that source key
> from the old real UID, even when it is checking a GID transition.  If the
> real UID and real GID differ, the policy attached to the real GID is
> therefore missed and the lookup can return the unconstrained default.
> 
> On current mainline, a test task with real UID 1000, real GID 2000 and
> only CAP_SETGID obtained non-allowlisted GID 2002 despite a 2000:2001 GID
> policy.  The bypass reproduced for setgid(), setegid(), setregid(),
> setresgid(), setfsgid() and setgroups() across three clean QEMU boots,
> and enabled access to a synthetic group-protected resource.  This shows
> a SafeSetID GID policy bypass and group privilege expansion; it does not
> show direct UID 0 elevation or a universal local privilege escalation.
> 
> Build the source key from the old real UID for UID policy checks and the
> old real GID for GID policy checks.  In three fixed-kernel boots, all
> tested non-allowlisted transitions were blocked while the allowed target,
> existing-ID, no-policy and UID-policy controls, and the existing SafeSetID
> selftest continued to pass.
> 
> Fixes: 5294bac97e12 ("LSM: SafeSetID: Add GID security policy handling")
> Cc: stable@vger.kernel.org
> Assisted-by: OpenAI Codex
> Signed-off-by: Sung Byeongchan <tjdqudcks0424@naver.com>

Seems obviously correct.  Thanks for the find and the fix.

Reviewed-by: Serge Hallyn <serge@hallyn.com>

> ---
>  security/safesetid/lsm.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/security/safesetid/lsm.c b/security/safesetid/lsm.c
> index d5fb949050dd8..18124fc499dbc 100644
> --- a/security/safesetid/lsm.c
> +++ b/security/safesetid/lsm.c
> @@ -148,13 +148,16 @@ static int safesetid_security_capable(const struct cred *cred,
>  static bool id_permitted_for_cred(const struct cred *old, kid_t new_id, enum setid_type new_type)
>  {
>  	bool permitted;
> +	kid_t source_id;
>  
>  	/* If our old creds already had this ID in it, it's fine. */
>  	if (new_type == UID) {
> +		source_id.uid = old->uid;
>  		if (uid_eq(new_id.uid, old->uid) || uid_eq(new_id.uid, old->euid) ||
>  			uid_eq(new_id.uid, old->suid))
>  			return true;
>  	} else if (new_type == GID){
> +		source_id.gid = old->gid;
>  		if (gid_eq(new_id.gid, old->gid) || gid_eq(new_id.gid, old->egid) ||
>  			gid_eq(new_id.gid, old->sgid))
>  			return true;
> @@ -162,11 +165,10 @@ static bool id_permitted_for_cred(const struct cred *old, kid_t new_id, enum set
>  		return false;
>  
>  	/*
> -	 * Transitions to new UIDs require a check against the policy of the old
> -	 * RUID.
> +	 * Transitions require a check against the policy of the old real ID.
>  	 */
>  	permitted =
> -	    setid_policy_lookup((kid_t){.uid = old->uid}, new_id, new_type) != SIDPOL_CONSTRAINED;
> +	    setid_policy_lookup(source_id, new_id, new_type) != SIDPOL_CONSTRAINED;
>  
>  	if (!permitted) {
>  		if (new_type == UID) {
> -- 
> 2.43.0

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

end of thread, other threads:[~2026-10-04 22:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-03 10:34 [PATCH 0/2] SafeSetID: use real GID for GID policy lookups tjdqudcks0424
2026-10-03 10:34 ` [PATCH 1/2] security: safesetid: use real GID for GID policy lookup tjdqudcks0424
2026-10-04 22:05   ` Serge E. Hallyn
2026-10-03 10:34 ` [PATCH 2/2] selftests/safesetid: test GID policy with mismatched real IDs tjdqudcks0424

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®