File Index
Files and directories
Sign in
FILE

pidfd_file_handle_test.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/pidfd/pidfd_file_handle_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 <sched.h>
 10#include <signal.h>
 11#include <stdio.h>
 12#include <stdlib.h>
 13#include <string.h>
 14#include <syscall.h>
 15#include <sys/prctl.h>
 16#include <sys/wait.h>
 17#include <unistd.h>
 18#include <sys/socket.h>
 19#include <linux/kcmp.h>
 20#include <sys/stat.h>
 21
 22#include "pidfd.h"
 23#include "kselftest_harness.h"
 24
 25FIXTURE(file_handle)
 26{
 27	pid_t pid;
 28	int pidfd;
 29
 30	pid_t child_pid1;
 31	int child_pidfd1;
 32
 33	pid_t child_pid2;
 34	int child_pidfd2;
 35
 36	pid_t child_pid3;
 37	int child_pidfd3;
 38};
 39
 40FIXTURE_SETUP(file_handle)
 41{
 42	int ret;
 43	int ipc_sockets[2];
 44	char c;
 45
 46	self->pid = getpid();
 47	self->pidfd = sys_pidfd_open(self->pid, 0);
 48	ASSERT_GE(self->pidfd, 0);
 49
 50	ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
 51	EXPECT_EQ(ret, 0);
 52
 53	self->child_pid1 = create_child(&self->child_pidfd1, CLONE_NEWUSER);
 54	EXPECT_GE(self->child_pid1, 0);
 55
 56	if (self->child_pid1 == 0) {
 57		close(ipc_sockets[0]);
 58
 59		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
 60			_exit(EXIT_FAILURE);
 61
 62		close(ipc_sockets[1]);
 63
 64		pause();
 65		_exit(EXIT_SUCCESS);
 66	}
 67
 68	close(ipc_sockets[1]);
 69	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
 70	close(ipc_sockets[0]);
 71
 72	ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
 73	EXPECT_EQ(ret, 0);
 74
 75	self->child_pid2 = create_child(&self->child_pidfd2, CLONE_NEWUSER | CLONE_NEWPID);
 76	EXPECT_GE(self->child_pid2, 0);
 77
 78	if (self->child_pid2 == 0) {
 79		close(ipc_sockets[0]);
 80
 81		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
 82			_exit(EXIT_FAILURE);
 83
 84		close(ipc_sockets[1]);
 85
 86		pause();
 87		_exit(EXIT_SUCCESS);
 88	}
 89
 90	close(ipc_sockets[1]);
 91	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
 92	close(ipc_sockets[0]);
 93
 94	ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
 95	EXPECT_EQ(ret, 0);
 96
 97	self->child_pid3 = create_child(&self->child_pidfd3, CLONE_NEWUSER | CLONE_NEWPID);
 98	EXPECT_GE(self->child_pid3, 0);
 99
100	if (self->child_pid3 == 0) {
101		close(ipc_sockets[0]);
102
103		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
104			_exit(EXIT_FAILURE);
105
106		close(ipc_sockets[1]);
107
108		pause();
109		_exit(EXIT_SUCCESS);
110	}
111
112	close(ipc_sockets[1]);
113	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
114	close(ipc_sockets[0]);
115}
116
117FIXTURE_TEARDOWN(file_handle)
118{
119	EXPECT_EQ(close(self->pidfd), 0);
120
121	EXPECT_EQ(sys_pidfd_send_signal(self->child_pidfd1, SIGKILL, NULL, 0), 0);
122	if (self->child_pidfd1 >= 0)
123		EXPECT_EQ(0, close(self->child_pidfd1));
124
125	EXPECT_EQ(sys_waitid(P_PID, self->child_pid1, NULL, WEXITED), 0);
126
127	EXPECT_EQ(sys_pidfd_send_signal(self->child_pidfd2, SIGKILL, NULL, 0), 0);
128	if (self->child_pidfd2 >= 0)
129		EXPECT_EQ(0, close(self->child_pidfd2));
130
131	EXPECT_EQ(sys_waitid(P_PID, self->child_pid2, NULL, WEXITED), 0);
132
133	if (self->child_pidfd3 >= 0) {
134		EXPECT_EQ(sys_pidfd_send_signal(self->child_pidfd3, SIGKILL, NULL, 0), 0);
135		EXPECT_EQ(0, close(self->child_pidfd3));
136		EXPECT_EQ(sys_waitid(P_PID, self->child_pid3, NULL, WEXITED), 0);
137	}
138}
139
140/*
141 * Test that we can decode a pidfs file handle in the same pid
142 * namespace.
143 */
144TEST_F(file_handle, file_handle_same_pidns)
145{
146	int mnt_id;
147	struct file_handle *fh;
148	int pidfd = -EBADF;
149	struct stat st1, st2;
150
151	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
152	ASSERT_NE(fh, NULL);
153	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
154	fh->handle_bytes = MAX_HANDLE_SZ;
155
156	ASSERT_EQ(name_to_handle_at(self->child_pidfd1, "", fh, &mnt_id, AT_EMPTY_PATH), 0);
157
158	ASSERT_EQ(fstat(self->child_pidfd1, &st1), 0);
159
160	pidfd = open_by_handle_at(self->pidfd, fh, 0);
161	ASSERT_GE(pidfd, 0);
162
163	ASSERT_EQ(fstat(pidfd, &st2), 0);
164	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
165
166	ASSERT_EQ(close(pidfd), 0);
167
168	pidfd = open_by_handle_at(self->pidfd, fh, O_CLOEXEC);
169	ASSERT_GE(pidfd, 0);
170
171	ASSERT_EQ(fstat(pidfd, &st2), 0);
172	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
173
174	ASSERT_EQ(close(pidfd), 0);
175
176	pidfd = open_by_handle_at(self->pidfd, fh, O_NONBLOCK);
177	ASSERT_GE(pidfd, 0);
178
179	ASSERT_EQ(fstat(pidfd, &st2), 0);
180	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
181
182	ASSERT_EQ(close(pidfd), 0);
183
184	free(fh);
185}
186
187/*
188 * Test that we can decode a pidfs file handle from a child pid
189 * namespace.
190 */
191TEST_F(file_handle, file_handle_child_pidns)
192{
193	int mnt_id;
194	struct file_handle *fh;
195	int pidfd = -EBADF;
196	struct stat st1, st2;
197
198	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
199	ASSERT_NE(fh, NULL);
200	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
201	fh->handle_bytes = MAX_HANDLE_SZ;
202
203	ASSERT_EQ(name_to_handle_at(self->child_pidfd2, "", fh, &mnt_id, AT_EMPTY_PATH), 0);
204
205	ASSERT_EQ(fstat(self->child_pidfd2, &st1), 0);
206
207	pidfd = open_by_handle_at(self->pidfd, fh, 0);
208	ASSERT_GE(pidfd, 0);
209
210	ASSERT_EQ(fstat(pidfd, &st2), 0);
211	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
212
213	ASSERT_EQ(close(pidfd), 0);
214
215	pidfd = open_by_handle_at(self->pidfd, fh, O_CLOEXEC);
216	ASSERT_GE(pidfd, 0);
217
218	ASSERT_EQ(fstat(pidfd, &st2), 0);
219	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
220
221	ASSERT_EQ(close(pidfd), 0);
222
223	pidfd = open_by_handle_at(self->pidfd, fh, O_NONBLOCK);
224	ASSERT_GE(pidfd, 0);
225
226	ASSERT_EQ(fstat(pidfd, &st2), 0);
227	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
228
229	ASSERT_EQ(close(pidfd), 0);
230
231	free(fh);
232}
233
234/*
235 * Test that we fail to decode a pidfs file handle from an ancestor
236 * child pid namespace.
237 */
238TEST_F(file_handle, file_handle_foreign_pidns)
239{
240	int mnt_id;
241	struct file_handle *fh;
242	pid_t pid;
243
244	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
245	ASSERT_NE(fh, NULL);
246	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
247	fh->handle_bytes = MAX_HANDLE_SZ;
248
249	ASSERT_EQ(name_to_handle_at(self->pidfd, "", fh, &mnt_id, AT_EMPTY_PATH), 0);
250
251	ASSERT_EQ(setns(self->child_pidfd2, CLONE_NEWUSER | CLONE_NEWPID), 0);
252
253	pid = fork();
254	ASSERT_GE(pid, 0);
255
256	if (pid == 0) {
257		int pidfd = open_by_handle_at(self->pidfd, fh, 0);
258		if (pidfd >= 0) {
259			TH_LOG("Managed to open pidfd outside of the caller's pid namespace hierarchy");
260			_exit(1);
261		}
262		_exit(0);
263	}
264
265	ASSERT_EQ(wait_for_pid(pid), 0);
266
267	free(fh);
268}
269
270/*
271 * Test that we can decode a pidfs file handle of a process that has
272 * exited but not been reaped.
273 */
274TEST_F(file_handle, pid_has_exited)
275{
276	int mnt_id, pidfd, child_pidfd3;
277	struct file_handle *fh;
278	struct stat st1, st2;
279
280	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
281	ASSERT_NE(fh, NULL);
282	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
283	fh->handle_bytes = MAX_HANDLE_SZ;
284
285	ASSERT_EQ(name_to_handle_at(self->child_pidfd3, "", fh, &mnt_id, AT_EMPTY_PATH), 0);
286
287	ASSERT_EQ(fstat(self->child_pidfd3, &st1), 0);
288
289	pidfd = open_by_handle_at(self->pidfd, fh, 0);
290	ASSERT_GE(pidfd, 0);
291
292	ASSERT_EQ(fstat(pidfd, &st2), 0);
293	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
294
295	ASSERT_EQ(close(pidfd), 0);
296
297	child_pidfd3 = self->child_pidfd3;
298	self->child_pidfd3 = -EBADF;
299	EXPECT_EQ(sys_pidfd_send_signal(child_pidfd3, SIGKILL, NULL, 0), 0);
300	EXPECT_EQ(close(child_pidfd3), 0);
301	EXPECT_EQ(sys_waitid(P_PID, self->child_pid3, NULL, WEXITED | WNOWAIT), 0);
302
303	pidfd = open_by_handle_at(self->pidfd, fh, 0);
304	ASSERT_GE(pidfd, 0);
305
306	EXPECT_EQ(sys_waitid(P_PID, self->child_pid3, NULL, WEXITED), 0);
307}
308
309/*
310 * Test that we fail to decode a pidfs file handle of a process that has
311 * already been reaped.
312 */
313TEST_F(file_handle, pid_has_been_reaped)
314{
315	int mnt_id, pidfd, child_pidfd3;
316	struct file_handle *fh;
317	struct stat st1, st2;
318
319	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
320	ASSERT_NE(fh, NULL);
321	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
322	fh->handle_bytes = MAX_HANDLE_SZ;
323
324	ASSERT_EQ(name_to_handle_at(self->child_pidfd3, "", fh, &mnt_id, AT_EMPTY_PATH), 0);
325
326	ASSERT_EQ(fstat(self->child_pidfd3, &st1), 0);
327
328	pidfd = open_by_handle_at(self->pidfd, fh, 0);
329	ASSERT_GE(pidfd, 0);
330
331	ASSERT_EQ(fstat(pidfd, &st2), 0);
332	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
333
334	ASSERT_EQ(close(pidfd), 0);
335
336	child_pidfd3 = self->child_pidfd3;
337	self->child_pidfd3 = -EBADF;
338	EXPECT_EQ(sys_pidfd_send_signal(child_pidfd3, SIGKILL, NULL, 0), 0);
339	EXPECT_EQ(close(child_pidfd3), 0);
340	EXPECT_EQ(sys_waitid(P_PID, self->child_pid3, NULL, WEXITED), 0);
341
342	pidfd = open_by_handle_at(self->pidfd, fh, 0);
343	ASSERT_LT(pidfd, 0);
344}
345
346/*
347 * Test valid flags to open a pidfd file handle. Note, that
348 * PIDFD_NONBLOCK is defined as O_NONBLOCK and O_NONBLOCK is an alias to
349 * O_NDELAY. Also note that PIDFD_THREAD is an alias for O_EXCL.
350 */
351TEST_F(file_handle, open_by_handle_at_valid_flags)
352{
353	int mnt_id;
354	struct file_handle *fh;
355	int pidfd = -EBADF;
356	struct stat st1, st2;
357
358	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
359	ASSERT_NE(fh, NULL);
360	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
361	fh->handle_bytes = MAX_HANDLE_SZ;
362
363	ASSERT_EQ(name_to_handle_at(self->child_pidfd2, "", fh, &mnt_id, AT_EMPTY_PATH), 0);
364
365	ASSERT_EQ(fstat(self->child_pidfd2, &st1), 0);
366
367	pidfd = open_by_handle_at(self->pidfd, fh,
368				  O_RDONLY |
369				  O_WRONLY |
370				  O_RDWR |
371				  O_NONBLOCK |
372				  O_NDELAY |
373				  O_CLOEXEC |
374				  O_EXCL);
375	ASSERT_GE(pidfd, 0);
376
377	ASSERT_EQ(fstat(pidfd, &st2), 0);
378	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
379
380	ASSERT_EQ(close(pidfd), 0);
381}
382
383/*
384 * Test that invalid flags passed to open a pidfd file handle are
385 * rejected.
386 */
387TEST_F(file_handle, open_by_handle_at_invalid_flags)
388{
389	int mnt_id;
390	struct file_handle *fh;
391	int pidfd = -EBADF;
392	static const struct invalid_pidfs_file_handle_flags {
393		int oflag;
394		const char *oflag_name;
395	}  invalid_pidfs_file_handle_flags[] = {
396		{ FASYNC,	"FASYNC"	},
397		{ O_CREAT,	"O_CREAT"	},
398		{ O_NOCTTY,	"O_NOCTTY"	},
399		{ O_CREAT,	"O_CREAT"	},
400		{ O_TRUNC,	"O_TRUNC"	},
401		{ O_APPEND,	"O_APPEND"	},
402		{ O_SYNC,	"O_SYNC"	},
403		{ O_DSYNC,	"O_DSYNC"	},
404		{ O_DIRECT,	"O_DIRECT"	},
405		{ O_DIRECTORY,	"O_DIRECTORY"	},
406		{ O_NOFOLLOW,	"O_NOFOLLOW"	},
407		{ O_NOATIME,	"O_NOATIME"	},
408		{ O_PATH,	"O_PATH"	},
409		{ O_TMPFILE,	"O_TMPFILE"	},
410		/*
411		 * O_LARGEFILE is added implicitly by
412		 * open_by_handle_at() so pidfs simply masks it off.
413		 */
414	};
415
416	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
417	ASSERT_NE(fh, NULL);
418	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
419	fh->handle_bytes = MAX_HANDLE_SZ;
420
421	ASSERT_EQ(name_to_handle_at(self->child_pidfd2, "", fh, &mnt_id, AT_EMPTY_PATH), 0);
422
423	for (int i = 0; i < ARRAY_SIZE(invalid_pidfs_file_handle_flags); i++) {
424		pidfd = open_by_handle_at(self->pidfd, fh, invalid_pidfs_file_handle_flags[i].oflag);
425		ASSERT_LT(pidfd, 0) {
426			TH_LOG("open_by_handle_at() succeeded with invalid flags: %s", invalid_pidfs_file_handle_flags[i].oflag_name);
427		}
428	}
429}
430
431/* Test that lookup fails. */
432TEST_F(file_handle, lookup_must_fail)
433{
434	int mnt_id;
435	struct file_handle *fh;
436
437	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
438	ASSERT_NE(fh, NULL);
439	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
440	fh->handle_bytes = MAX_HANDLE_SZ;
441
442	ASSERT_NE(name_to_handle_at(self->child_pidfd2, "lookup-is-not-possible-with-pidfs", fh, &mnt_id, AT_EMPTY_PATH), 0);
443	ASSERT_EQ(errno, ENOTDIR);
444	ASSERT_NE(name_to_handle_at(self->child_pidfd2, "lookup-is-not-possible-with-pidfs", fh, &mnt_id, 0), 0);
445	ASSERT_EQ(errno, ENOTDIR);
446}
447
448#ifndef AT_HANDLE_CONNECTABLE
449#define AT_HANDLE_CONNECTABLE 0x002
450#endif
451
452/*
453 * Test that AT_HANDLE_CONNECTABLE is rejected. Connectable file handles
454 * don't make sense for pidfs. Note that currently AT_HANDLE_CONNECTABLE
455 * is rejected because it is incompatible with AT_EMPTY_PATH which is
456 * required with pidfds as we don't support lookup.
457 */
458TEST_F(file_handle, invalid_name_to_handle_at_flags)
459{
460	int mnt_id;
461	struct file_handle *fh;
462
463	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
464	ASSERT_NE(fh, NULL);
465	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
466	fh->handle_bytes = MAX_HANDLE_SZ;
467
468	ASSERT_NE(name_to_handle_at(self->child_pidfd2, "", fh, &mnt_id, AT_EMPTY_PATH | AT_HANDLE_CONNECTABLE), 0);
469}
470
471#ifndef AT_HANDLE_FID
472#define AT_HANDLE_FID 0x200
473#endif
474
475/*
476 * Test that a request with AT_HANDLE_FID always leads to decodable file
477 * handle as pidfs always provides export operations.
478 */
479TEST_F(file_handle, valid_name_to_handle_at_flags)
480{
481	int mnt_id, pidfd;
482	struct file_handle *fh;
483	struct stat st1, st2;
484
485	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
486	ASSERT_NE(fh, NULL);
487	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
488	fh->handle_bytes = MAX_HANDLE_SZ;
489
490	ASSERT_EQ(name_to_handle_at(self->child_pidfd2, "", fh, &mnt_id, AT_EMPTY_PATH | AT_HANDLE_FID), 0);
491
492	ASSERT_EQ(fstat(self->child_pidfd2, &st1), 0);
493
494	pidfd = open_by_handle_at(self->pidfd, fh, 0);
495	ASSERT_GE(pidfd, 0);
496
497	ASSERT_EQ(fstat(pidfd, &st2), 0);
498	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
499
500	ASSERT_EQ(close(pidfd), 0);
501}
502
503/*
504 * That we decode a file handle without having to pass a pidfd.
505 */
506TEST_F(file_handle, decode_purely_based_on_file_handle)
507{
508	int mnt_id;
509	struct file_handle *fh;
510	int pidfd = -EBADF;
511	struct stat st1, st2;
512
513	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
514	ASSERT_NE(fh, NULL);
515	memset(fh, 0, sizeof(struct file_handle) + MAX_HANDLE_SZ);
516	fh->handle_bytes = MAX_HANDLE_SZ;
517
518	ASSERT_EQ(name_to_handle_at(self->child_pidfd1, "", fh, &mnt_id, AT_EMPTY_PATH), 0);
519
520	ASSERT_EQ(fstat(self->child_pidfd1, &st1), 0);
521
522	pidfd = open_by_handle_at(FD_PIDFS_ROOT, fh, 0);
523	ASSERT_GE(pidfd, 0);
524
525	ASSERT_EQ(fstat(pidfd, &st2), 0);
526	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
527
528	ASSERT_EQ(close(pidfd), 0);
529
530	pidfd = open_by_handle_at(FD_PIDFS_ROOT, fh, O_CLOEXEC);
531	ASSERT_GE(pidfd, 0);
532
533	ASSERT_EQ(fstat(pidfd, &st2), 0);
534	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
535
536	ASSERT_EQ(close(pidfd), 0);
537
538	pidfd = open_by_handle_at(FD_PIDFS_ROOT, fh, O_NONBLOCK);
539	ASSERT_GE(pidfd, 0);
540
541	ASSERT_EQ(fstat(pidfd, &st2), 0);
542	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
543
544	ASSERT_EQ(close(pidfd), 0);
545
546	pidfd = open_by_handle_at(self->pidfd, fh, 0);
547	ASSERT_GE(pidfd, 0);
548
549	ASSERT_EQ(fstat(pidfd, &st2), 0);
550	ASSERT_TRUE(st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
551
552	ASSERT_EQ(close(pidfd), 0);
553
554	pidfd = open_by_handle_at(-EBADF, fh, 0);
555	ASSERT_LT(pidfd, 0);
556
557	pidfd = open_by_handle_at(AT_FDCWD, fh, 0);
558	ASSERT_LT(pidfd, 0);
559
560	free(fh);
561}
562
563TEST_HARNESS_MAIN
~/ Read-only file preview.