11 #include <asm/unistd.h>
14 #include <sys/types.h>
16 #include <sys/syscall.h>
19 #include <sys/socket.h>
34 #include "config.h" // for VERSION
36 char *progname
= NULL
;
38 unsigned int page_size
;
39 unsigned int num_online_cpus
;
43 #define SHM_PROT_PAGES 30
45 static int create_shm(void)
48 unsigned int shm_pages
;
50 shm_pages
= ((sizeof(struct shm_s
) + page_size
- 1) & ~(page_size
- 1)) / page_size
;
52 /* Waste some address space to set up some "protection" near the SHM location. */
53 p
= alloc_shared((SHM_PROT_PAGES
+ shm_pages
+ SHM_PROT_PAGES
) * page_size
);
59 mprotect(p
, SHM_PROT_PAGES
* page_size
, PROT_NONE
);
60 mprotect(p
+ (SHM_PROT_PAGES
+ shm_pages
) * page_size
,
61 SHM_PROT_PAGES
* page_size
, PROT_NONE
);
63 shm
= p
+ SHM_PROT_PAGES
* page_size
;
65 memset(shm
, 0, sizeof(struct shm_s
));
67 shm
->total_syscalls_done
= 1;
70 memset(shm
->pids
, EMPTY_PIDSLOT
, sizeof(shm
->pids
));
72 shm
->nr_active_syscalls
= 0;
73 shm
->nr_active_32bit_syscalls
= 0;
74 shm
->nr_active_64bit_syscalls
= 0;
75 memset(shm
->active_syscalls
, 0, sizeof(shm
->active_syscalls
));
76 memset(shm
->active_syscalls32
, 0, sizeof(shm
->active_syscalls32
));
77 memset(shm
->active_syscalls64
, 0, sizeof(shm
->active_syscalls64
));
79 /* Overwritten later in setup_shm_postargs if user passed -s */
80 shm
->seed
= new_seed();
82 /* Set seed in parent thread */
88 static void setup_shm_postargs(void)
90 if (user_set_seed
== TRUE
) {
91 shm
->seed
= init_seed(seed
);
92 /* Set seed in parent thread */
96 if (user_specified_children
!= 0)
97 shm
->max_children
= user_specified_children
;
99 shm
->max_children
= sysconf(_SC_NPROCESSORS_ONLN
);
101 if (shm
->max_children
> MAX_NR_CHILDREN
) {
102 outputerr("Increase MAX_NR_CHILDREN!\n");
107 /* This is run *after* we've parsed params */
108 static int munge_tables(void)
112 /* By default, all syscall entries will be disabled.
113 * If we didn't pass -c, -x or -r, mark all syscalls active.
115 if ((do_specific_syscall
== FALSE
) && (do_exclude_syscall
== FALSE
) && (random_selection
== FALSE
) && (desired_group
== GROUP_NONE
))
116 mark_all_syscalls_active();
118 if (desired_group
!= GROUP_NONE
) {
119 ret
= setup_syscall_group(desired_group
);
124 if (random_selection
== TRUE
)
125 enable_random_syscalls();
127 /* If we saw a '-x', set all syscalls to enabled, then selectively disable.
128 * Unless we've started enabling them already (with -r)
130 if (do_exclude_syscall
== TRUE
) {
131 if (random_selection
== FALSE
)
132 mark_all_syscalls_active();
133 deactivate_disabled_syscalls();
136 /* if we passed -n, make sure there's no VM/VFS syscalls enabled. */
137 if (no_files
== TRUE
)
138 disable_non_net_syscalls();
140 sanity_check_tables();
142 count_syscalls_enabled();
145 display_enabled_syscalls();
147 if (validate_syscall_tables() == FALSE
) {
148 outputstd("No syscalls were enabled!\n");
149 outputstd("Use 32bit:%d 64bit:%d\n", use_32bit
, use_64bit
);
157 * just in case we're not using the test.sh harness, we
158 * change to the tmp dir if it exists.
160 static void change_tmp_dir(void)
163 const char tmpdir
[]="tmp/";
166 /* Check if it exists, bail early if it doesn't */
167 ret
= (lstat(tmpdir
, &sb
));
171 /* Just in case a previous run screwed the perms. */
172 ret
= chmod(tmpdir
, 0755);
174 output(0, "Couldn't chmod %s to 0755.\n", tmpdir
);
178 output(0, "Couldn't change to %s\n", tmpdir
);
182 int main(int argc
, char* argv
[])
184 int ret
= EXIT_SUCCESS
;
188 outputstd("Trinity v" __stringify(VERSION
) " Dave Jones <davej@redhat.com>\n");
194 page_size
= getpagesize();
195 num_online_cpus
= sysconf(_SC_NPROCESSORS_ONLN
);
197 select_syscall_tables();
202 parse_args(argc
, argv
);
203 outputstd("Done parsing arguments.\n");
205 if (kernel_taint_mask
!= (int)0xFFFFFFFF) {
206 outputstd("Custom kernel taint mask has been specified: 0x%08x (%d).\n", kernel_taint_mask
, kernel_taint_mask
);
209 setup_shm_postargs();
214 if (munge_tables() == FALSE
) {
219 if (show_syscall_list
== TRUE
) {
220 dump_syscall_tables();
226 if (show_ioctl_list
== TRUE
) {
232 if (dangerous
== TRUE
) {
233 outputstd("DANGER: RUNNING AS ROOT.\n");
234 outputstd("Unless you are running in a virtual machine, this could cause serious problems such as overwriting CMOS\n");
235 outputstd("or similar which could potentially make this machine unbootable without a firmware reset.\n\n");
236 outputstd("ctrl-c now unless you really know what you are doing.\n");
237 for (i
= 10; i
> 0; i
--) {
238 outputstd("Continuing in %d seconds.\r", i
);
239 (void)fflush(stdout
);
243 outputstd("Don't run as root (or pass --dangerous if you know what you are doing).\n");
248 if (do_specific_proto
== TRUE
)
249 find_specific_proto(specific_proto_optarg
);
257 setup_main_signals();
259 kernel_taint_initial
= check_tainted();
260 if (kernel_taint_initial
!= 0) {
261 output(0, "Kernel was tainted on startup. Will ignore flags that are already set.\n");
266 /* check if we ctrl'c or something went wrong during init. */
267 if (shm
->exit_reason
!= STILL_RUNNING
)
275 waitpid(watchdog_pid
, &childstatus
, 0);
277 output(0, "\nRan %ld syscalls. Successes: %ld Failures: %ld\n",
278 shm
->total_syscalls_done
- 1, shm
->successes
, shm
->failures
);
284 for (i
= 0; i
< nr_sockets
; i
++) {
286 struct linger ling
= { .l_onoff
= FALSE
, };
288 ling
.l_onoff
= FALSE
; /* linger active */
289 r
= setsockopt(shm
->socket_fds
[i
], SOL_SOCKET
, SO_LINGER
, &ling
, sizeof(struct linger
));
291 perror("setsockopt");
292 r
= shutdown(shm
->socket_fds
[i
], SHUT_RDWR
);
295 close(shm
->socket_fds
[i
]);