xref: /linux/tools/testing/selftests/pidfd/pidfd_file_handle_test.c (revision 5f85bd6aeceaecd0ff3a5ee827bf75eb6141ad55)
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 
FIXTURE(file_handle)25 FIXTURE(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 
FIXTURE_SETUP(file_handle)40 FIXTURE_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 
FIXTURE_TEARDOWN(file_handle)117 FIXTURE_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  */
TEST_F(file_handle,file_handle_same_pidns)144 TEST_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  */
TEST_F(file_handle,file_handle_child_pidns)191 TEST_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  */
TEST_F(file_handle,file_handle_foreign_pidns)238 TEST_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  */
TEST_F(file_handle,pid_has_exited)274 TEST_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  */
TEST_F(file_handle,pid_has_been_reaped)313 TEST_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  */
TEST_F(file_handle,open_by_handle_at_valid_flags)351 TEST_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  */
TEST_F(file_handle,open_by_handle_at_invalid_flags)387 TEST_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. */
TEST_F(file_handle,lookup_must_fail)432 TEST_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  */
TEST_F(file_handle,invalid_name_to_handle_at_flags)458 TEST_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  */
TEST_F(file_handle,valid_name_to_handle_at_flags)479 TEST_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 TEST_HARNESS_MAIN
504