add F_GETOWNER_UIDS fcntl flag
[trinity.git] / params.c
blob86d15cc2f741b547dcec67fc6aac7ad7f6e34971
1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <getopt.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
9 #include "trinity.h" // progname
10 #include "random.h"
11 #include "syscall.h"
12 #include "log.h"
13 #include "net.h"
14 #include "params.h"
15 #include "protocols.h"
16 #include "tables.h"
18 #define TAINT_NAME_LEN 32
20 bool debug = FALSE;
22 bool do_specific_syscall = FALSE;
23 bool do_exclude_syscall = FALSE;
25 bool do_32_arch = TRUE;
26 bool do_64_arch = TRUE;
28 unsigned int specific_proto = 0;
29 unsigned int user_specified_children = 0;
31 bool do_specific_proto = FALSE;
32 bool no_protos[TRINITY_PF_MAX];
34 bool dopause = FALSE;
35 bool show_syscall_list = FALSE;
36 bool show_ioctl_list = FALSE;
37 unsigned char quiet_level = 0;
38 bool verbose = FALSE;
39 bool monochrome = FALSE;
40 bool dangerous = FALSE;
41 bool logging = TRUE;
42 bool do_syslog = FALSE;
43 bool random_selection = FALSE;
44 unsigned int random_selection_num;
45 bool no_files = FALSE;
47 bool user_set_seed = FALSE;
49 unsigned char desired_group = GROUP_NONE;
51 char *specific_proto_optarg;
53 char *victim_path;
55 int kernel_taint_initial = 0;
56 int kernel_taint_mask = 0xFFFFFFFF;
57 bool kernel_taint_param_occured = FALSE;
59 static void usage(void)
61 outputerr("%s\n", progname);
62 outputerr(" --arch, -a: selects syscalls for the specified architecture (32 or 64). Both by default.\n");
63 outputerr(" --children,-C: specify number of child processes\n");
64 outputerr(" --debug,-D: enable debug\n");
65 outputerr(" --exclude,-x: don't call a specific syscall\n");
66 outputerr(" --group,-g: only run syscalls from a certain group (So far just 'vm').\n");
67 outputerr(" --ioctls,-I: list all ioctls.\n");
68 outputerr(" --kernel_taint, -T: controls which kernel taint flags should be considered, for more details refer to README file. \n");
69 outputerr(" --list,-L: list all syscalls known on this architecture.\n");
70 outputerr(" --logging,-l: (off=disable logging).\n");
71 outputerr(" --monochrome,-m: don't output ANSI codes\n");
72 outputerr(" --no_files,-n: Only pass sockets as fd's, not files\n");
73 outputerr(" --proto,-P: specify specific network protocol for sockets.\n");
74 outputerr(" --no_proto,-E: specify network protocols to be excluded from testing.\n");
75 outputerr(" --quiet,-q: less output.\n");
76 outputerr(" --random,-r#: pick N syscalls at random and just fuzz those\n");
77 outputerr(" --syslog,-S: log important info to syslog. (useful if syslog is remote)\n");
78 outputerr(" --verbose,-v: increase output verbosity.\n");
79 outputerr(" --victims,-V: path to victim files.\n");
80 outputerr("\n");
81 outputerr(" -c#,@: target specific syscall (takes syscall name as parameter and optionally 32 or 64 as bit-width. Default:both).\n");
82 outputerr(" -N#: do # syscalls then exit.\n");
83 outputerr(" -p: pause after syscall.\n");
84 outputerr(" -s#: use # as random seed.\n");
85 exit(EXIT_SUCCESS);
88 static const struct option longopts[] = {
89 { "children", required_argument, NULL, 'C' },
90 { "dangerous", no_argument, NULL, 'd' },
91 { "debug", no_argument, NULL, 'D' },
92 { "exclude", required_argument, NULL, 'x' },
93 { "group", required_argument, NULL, 'g' },
94 { "kernel_taint", required_argument, NULL, 'T' },
95 { "help", no_argument, NULL, 'h' },
96 { "list", no_argument, NULL, 'L' },
97 { "ioctls", no_argument, NULL, 'I' },
98 { "logging", required_argument, NULL, 'l' },
99 { "monochrome", no_argument, NULL, 'm' },
100 { "no_files", no_argument, NULL, 'n' },
101 { "proto", required_argument, NULL, 'P' },
102 { "no_proto", required_argument, NULL, 'E' },
103 { "random", required_argument, NULL, 'r' },
104 { "quiet", no_argument, NULL, 'q' },
105 { "syslog", no_argument, NULL, 'S' },
106 { "victims", required_argument, NULL, 'V' },
107 { "verbose", no_argument, NULL, 'v' },
108 { "arch", required_argument, NULL, 'a' },
109 { NULL, 0, NULL, 0 } };
111 static void toggle_taint_flag(int bit) {
112 kernel_taint_mask |= (1 << bit);
115 static void toggle_taint_flag_by_name(char *beg, char *end) {
116 char flagname[TAINT_NAME_LEN];
117 char *name;
118 int maxlen;
120 if (end == NULL) {
121 name = beg;
122 } else {
123 name = flagname;
124 maxlen = end - beg;
125 if (maxlen > (TAINT_NAME_LEN - 1))
126 maxlen = TAINT_NAME_LEN - 1;
127 strncpy(flagname, beg, maxlen);
128 flagname[maxlen] = 0;
131 if (strcmp(name,"PROPRIETARY_MODULE") == 0)
132 toggle_taint_flag(TAINT_PROPRIETARY_MODULE);
133 else if (strcmp(name,"FORCED_MODULE") == 0)
134 toggle_taint_flag(TAINT_FORCED_MODULE);
135 else if (strcmp(name,"UNSAFE_SMP") == 0)
136 toggle_taint_flag(TAINT_UNSAFE_SMP);
137 else if (strcmp(name,"FORCED_RMMOD") == 0)
138 toggle_taint_flag(TAINT_FORCED_RMMOD);
139 else if (strcmp(name,"MACHINE_CHECK") == 0)
140 toggle_taint_flag(TAINT_MACHINE_CHECK);
141 else if (strcmp(name,"BAD_PAGE") == 0)
142 toggle_taint_flag(TAINT_BAD_PAGE);
143 else if (strcmp(name,"USER") == 0)
144 toggle_taint_flag(TAINT_USER);
145 else if (strcmp(name,"DIE") == 0)
146 toggle_taint_flag(TAINT_DIE);
147 else if (strcmp(name,"OVERRIDDEN_ACPI_TABLE") == 0)
148 toggle_taint_flag(TAINT_OVERRIDDEN_ACPI_TABLE);
149 else if (strcmp(name,"WARN") == 0)
150 toggle_taint_flag(TAINT_WARN);
151 else if (strcmp(name,"CRAP") == 0)
152 toggle_taint_flag(TAINT_CRAP);
153 else if (strcmp(name,"FIRMWARE_WORKAROUND") == 0)
154 toggle_taint_flag(TAINT_FIRMWARE_WORKAROUND);
155 else if (strcmp(name,"OOT_MODULE") == 0)
156 toggle_taint_flag(TAINT_OOT_MODULE);
157 else {
158 outputerr("Unrecognizable kernel taint flag \"%s\".\n", name);
159 exit(EXIT_FAILURE);
163 static void process_taint_arg(char *taintarg) {
164 char *beg, *end;
166 if (kernel_taint_param_occured == FALSE) {
167 kernel_taint_param_occured = TRUE;
168 kernel_taint_mask = 0; //We now only care about flags that user specified.
171 beg = taintarg;
172 end = strchr(beg, ',');
173 while(end != NULL) {
174 toggle_taint_flag_by_name(beg,end);
175 beg = end + 1;
176 end = strchr(beg, ',');
178 toggle_taint_flag_by_name(beg,end);
181 void parse_args(int argc, char *argv[])
183 int opt;
185 while ((opt = getopt_long(argc, argv, "a:c:C:dDg:hIl:LN:mnP:E:pqr:s:T:SV:vx:", longopts, NULL)) != -1) {
186 switch (opt) {
187 default:
188 if (opt == '?')
189 exit(EXIT_FAILURE);
190 else
191 outputstd("opt:%c\n", opt);
192 return;
194 case '\0':
195 return;
197 case 'c':
198 /* syscalls are all disabled at this point. enable the syscall we care about. */
199 do_specific_syscall = TRUE;
200 toggle_syscall(optarg, TRUE);
201 break;
203 case 'a':
204 /* One of the architectures selected*/
205 do_32_arch = FALSE;
206 do_64_arch = FALSE;
207 if (strcmp(optarg, "64") == 0)
208 do_64_arch = TRUE;
209 else if (strcmp(optarg, "32") == 0)
210 do_32_arch = TRUE;
211 else
212 exit(EXIT_FAILURE);
214 break;
216 case 'C':
217 user_specified_children = strtoll(optarg, NULL, 10);
218 break;
220 case 'd':
221 dangerous = 1;
222 break;
224 case 'D':
225 debug = 1;
226 break;
228 case 'g':
229 if (!strcmp(optarg, "vm"))
230 desired_group = GROUP_VM;
231 if (!strcmp(optarg, "vfs"))
232 desired_group = GROUP_VFS;
233 break;
235 /* Show help */
236 case 'h':
237 usage();
238 exit(EXIT_SUCCESS);
240 case 'I':
241 show_ioctl_list = TRUE;
242 break;
244 case 'l':
245 if (!strcmp(optarg, "off"))
246 logging = 0;
247 break;
249 case 'L':
250 show_syscall_list = TRUE;
251 break;
253 case 'm':
254 monochrome = TRUE;
255 break;
257 case 'n':
258 no_files = TRUE;
259 break;
261 /* Set number of syscalls to do */
262 case 'N':
263 syscalls_todo = strtoll(optarg, NULL, 10);
264 break;
266 /* Pause after each syscall */
267 case 'p':
268 dopause = 1;
269 break;
271 case 'P':
272 do_specific_proto = 1;
273 specific_proto = strtol(optarg, NULL, 10);
274 specific_proto_optarg = optarg;
275 break;
277 case 'E':
278 parse_exclude_protos(optarg);
279 break;
281 case 'q':
282 quiet_level++;
283 break;
285 case 'r':
286 if (do_exclude_syscall == TRUE) {
287 outputerr("-r needs to be before any -x options.\n");
288 exit(EXIT_FAILURE);
290 random_selection = 1;
291 random_selection_num = strtol(optarg, NULL, 10);
292 break;
294 /* Set seed */
295 case 's':
296 seed = strtol(optarg, NULL, 10);
297 user_set_seed = TRUE;
298 break;
301 case 'S':
302 do_syslog = TRUE;
303 break;
305 case 'T':
306 //Load mask for kernel taint flags.
307 process_taint_arg(optarg);
308 break;
310 case 'v':
311 verbose = TRUE;
312 break;
314 case 'V':
315 victim_path = strdup(optarg);
316 //FIXME: Later, allow for multiple victim files
317 break;
319 case 'x':
320 do_exclude_syscall = TRUE;
321 toggle_syscall(optarg, FALSE);
322 break;
325 if (quiet_level > MAX_LOGLEVEL)
326 quiet_level = MAX_LOGLEVEL;
328 quiet_level = MAX_LOGLEVEL - quiet_level;