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