File Index
Files and directories
Sign in
FILE

pidfd_xattr_test.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/pidfd/pidfd_xattr_test.c 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
 27FIXTURE(pidfs_xattr)
 28{
 29	pid_t child_pid;
 30	int child_pidfd;
 31};
 32
 33FIXTURE_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
 42FIXTURE_TEARDOWN(pidfs_xattr)
 43{
 44	sys_waitid(P_PID, self->child_pid, NULL, WEXITED);
 45}
 46
 47TEST_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
 97TEST_F(pidfs_xattr, set_get_list_xattr_persistent)
 98{
 99	int ret;
100	char buf[32];
101	char list[PATH_MAX] = {};
102
103	ret = fsetxattr(self->child_pidfd, "trusted.persistent", "persistent value", strlen("persistent value"), 0);
104	ASSERT_EQ(ret, 0);
105
106	memset(buf, 0, sizeof(buf));
107	ret = fgetxattr(self->child_pidfd, "trusted.persistent", buf, sizeof(buf));
108	ASSERT_EQ(ret, strlen("persistent value"));
109	ASSERT_EQ(strcmp(buf, "persistent value"), 0);
110
111	ret = flistxattr(self->child_pidfd, list, sizeof(list));
112	ASSERT_GT(ret, 0);
113	ASSERT_EQ(strcmp(list, "trusted.persistent"), 0)
114
115	ASSERT_EQ(close(self->child_pidfd), 0);
116	self->child_pidfd = -EBADF;
117	sleep(2);
118
119	self->child_pidfd = sys_pidfd_open(self->child_pid, 0);
120	ASSERT_GE(self->child_pidfd, 0);
121
122	memset(buf, 0, sizeof(buf));
123	ret = fgetxattr(self->child_pidfd, "trusted.persistent", buf, sizeof(buf));
124	ASSERT_EQ(ret, strlen("persistent value"));
125	ASSERT_EQ(strcmp(buf, "persistent value"), 0);
126
127	ret = flistxattr(self->child_pidfd, list, sizeof(list));
128	ASSERT_GT(ret, 0);
129	ASSERT_EQ(strcmp(list, "trusted.persistent"), 0);
130}
131
132TEST_HARNESS_MAIN
~/ Read-only file preview.