clone3_selftests.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 CLONE_INTO_CGROUP
  14. #define CLONE_INTO_CGROUP 0x200000000ULL /* Clone into a specific cgroup given the right permissions. */
  15. #endif
  16. #ifndef __NR_clone3
  17. #define __NR_clone3 -1
  18. #endif
  19. struct __clone_args {
  20. __aligned_u64 flags;
  21. __aligned_u64 pidfd;
  22. __aligned_u64 child_tid;
  23. __aligned_u64 parent_tid;
  24. __aligned_u64 exit_signal;
  25. __aligned_u64 stack;
  26. __aligned_u64 stack_size;
  27. __aligned_u64 tls;
  28. #ifndef CLONE_ARGS_SIZE_VER0
  29. #define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */
  30. #endif
  31. __aligned_u64 set_tid;
  32. __aligned_u64 set_tid_size;
  33. #ifndef CLONE_ARGS_SIZE_VER1
  34. #define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */
  35. #endif
  36. __aligned_u64 cgroup;
  37. #ifndef CLONE_ARGS_SIZE_VER2
  38. #define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */
  39. #endif
  40. };
  41. static pid_t sys_clone3(struct __clone_args *args, size_t size)
  42. {
  43. fflush(stdout);
  44. fflush(stderr);
  45. return syscall(__NR_clone3, args, size);
  46. }
  47. static inline void test_clone3_supported(void)
  48. {
  49. pid_t pid;
  50. struct __clone_args args = {};
  51. if (__NR_clone3 < 0)
  52. ksft_exit_skip("clone3() syscall is not supported\n");
  53. /* Set to something that will always cause EINVAL. */
  54. args.exit_signal = -1;
  55. pid = sys_clone3(&args, sizeof(args));
  56. if (!pid)
  57. exit(EXIT_SUCCESS);
  58. if (pid > 0) {
  59. wait(NULL);
  60. ksft_exit_fail_msg(
  61. "Managed to create child process with invalid exit_signal\n");
  62. }
  63. if (errno == ENOSYS)
  64. ksft_exit_skip("clone3() syscall is not supported\n");
  65. ksft_print_msg("clone3() syscall supported\n");
  66. }
  67. #endif /* _CLONE3_SELFTESTS_H */