1 /*
2 * Check for PTRACE_EVENT_EXEC diagnostics.
3 *
4 * Copyright (c) 2019 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2019-2020 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include <errno.h>
13 #include <pthread.h>
14 #include <stdio.h>
15 #include <unistd.h>
16 #include "scno.h"
17
18 #ifndef QUIET_MSG
19 # define QUIET_MSG 0
20 #endif
21
22 static pid_t leader;
23 static volatile unsigned int trigger;
24
25 static void *
26 thread(void *arg)
27 {
28 const char *argv[] = {((char **) arg)[0], "1", "2", NULL};
29 int tid = syscall(__NR_gettid);
30
31 printf("%-5d execveat(AT_FDCWD, \"%s\", [\"%s\", \"%s\", \"%s\"]"
32 ", NULL, 0 <pid changed to %d ...>\n"
33 #if !QUIET_MSG
34 "%-5d +++ superseded by execve in pid %d +++\n"
35 #endif
36 , tid, argv[0], argv[0], argv[1], argv[2], leader
37 #if !QUIET_MSG
38 , leader, tid
39 #endif
40 );
41
42 while (!trigger) {
43 /* Wait for the parent to enter the busy loop. */
44 }
45
46 syscall(__NR_execveat, -100, argv[0], argv, NULL, 0);
47 perror_msg_and_fail("execveat");
48 }
49
50 int
51 main(int ac, char **av)
52 {
53 setvbuf(stdout, NULL, _IONBF, 0);
54 leader = getpid();
55
56 if (ac <= 1) {
57 char *argv[] = {av[0], (char *) "1", NULL};
58 printf("%-5d execveat(AT_FDCWD, \"%s\""
59 ", [\"%s\", \"%s\"], NULL, 0) = 0\n",
60 leader, argv[0], argv[0], argv[1]);
61 syscall(__NR_execveat, -100, argv[0], argv, NULL, 0);
62 perror_msg_and_skip("execveat");
63 }
64
65 /*
66 * Since execveat is supported by the kernel,
67 * PTRACE_EVENT_EXEC support in the kernel is good enough.
68 */
69 if (ac <= 2) {
70 pthread_t t;
71 errno = pthread_create(&t, NULL, thread, av);
72 if (errno)
73 perror_msg_and_fail("pthread_create");
74
75 for (;;)
76 ++trigger;
77 }
78
79 printf("%-5d <... execveat resumed>) = 0\n"
80 "%-5d +++ exited with 0 +++\n",
81 leader, leader);
82 return 0;
83 }