0001
0002
0003 #ifndef _CLONE3_SELFTESTS_H
0004 #define _CLONE3_SELFTESTS_H
0005
0006 #define _GNU_SOURCE
0007 #include <sched.h>
0008 #include <linux/sched.h>
0009 #include <linux/types.h>
0010 #include <stdint.h>
0011 #include <syscall.h>
0012 #include <sys/wait.h>
0013
0014 #include "../kselftest.h"
0015
0016 #define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr)))
0017
0018 #ifndef CLONE_INTO_CGROUP
0019 #define CLONE_INTO_CGROUP 0x200000000ULL
0020 #endif
0021
0022 #ifndef __NR_clone3
0023 #define __NR_clone3 -1
0024 #endif
0025
0026 struct __clone_args {
0027 __aligned_u64 flags;
0028 __aligned_u64 pidfd;
0029 __aligned_u64 child_tid;
0030 __aligned_u64 parent_tid;
0031 __aligned_u64 exit_signal;
0032 __aligned_u64 stack;
0033 __aligned_u64 stack_size;
0034 __aligned_u64 tls;
0035 #ifndef CLONE_ARGS_SIZE_VER0
0036 #define CLONE_ARGS_SIZE_VER0 64
0037 #endif
0038 __aligned_u64 set_tid;
0039 __aligned_u64 set_tid_size;
0040 #ifndef CLONE_ARGS_SIZE_VER1
0041 #define CLONE_ARGS_SIZE_VER1 80
0042 #endif
0043 __aligned_u64 cgroup;
0044 #ifndef CLONE_ARGS_SIZE_VER2
0045 #define CLONE_ARGS_SIZE_VER2 88
0046 #endif
0047 };
0048
0049 static pid_t sys_clone3(struct __clone_args *args, size_t size)
0050 {
0051 fflush(stdout);
0052 fflush(stderr);
0053 return syscall(__NR_clone3, args, size);
0054 }
0055
0056 static inline void test_clone3_supported(void)
0057 {
0058 pid_t pid;
0059 struct __clone_args args = {};
0060
0061 if (__NR_clone3 < 0)
0062 ksft_exit_skip("clone3() syscall is not supported\n");
0063
0064
0065 args.exit_signal = -1;
0066 pid = sys_clone3(&args, sizeof(args));
0067 if (!pid)
0068 exit(EXIT_SUCCESS);
0069
0070 if (pid > 0) {
0071 wait(NULL);
0072 ksft_exit_fail_msg(
0073 "Managed to create child process with invalid exit_signal\n");
0074 }
0075
0076 if (errno == ENOSYS)
0077 ksft_exit_skip("clone3() syscall is not supported\n");
0078
0079 ksft_print_msg("clone3() syscall supported\n");
0080 }
0081
0082 #endif