clone3_selftests.h 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _CLONE3_SELFTESTS_H
  3. #define _CLONE3_SELFTESTS_H
  4. #define _GNU_SOURCE
  5. #include <sched.h>
  6. #include <linux/sched.h>
  7. #include <linux/types.h>
  8. #include <stdint.h>
  9. #include <syscall.h>
  10. #include <sys/wait.h>
  11. #include "kselftest.h"
  12. #define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr)))
  13. #ifndef __NR_clone3
  14. #define __NR_clone3 435
  15. #endif
  16. struct __clone_args {
  17. __aligned_u64 flags;
  18. __aligned_u64 pidfd;
  19. __aligned_u64 child_tid;
  20. __aligned_u64 parent_tid;
  21. __aligned_u64 exit_signal;
  22. __aligned_u64 stack;
  23. __aligned_u64 stack_size;
  24. __aligned_u64 tls;
  25. __aligned_u64 set_tid;
  26. __aligned_u64 set_tid_size;
  27. __aligned_u64 cgroup;
  28. };
  29. static pid_t sys_clone3(struct __clone_args *args, size_t size)
  30. {
  31. fflush(stdout);
  32. fflush(stderr);
  33. return syscall(__NR_clone3, args, size);
  34. }
  35. static inline void test_clone3_supported(void)
  36. {
  37. pid_t pid;
  38. struct __clone_args args = {};
  39. if (__NR_clone3 < 0)
  40. ksft_exit_skip("clone3() syscall is not supported\n");
  41. /* Set to something that will always cause EINVAL. */
  42. args.exit_signal = -1;
  43. pid = sys_clone3(&args, sizeof(args));
  44. if (!pid)
  45. exit(EXIT_SUCCESS);
  46. if (pid > 0) {
  47. wait(NULL);
  48. ksft_exit_fail_msg(
  49. "Managed to create child process with invalid exit_signal\n");
  50. }
  51. if (errno == ENOSYS)
  52. ksft_exit_skip("clone3() syscall is not supported\n");
  53. ksft_print_msg("clone3() syscall supported\n");
  54. }
  55. #endif /* _CLONE3_SELFTESTS_H */