remove_on_exec.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Test for remove_on_exec.
  4. *
  5. * Copyright (C) 2021, Google LLC.
  6. */
  7. #define _GNU_SOURCE
  8. /* We need the latest siginfo from the kernel repo. */
  9. #include <sys/types.h>
  10. #include <asm/siginfo.h>
  11. #define __have_siginfo_t 1
  12. #define __have_sigval_t 1
  13. #define __have_sigevent_t 1
  14. #define __siginfo_t_defined
  15. #define __sigval_t_defined
  16. #define __sigevent_t_defined
  17. #define _BITS_SIGINFO_CONSTS_H 1
  18. #define _BITS_SIGEVENT_CONSTS_H 1
  19. #include <stdbool.h>
  20. #include <stddef.h>
  21. #include <stdint.h>
  22. #include <stdio.h>
  23. #include <linux/perf_event.h>
  24. #include <pthread.h>
  25. #include <signal.h>
  26. #include <sys/ioctl.h>
  27. #include <sys/syscall.h>
  28. #include <unistd.h>
  29. #include "../kselftest_harness.h"
  30. static volatile int signal_count;
  31. static struct perf_event_attr make_event_attr(void)
  32. {
  33. struct perf_event_attr attr = {
  34. .type = PERF_TYPE_HARDWARE,
  35. .size = sizeof(attr),
  36. .config = PERF_COUNT_HW_INSTRUCTIONS,
  37. .sample_period = 1000,
  38. .exclude_kernel = 1,
  39. .exclude_hv = 1,
  40. .disabled = 1,
  41. .inherit = 1,
  42. /*
  43. * Children normally retain their inherited event on exec; with
  44. * remove_on_exec, we'll remove their event, but the parent and
  45. * any other non-exec'd children will keep their events.
  46. */
  47. .remove_on_exec = 1,
  48. .sigtrap = 1,
  49. };
  50. return attr;
  51. }
  52. static void sigtrap_handler(int signum, siginfo_t *info, void *ucontext)
  53. {
  54. if (info->si_code != TRAP_PERF) {
  55. fprintf(stderr, "%s: unexpected si_code %d\n", __func__, info->si_code);
  56. return;
  57. }
  58. signal_count++;
  59. }
  60. FIXTURE(remove_on_exec)
  61. {
  62. struct sigaction oldact;
  63. int fd;
  64. };
  65. FIXTURE_SETUP(remove_on_exec)
  66. {
  67. struct perf_event_attr attr = make_event_attr();
  68. struct sigaction action = {};
  69. signal_count = 0;
  70. /* Initialize sigtrap handler. */
  71. action.sa_flags = SA_SIGINFO | SA_NODEFER;
  72. action.sa_sigaction = sigtrap_handler;
  73. sigemptyset(&action.sa_mask);
  74. ASSERT_EQ(sigaction(SIGTRAP, &action, &self->oldact), 0);
  75. /* Initialize perf event. */
  76. self->fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, PERF_FLAG_FD_CLOEXEC);
  77. ASSERT_NE(self->fd, -1);
  78. }
  79. FIXTURE_TEARDOWN(remove_on_exec)
  80. {
  81. close(self->fd);
  82. sigaction(SIGTRAP, &self->oldact, NULL);
  83. }
  84. /* Verify event propagates to fork'd child. */
  85. TEST_F(remove_on_exec, fork_only)
  86. {
  87. int status;
  88. pid_t pid = fork();
  89. if (pid == 0) {
  90. ASSERT_EQ(signal_count, 0);
  91. ASSERT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
  92. while (!signal_count);
  93. _exit(42);
  94. }
  95. while (!signal_count); /* Child enables event. */
  96. EXPECT_EQ(waitpid(pid, &status, 0), pid);
  97. EXPECT_EQ(WEXITSTATUS(status), 42);
  98. }
  99. /*
  100. * Verify that event does _not_ propagate to fork+exec'd child; event enabled
  101. * after fork+exec.
  102. */
  103. TEST_F(remove_on_exec, fork_exec_then_enable)
  104. {
  105. pid_t pid_exec, pid_only_fork;
  106. int pipefd[2];
  107. int tmp;
  108. /*
  109. * Non-exec child, to ensure exec does not affect inherited events of
  110. * other children.
  111. */
  112. pid_only_fork = fork();
  113. if (pid_only_fork == 0) {
  114. /* Block until parent enables event. */
  115. while (!signal_count);
  116. _exit(42);
  117. }
  118. ASSERT_NE(pipe(pipefd), -1);
  119. pid_exec = fork();
  120. if (pid_exec == 0) {
  121. ASSERT_NE(dup2(pipefd[1], STDOUT_FILENO), -1);
  122. close(pipefd[0]);
  123. execl("/proc/self/exe", "exec_child", NULL);
  124. _exit((perror("exec failed"), 1));
  125. }
  126. close(pipefd[1]);
  127. ASSERT_EQ(waitpid(pid_exec, &tmp, WNOHANG), 0); /* Child is running. */
  128. /* Wait for exec'd child to start spinning. */
  129. EXPECT_EQ(read(pipefd[0], &tmp, sizeof(int)), sizeof(int));
  130. EXPECT_EQ(tmp, 42);
  131. close(pipefd[0]);
  132. /* Now we can enable the event, knowing the child is doing work. */
  133. EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
  134. /* If the event propagated to the exec'd child, it will exit normally... */
  135. usleep(100000); /* ... give time for event to trigger (in case of bug). */
  136. EXPECT_EQ(waitpid(pid_exec, &tmp, WNOHANG), 0); /* Should still be running. */
  137. EXPECT_EQ(kill(pid_exec, SIGKILL), 0);
  138. /* Verify removal from child did not affect this task's event. */
  139. tmp = signal_count;
  140. while (signal_count == tmp); /* Should not hang! */
  141. /* Nor should it have affected the first child. */
  142. EXPECT_EQ(waitpid(pid_only_fork, &tmp, 0), pid_only_fork);
  143. EXPECT_EQ(WEXITSTATUS(tmp), 42);
  144. }
  145. /*
  146. * Verify that event does _not_ propagate to fork+exec'd child; event enabled
  147. * before fork+exec.
  148. */
  149. TEST_F(remove_on_exec, enable_then_fork_exec)
  150. {
  151. pid_t pid_exec;
  152. int tmp;
  153. EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
  154. pid_exec = fork();
  155. if (pid_exec == 0) {
  156. execl("/proc/self/exe", "exec_child", NULL);
  157. _exit((perror("exec failed"), 1));
  158. }
  159. /*
  160. * The child may exit abnormally at any time if the event propagated and
  161. * a SIGTRAP is sent before the handler was set up.
  162. */
  163. usleep(100000); /* ... give time for event to trigger (in case of bug). */
  164. EXPECT_EQ(waitpid(pid_exec, &tmp, WNOHANG), 0); /* Should still be running. */
  165. EXPECT_EQ(kill(pid_exec, SIGKILL), 0);
  166. /* Verify removal from child did not affect this task's event. */
  167. tmp = signal_count;
  168. while (signal_count == tmp); /* Should not hang! */
  169. }
  170. TEST_F(remove_on_exec, exec_stress)
  171. {
  172. pid_t pids[30];
  173. int i, tmp;
  174. for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) {
  175. pids[i] = fork();
  176. if (pids[i] == 0) {
  177. execl("/proc/self/exe", "exec_child", NULL);
  178. _exit((perror("exec failed"), 1));
  179. }
  180. /* Some forked with event disabled, rest with enabled. */
  181. if (i > 10)
  182. EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
  183. }
  184. usleep(100000); /* ... give time for event to trigger (in case of bug). */
  185. for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) {
  186. /* All children should still be running. */
  187. EXPECT_EQ(waitpid(pids[i], &tmp, WNOHANG), 0);
  188. EXPECT_EQ(kill(pids[i], SIGKILL), 0);
  189. }
  190. /* Verify event is still alive. */
  191. tmp = signal_count;
  192. while (signal_count == tmp);
  193. }
  194. /* For exec'd child. */
  195. static void exec_child(void)
  196. {
  197. struct sigaction action = {};
  198. const int val = 42;
  199. /* Set up sigtrap handler in case we erroneously receive a trap. */
  200. action.sa_flags = SA_SIGINFO | SA_NODEFER;
  201. action.sa_sigaction = sigtrap_handler;
  202. sigemptyset(&action.sa_mask);
  203. if (sigaction(SIGTRAP, &action, NULL))
  204. _exit((perror("sigaction failed"), 1));
  205. /* Signal parent that we're starting to spin. */
  206. if (write(STDOUT_FILENO, &val, sizeof(int)) == -1)
  207. _exit((perror("write failed"), 1));
  208. /* Should hang here until killed. */
  209. while (!signal_count);
  210. }
  211. #define main test_main
  212. TEST_HARNESS_MAIN
  213. #undef main
  214. int main(int argc, char *argv[])
  215. {
  216. if (!strcmp(argv[0], "exec_child")) {
  217. exec_child();
  218. return 1;
  219. }
  220. return test_main(argc, argv);
  221. }