Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/pidfd: test extended attribute support

Add tests for extended attribute support on pidfds.

Link: https://lore.kernel.org/20250618-work-pidfs-persistent-v2-13-98f3456fd552@kernel.org
Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>

+100 -1
+1
tools/testing/selftests/pidfd/.gitignore
··· 10 10 pidfd_bind_mount 11 11 pidfd_info_test 12 12 pidfd_exec_helper 13 + pidfd_xattr_test
+2 -1
tools/testing/selftests/pidfd/Makefile
··· 3 3 4 4 TEST_GEN_PROGS := pidfd_test pidfd_fdinfo_test pidfd_open_test \ 5 5 pidfd_poll_test pidfd_wait pidfd_getfd_test pidfd_setns_test \ 6 - pidfd_file_handle_test pidfd_bind_mount pidfd_info_test 6 + pidfd_file_handle_test pidfd_bind_mount pidfd_info_test \ 7 + pidfd_xattr_test 7 8 8 9 TEST_GEN_PROGS_EXTENDED := pidfd_exec_helper 9 10
+97
tools/testing/selftests/pidfd/pidfd_xattr_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #define _GNU_SOURCE 4 + #include <errno.h> 5 + #include <fcntl.h> 6 + #include <limits.h> 7 + #include <linux/types.h> 8 + #include <poll.h> 9 + #include <pthread.h> 10 + #include <sched.h> 11 + #include <signal.h> 12 + #include <stdio.h> 13 + #include <stdlib.h> 14 + #include <string.h> 15 + #include <syscall.h> 16 + #include <sys/prctl.h> 17 + #include <sys/wait.h> 18 + #include <unistd.h> 19 + #include <sys/socket.h> 20 + #include <linux/kcmp.h> 21 + #include <sys/stat.h> 22 + #include <sys/xattr.h> 23 + 24 + #include "pidfd.h" 25 + #include "../kselftest_harness.h" 26 + 27 + FIXTURE(pidfs_xattr) 28 + { 29 + pid_t child_pid; 30 + int child_pidfd; 31 + }; 32 + 33 + FIXTURE_SETUP(pidfs_xattr) 34 + { 35 + self->child_pid = create_child(&self->child_pidfd, CLONE_NEWUSER | CLONE_NEWPID); 36 + EXPECT_GE(self->child_pid, 0); 37 + 38 + if (self->child_pid == 0) 39 + _exit(EXIT_SUCCESS); 40 + } 41 + 42 + FIXTURE_TEARDOWN(pidfs_xattr) 43 + { 44 + sys_waitid(P_PID, self->child_pid, NULL, WEXITED); 45 + } 46 + 47 + TEST_F(pidfs_xattr, set_get_list_xattr_multiple) 48 + { 49 + int ret, i; 50 + char xattr_name[32]; 51 + char xattr_value[32]; 52 + char buf[32]; 53 + const int num_xattrs = 10; 54 + char list[PATH_MAX] = {}; 55 + 56 + for (i = 0; i < num_xattrs; i++) { 57 + snprintf(xattr_name, sizeof(xattr_name), "trusted.testattr%d", i); 58 + snprintf(xattr_value, sizeof(xattr_value), "testvalue%d", i); 59 + ret = fsetxattr(self->child_pidfd, xattr_name, xattr_value, strlen(xattr_value), 0); 60 + ASSERT_EQ(ret, 0); 61 + } 62 + 63 + for (i = 0; i < num_xattrs; i++) { 64 + snprintf(xattr_name, sizeof(xattr_name), "trusted.testattr%d", i); 65 + snprintf(xattr_value, sizeof(xattr_value), "testvalue%d", i); 66 + memset(buf, 0, sizeof(buf)); 67 + ret = fgetxattr(self->child_pidfd, xattr_name, buf, sizeof(buf)); 68 + ASSERT_EQ(ret, strlen(xattr_value)); 69 + ASSERT_EQ(strcmp(buf, xattr_value), 0); 70 + } 71 + 72 + ret = flistxattr(self->child_pidfd, list, sizeof(list)); 73 + ASSERT_GT(ret, 0); 74 + for (i = 0; i < num_xattrs; i++) { 75 + snprintf(xattr_name, sizeof(xattr_name), "trusted.testattr%d", i); 76 + bool found = false; 77 + for (char *it = list; it < list + ret; it += strlen(it) + 1) { 78 + if (strcmp(it, xattr_name)) 79 + continue; 80 + found = true; 81 + break; 82 + } 83 + ASSERT_TRUE(found); 84 + } 85 + 86 + for (i = 0; i < num_xattrs; i++) { 87 + snprintf(xattr_name, sizeof(xattr_name), "trusted.testattr%d", i); 88 + ret = fremovexattr(self->child_pidfd, xattr_name); 89 + ASSERT_EQ(ret, 0); 90 + 91 + ret = fgetxattr(self->child_pidfd, xattr_name, buf, sizeof(buf)); 92 + ASSERT_EQ(ret, -1); 93 + ASSERT_EQ(errno, ENODATA); 94 + } 95 + } 96 + 97 + TEST_HARNESS_MAIN