lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250903175841.232537-2-dwindsor@gmail.com>
Date: Wed,  3 Sep 2025 13:58:41 -0400
From: David Windsor <dwindsor@...il.com>
To: bpf@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
	martin.lau@...ux.dev,
	ast@...nel.org,
	daniel@...earbox.net,
	andrii@...nel.org,
	eddyz87@...il.com,
	song@...nel.org,
	yonghong.song@...ux.dev,
	john.fastabend@...il.com,
	kpsingh@...nel.org,
	sdf@...ichev.me,
	haoluo@...gle.com,
	jolsa@...nel.org,
	dwindsor@...il.com
Subject: [PATCH 2/2] selftests/bpf: Add cred local storage tests

Signed-off-by: David Windsor <dwindsor@...il.com>
---
 .../selftests/bpf/prog_tests/cred_storage.c   | 52 +++++++++++
 .../selftests/bpf/progs/cred_storage.c        | 87 +++++++++++++++++++
 2 files changed, 139 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/cred_storage.c
 create mode 100644 tools/testing/selftests/bpf/progs/cred_storage.c

diff --git a/tools/testing/selftests/bpf/prog_tests/cred_storage.c b/tools/testing/selftests/bpf/prog_tests/cred_storage.c
new file mode 100644
index 000000000000..1a99f6453a0f
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/cred_storage.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <test_progs.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include "cred_storage.skel.h"
+
+static void test_cred_lifecycle(void)
+{
+	struct cred_storage *skel;
+	pid_t child;
+	int status, err;
+
+	skel = cred_storage__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "skel_load"))
+		return;
+
+	err = cred_storage__attach(skel);
+	if (!ASSERT_OK(err, "attach"))
+		goto cleanup;
+
+	skel->data->cred_storage_result = -1;
+
+	skel->bss->monitored_pid = getpid();
+
+	child = fork();
+	if (child == 0) {
+		/* forces cred_prepare with new credentials */
+		exit(0);
+	} else if (child > 0) {
+		waitpid(child, &status, 0);
+
+		/* give time for cred_free hook to run */
+		usleep(10000);
+
+		/* verify that the dummy value was stored and persisted */
+		ASSERT_EQ(skel->data->cred_storage_result, 0,
+			  "cred_storage_dummy_value");
+	} else {
+		ASSERT_TRUE(false, "fork failed");
+	}
+
+cleanup:
+	cred_storage__destroy(skel);
+}
+
+void test_cred_storage(void)
+{
+	if (test__start_subtest("lifecycle"))
+		test_cred_lifecycle();
+}
diff --git a/tools/testing/selftests/bpf/progs/cred_storage.c b/tools/testing/selftests/bpf/progs/cred_storage.c
new file mode 100644
index 000000000000..ae66d3b00d2e
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/cred_storage.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2025 David Windsor.
+ */
+
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+char _license[] SEC("license") = "GPL";
+
+#define DUMMY_STORAGE_VALUE 0xdeadbeef
+
+extern struct bpf_local_storage_data *bpf_cred_storage_get(struct bpf_map *map,
+							   struct cred *cred,
+							   void *init, int init__sz, __u64 flags) __ksym;
+
+__u32 monitored_pid = 0;
+int cred_storage_result = -1;
+
+struct cred_storage {
+	__u32 value;
+};
+
+struct {
+	__uint(type, BPF_MAP_TYPE_CRED_STORAGE);
+	__uint(map_flags, BPF_F_NO_PREALLOC);
+	__type(key, int);
+	__type(value, struct cred_storage);
+} cred_storage_map SEC(".maps");
+
+SEC("lsm/cred_prepare")
+int BPF_PROG(cred_prepare, struct cred *new, const struct cred *old, gfp_t gfp)
+{
+	__u32 pid = bpf_get_current_pid_tgid() >> 32;
+	struct cred_storage init_storage = {
+		.value = DUMMY_STORAGE_VALUE,
+	};
+	struct bpf_local_storage_data *sdata;
+	struct cred_storage *storage;
+
+	if (pid != monitored_pid)
+		return 0;
+
+	sdata = bpf_cred_storage_get((struct bpf_map *)&cred_storage_map, new, &init_storage,
+				     sizeof(init_storage), BPF_LOCAL_STORAGE_GET_F_CREATE);
+	if (!sdata)
+		return 0;
+
+	storage = (struct cred_storage *)sdata->data;
+	if (!storage)
+		return 0;
+
+	/* Verify the storage was initialized correctly */
+	if (storage->value == DUMMY_STORAGE_VALUE)
+		cred_storage_result = 0;
+
+	return 0;
+}
+
+SEC("lsm/cred_free")
+int BPF_PROG(cred_free, struct cred *cred)
+{
+	__u32 pid = bpf_get_current_pid_tgid() >> 32;
+	struct bpf_local_storage_data *sdata;
+	struct cred_storage *storage;
+
+	if (pid != monitored_pid)
+		return 0;
+
+	/* Try to retrieve the storage that should have been created in prepare */
+	sdata = bpf_cred_storage_get((struct bpf_map *)&cred_storage_map, cred,
+				     NULL, 0, 0);
+	if (!sdata)
+		return 0;
+
+	storage = (struct cred_storage *)sdata->data;
+	if (!storage)
+		return 0;
+
+	/* Verify the dummy value is still there during free */
+	if (storage->value == DUMMY_STORAGE_VALUE)
+		cred_storage_result = 0;
+
+	return 0;
+}
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ