1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 #ifndef __PIDFD_H 4 #define __PIDFD_H 5 6 #define _GNU_SOURCE 7 #include <errno.h> 8 #include <fcntl.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/ioctl.h> 16 #include <sys/types.h> 17 #include <sys/wait.h> 18 19 #include "../kselftest.h" 20 #include "../clone3/clone3_selftests.h" 21 22 #ifndef FD_PIDFS_ROOT 23 #define FD_PIDFS_ROOT -10002 24 #endif 25 26 #ifndef P_PIDFD 27 #define P_PIDFD 3 28 #endif 29 30 #ifndef CLONE_NEWTIME 31 #define CLONE_NEWTIME 0x00000080 32 #endif 33 34 #ifndef CLONE_PIDFD 35 #define CLONE_PIDFD 0x00001000 36 #endif 37 38 #ifndef __NR_pidfd_open 39 #define __NR_pidfd_open 434 40 #endif 41 42 #ifndef __NR_pidfd_send_signal 43 #define __NR_pidfd_send_signal 424 44 #endif 45 46 #ifndef __NR_clone3 47 #define __NR_clone3 435 48 #endif 49 50 #ifndef __NR_pidfd_getfd 51 #define __NR_pidfd_getfd 438 52 #endif 53 54 #ifndef PIDFD_NONBLOCK 55 #define PIDFD_NONBLOCK O_NONBLOCK 56 #endif 57 58 #ifndef PIDFD_SELF_THREAD 59 #define PIDFD_SELF_THREAD -10000 /* Current thread. */ 60 #endif 61 62 #ifndef PIDFD_SELF_THREAD_GROUP 63 #define PIDFD_SELF_THREAD_GROUP -10001 /* Current thread group leader. */ 64 #endif 65 66 #ifndef PIDFD_SELF 67 #define PIDFD_SELF PIDFD_SELF_THREAD 68 #endif 69 70 #ifndef PIDFD_SELF_PROCESS 71 #define PIDFD_SELF_PROCESS PIDFD_SELF_THREAD_GROUP 72 #endif 73 74 #ifndef PIDFS_IOCTL_MAGIC 75 #define PIDFS_IOCTL_MAGIC 0xFF 76 #endif 77 78 #ifndef PIDFD_GET_CGROUP_NAMESPACE 79 #define PIDFD_GET_CGROUP_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 1) 80 #endif 81 82 #ifndef PIDFD_GET_IPC_NAMESPACE 83 #define PIDFD_GET_IPC_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 2) 84 #endif 85 86 #ifndef PIDFD_GET_MNT_NAMESPACE 87 #define PIDFD_GET_MNT_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 3) 88 #endif 89 90 #ifndef PIDFD_GET_NET_NAMESPACE 91 #define PIDFD_GET_NET_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 4) 92 #endif 93 94 #ifndef PIDFD_GET_PID_NAMESPACE 95 #define PIDFD_GET_PID_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 5) 96 #endif 97 98 #ifndef PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE 99 #define PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 6) 100 #endif 101 102 #ifndef PIDFD_GET_TIME_NAMESPACE 103 #define PIDFD_GET_TIME_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 7) 104 #endif 105 106 #ifndef PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE 107 #define PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 8) 108 #endif 109 110 #ifndef PIDFD_GET_USER_NAMESPACE 111 #define PIDFD_GET_USER_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 9) 112 #endif 113 114 #ifndef PIDFD_GET_UTS_NAMESPACE 115 #define PIDFD_GET_UTS_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 10) 116 #endif 117 118 #ifndef PIDFD_GET_INFO 119 #define PIDFD_GET_INFO _IOWR(PIDFS_IOCTL_MAGIC, 11, struct pidfd_info) 120 #endif 121 122 #ifndef PIDFD_INFO_PID 123 #define PIDFD_INFO_PID (1UL << 0) /* Always returned, even if not requested */ 124 #endif 125 126 #ifndef PIDFD_INFO_CREDS 127 #define PIDFD_INFO_CREDS (1UL << 1) /* Always returned, even if not requested */ 128 #endif 129 130 #ifndef PIDFD_INFO_CGROUPID 131 #define PIDFD_INFO_CGROUPID (1UL << 2) /* Always returned if available, even if not requested */ 132 #endif 133 134 #ifndef PIDFD_INFO_EXIT 135 #define PIDFD_INFO_EXIT (1UL << 3) /* Always returned if available, even if not requested */ 136 #endif 137 138 #ifndef PIDFD_INFO_COREDUMP 139 #define PIDFD_INFO_COREDUMP (1UL << 4) 140 #endif 141 142 #ifndef PIDFD_COREDUMPED 143 #define PIDFD_COREDUMPED (1U << 0) /* Did crash and... */ 144 #endif 145 146 #ifndef PIDFD_COREDUMP_SKIP 147 #define PIDFD_COREDUMP_SKIP (1U << 1) /* coredumping generation was skipped. */ 148 #endif 149 150 #ifndef PIDFD_COREDUMP_USER 151 #define PIDFD_COREDUMP_USER (1U << 2) /* coredump was done as the user. */ 152 #endif 153 154 #ifndef PIDFD_COREDUMP_ROOT 155 #define PIDFD_COREDUMP_ROOT (1U << 3) /* coredump was done as root. */ 156 #endif 157 158 #ifndef PIDFD_THREAD 159 #define PIDFD_THREAD O_EXCL 160 #endif 161 162 struct pidfd_info { 163 __u64 mask; 164 __u64 cgroupid; 165 __u32 pid; 166 __u32 tgid; 167 __u32 ppid; 168 __u32 ruid; 169 __u32 rgid; 170 __u32 euid; 171 __u32 egid; 172 __u32 suid; 173 __u32 sgid; 174 __u32 fsuid; 175 __u32 fsgid; 176 __s32 exit_code; 177 __u32 coredump_mask; 178 __u32 __spare1; 179 }; 180 181 /* 182 * The kernel reserves 300 pids via RESERVED_PIDS in kernel/pid.c 183 * That means, when it wraps around any pid < 300 will be skipped. 184 * So we need to use a pid > 300 in order to test recycling. 185 */ 186 #define PID_RECYCLE 1000 187 188 /* 189 * Define a few custom error codes for the child process to clearly indicate 190 * what is happening. This way we can tell the difference between a system 191 * error, a test error, etc. 192 */ 193 #define PIDFD_PASS 0 194 #define PIDFD_FAIL 1 195 #define PIDFD_ERROR 2 196 #define PIDFD_SKIP 3 197 #define PIDFD_XFAIL 4 198 199 static inline int sys_waitid(int which, pid_t pid, siginfo_t *info, int options) 200 { 201 return syscall(__NR_waitid, which, pid, info, options, NULL); 202 } 203 204 static inline int wait_for_pid(pid_t pid) 205 { 206 int status, ret; 207 208 again: 209 ret = waitpid(pid, &status, 0); 210 if (ret == -1) { 211 if (errno == EINTR) 212 goto again; 213 214 ksft_print_msg("waitpid returned -1, errno=%d\n", errno); 215 return -1; 216 } 217 218 if (!WIFEXITED(status)) { 219 ksft_print_msg( 220 "waitpid !WIFEXITED, WIFSIGNALED=%d, WTERMSIG=%d\n", 221 WIFSIGNALED(status), WTERMSIG(status)); 222 return -1; 223 } 224 225 ret = WEXITSTATUS(status); 226 return ret; 227 } 228 229 static inline int sys_pidfd_open(pid_t pid, unsigned int flags) 230 { 231 return syscall(__NR_pidfd_open, pid, flags); 232 } 233 234 static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info, 235 unsigned int flags) 236 { 237 return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags); 238 } 239 240 static inline int sys_pidfd_getfd(int pidfd, int fd, int flags) 241 { 242 return syscall(__NR_pidfd_getfd, pidfd, fd, flags); 243 } 244 245 static inline int sys_memfd_create(const char *name, unsigned int flags) 246 { 247 return syscall(__NR_memfd_create, name, flags); 248 } 249 250 static inline pid_t create_child(int *pidfd, unsigned flags) 251 { 252 struct __clone_args args = { 253 .flags = CLONE_PIDFD | flags, 254 .exit_signal = SIGCHLD, 255 .pidfd = ptr_to_u64(pidfd), 256 }; 257 258 return sys_clone3(&args, sizeof(struct __clone_args)); 259 } 260 261 static inline ssize_t read_nointr(int fd, void *buf, size_t count) 262 { 263 ssize_t ret; 264 265 do { 266 ret = read(fd, buf, count); 267 } while (ret < 0 && errno == EINTR); 268 269 return ret; 270 } 271 272 static inline ssize_t write_nointr(int fd, const void *buf, size_t count) 273 { 274 ssize_t ret; 275 276 do { 277 ret = write(fd, buf, count); 278 } while (ret < 0 && errno == EINTR); 279 280 return ret; 281 } 282 283 static inline int sys_execveat(int dirfd, const char *pathname, 284 char *const argv[], char *const envp[], 285 int flags) 286 { 287 return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags); 288 } 289 290 #endif /* __PIDFD_H */ 291