1 /*
2 * Check decoding of pidfd_open syscall.
3 *
4 * Copyright (c) 2019 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2019-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include "scno.h"
13
14 #include <fcntl.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 #include "kernel_fcntl.h"
18 #include "pidns.h"
19
20 static const char *errstr;
21
22 static long
23 k_pidfd_open(const unsigned int pid, const unsigned int flags)
24 {
25 const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
26 const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
27 const kernel_ulong_t arg1 = fill | pid;
28 const kernel_ulong_t arg2 = fill | flags;
29 const long rc = syscall(__NR_pidfd_open,
30 arg1, arg2, bad, bad, bad, bad);
31 errstr = sprintrc(rc);
32 return rc;
33 }
34
35 int
36 main(void)
37 {
38 PIDNS_TEST_INIT;
39
40 #if defined PATH_TRACING || defined PRINT_PATHS
41 skip_if_unavailable("/proc/self/fd/");
42 #endif
43
44 #ifdef PATH_TRACING
45 static const char path_full[] = "/dev/full";
46 (void) close(0);
47 if (open(path_full, O_WRONLY))
48 perror_msg_and_skip(path_full);
49 #endif
50
51 k_pidfd_open(0, 0);
52 #ifndef PATH_TRACING
53 pidns_print_leader();
54 printf("pidfd_open(0, 0) = %s\n", errstr);
55 #endif
56
57 k_pidfd_open(-1U, 0);
58 #ifndef PATH_TRACING
59 pidns_print_leader();
60 printf("pidfd_open(-1, 0) = %s\n", errstr);
61 #endif
62
63 k_pidfd_open(0, O_NONBLOCK);
64 #ifndef PATH_TRACING
65 pidns_print_leader();
66 printf("pidfd_open(0, PIDFD_NONBLOCK) = %s\n", errstr);
67 #endif
68
69 k_pidfd_open(-1U, O_NONBLOCK);
70 #ifndef PATH_TRACING
71 pidns_print_leader();
72 printf("pidfd_open(-1, PIDFD_NONBLOCK) = %s\n", errstr);
73 #endif
74
75 k_pidfd_open(0, -1U);
76 #ifndef PATH_TRACING
77 pidns_print_leader();
78 printf("pidfd_open(0, PIDFD_NONBLOCK|%#x) = %s\n",
79 -1U & (~O_NONBLOCK), errstr);
80 #endif
81
82 const unsigned int flags = 0xfacefeed & (~O_NONBLOCK);
83 const int pid = getpid();
84
85 k_pidfd_open(pid, flags);
86 #ifndef PATH_TRACING
87 const char *pid_str = pidns_pid2str(PT_TGID);
88 pidns_print_leader();
89 printf("pidfd_open(%d%s, %#x /* PIDFD_??? */) = %s\n",
90 pid, pid_str, flags, errstr);
91 #endif
92
93 #ifdef PRINT_PATHS
94 long rc = k_pidfd_open(pid, 0);
95 if (rc < 0)
96 perror_msg_and_skip("pidfd_open");
97 #else
98 k_pidfd_open(pid, 0);
99 #endif
100
101 #ifndef PATH_TRACING
102 pidns_print_leader();
103 printf("pidfd_open(%d%s, 0) = "
104 # if defined PRINT_PIDFD
105 "%ld<pid:%d>\n", pid, pid_str, rc, pid
106 # elif defined PRINT_PATHS
107 "%ld<anon_inode:[pidfd]>\n", pid, pid_str, rc
108 # else
109 "%s\n", pid, pid_str, errstr
110 # endif
111 );
112 #endif
113
114 pidns_print_leader();
115 puts("+++ exited with 0 +++");
116 return 0;
117 }