13 #include "protocols.h"
17 #include "trinity.h" // progname
19 #define TAINT_NAME_LEN 32
23 bool do_specific_syscall
= FALSE
;
24 bool do_exclude_syscall
= FALSE
;
26 bool do_32_arch
= TRUE
;
27 bool do_64_arch
= TRUE
;
29 unsigned int specific_proto
= 0;
30 unsigned int user_specified_children
= 0;
32 bool do_specific_proto
= FALSE
;
33 bool no_protos
[TRINITY_PF_MAX
];
36 bool show_syscall_list
= FALSE
;
37 bool show_ioctl_list
= FALSE
;
38 unsigned char quiet_level
= 0;
40 bool monochrome
= FALSE
;
41 bool dangerous
= FALSE
;
42 bool dropprivs
= FALSE
;
44 bool do_syslog
= FALSE
;
45 bool random_selection
= FALSE
;
46 unsigned int random_selection_num
;
47 bool no_files
= FALSE
;
49 bool user_set_seed
= FALSE
;
51 unsigned char desired_group
= GROUP_NONE
;
53 char *specific_proto_optarg
;
57 int kernel_taint_initial
= 0;
58 unsigned int kernel_taint_mask
= 0xFFFFFFFF;
59 bool kernel_taint_param_occured
= FALSE
;
61 static void usage(void)
63 outputerr("%s\n", progname
);
64 outputerr(" --arch, -a: selects syscalls for the specified architecture (32 or 64). Both by default.\n");
65 outputerr(" --children,-C: specify number of child processes\n");
66 outputerr(" --debug,-D: enable debug\n");
67 outputerr(" --dropprivs, -X: if run as root, switch to nobody [EXPERIMENTAL]\n");
68 outputerr(" --exclude,-x: don't call a specific syscall\n");
69 outputerr(" --group,-g: only run syscalls from a certain group (So far just 'vm').\n");
70 outputerr(" --ioctls,-I: list all ioctls.\n");
71 outputerr(" --kernel_taint, -T: controls which kernel taint flags should be considered, for more details refer to README file. \n");
72 outputerr(" --list,-L: list all syscalls known on this architecture.\n");
73 outputerr(" --logging,-l: (off=disable logging).\n");
74 outputerr(" --monochrome,-m: don't output ANSI codes\n");
75 outputerr(" --no_files,-n: Only pass sockets as fd's, not files\n");
76 outputerr(" --proto,-P: specify specific network protocol for sockets.\n");
77 outputerr(" --no_proto,-E: specify network protocols to be excluded from testing.\n");
78 outputerr(" --quiet,-q: less output.\n");
79 outputerr(" --random,-r#: pick N syscalls at random and just fuzz those\n");
80 outputerr(" --syslog,-S: log important info to syslog. (useful if syslog is remote)\n");
81 outputerr(" --verbose,-v: increase output verbosity.\n");
82 outputerr(" --victims,-V: path to victim files.\n");
84 outputerr(" -c#,@: target specific syscall (takes syscall name as parameter and optionally 32 or 64 as bit-width. Default:both).\n");
85 outputerr(" -N#: do # syscalls then exit.\n");
86 outputerr(" -p: pause after syscall.\n");
87 outputerr(" -s#: use # as random seed.\n");
91 static const char paramstr
[] = "a:c:C:dDg:hIl:LN:mnP:E:pqr:s:T:SV:vx:X";
93 static const struct option longopts
[] = {
94 { "children", required_argument
, NULL
, 'C' },
95 { "dangerous", no_argument
, NULL
, 'd' },
96 { "dropprivs", no_argument
, NULL
, 'X'},
97 { "debug", no_argument
, NULL
, 'D' },
98 { "exclude", required_argument
, NULL
, 'x' },
99 { "group", required_argument
, NULL
, 'g' },
100 { "kernel_taint", required_argument
, NULL
, 'T' },
101 { "help", no_argument
, NULL
, 'h' },
102 { "list", no_argument
, NULL
, 'L' },
103 { "ioctls", no_argument
, NULL
, 'I' },
104 { "logging", required_argument
, NULL
, 'l' },
105 { "monochrome", no_argument
, NULL
, 'm' },
106 { "no_files", no_argument
, NULL
, 'n' },
107 { "proto", required_argument
, NULL
, 'P' },
108 { "no_proto", required_argument
, NULL
, 'E' },
109 { "random", required_argument
, NULL
, 'r' },
110 { "quiet", no_argument
, NULL
, 'q' },
111 { "syslog", no_argument
, NULL
, 'S' },
112 { "victims", required_argument
, NULL
, 'V' },
113 { "verbose", no_argument
, NULL
, 'v' },
114 { "arch", required_argument
, NULL
, 'a' },
115 { NULL
, 0, NULL
, 0 } };
117 static void toggle_taint_flag(int bit
) {
118 kernel_taint_mask
|= (1 << bit
);
121 static void toggle_taint_flag_by_name(char *beg
, char *end
) {
122 char flagname
[TAINT_NAME_LEN
];
132 if (maxlen
> (TAINT_NAME_LEN
- 1))
133 maxlen
= TAINT_NAME_LEN
- 1;
134 strncpy(flagname
, beg
, maxlen
);
135 flagname
[maxlen
] = 0;
138 if (strcmp(name
,"PROPRIETARY_MODULE") == 0)
139 toggle_taint_flag(TAINT_PROPRIETARY_MODULE
);
140 else if (strcmp(name
,"FORCED_MODULE") == 0)
141 toggle_taint_flag(TAINT_FORCED_MODULE
);
142 else if (strcmp(name
,"UNSAFE_SMP") == 0)
143 toggle_taint_flag(TAINT_UNSAFE_SMP
);
144 else if (strcmp(name
,"FORCED_RMMOD") == 0)
145 toggle_taint_flag(TAINT_FORCED_RMMOD
);
146 else if (strcmp(name
,"MACHINE_CHECK") == 0)
147 toggle_taint_flag(TAINT_MACHINE_CHECK
);
148 else if (strcmp(name
,"BAD_PAGE") == 0)
149 toggle_taint_flag(TAINT_BAD_PAGE
);
150 else if (strcmp(name
,"USER") == 0)
151 toggle_taint_flag(TAINT_USER
);
152 else if (strcmp(name
,"DIE") == 0)
153 toggle_taint_flag(TAINT_DIE
);
154 else if (strcmp(name
,"OVERRIDDEN_ACPI_TABLE") == 0)
155 toggle_taint_flag(TAINT_OVERRIDDEN_ACPI_TABLE
);
156 else if (strcmp(name
,"WARN") == 0)
157 toggle_taint_flag(TAINT_WARN
);
158 else if (strcmp(name
,"CRAP") == 0)
159 toggle_taint_flag(TAINT_CRAP
);
160 else if (strcmp(name
,"FIRMWARE_WORKAROUND") == 0)
161 toggle_taint_flag(TAINT_FIRMWARE_WORKAROUND
);
162 else if (strcmp(name
,"OOT_MODULE") == 0)
163 toggle_taint_flag(TAINT_OOT_MODULE
);
165 outputerr("Unrecognizable kernel taint flag \"%s\".\n", name
);
170 static void process_taint_arg(char *taintarg
) {
173 if (kernel_taint_param_occured
== FALSE
) {
174 kernel_taint_param_occured
= TRUE
;
175 kernel_taint_mask
= 0; //We now only care about flags that user specified.
179 end
= strchr(beg
, ',');
181 toggle_taint_flag_by_name(beg
,end
);
183 end
= strchr(beg
, ',');
185 toggle_taint_flag_by_name(beg
,end
);
188 void parse_args(int argc
, char *argv
[])
192 while ((opt
= getopt_long(argc
, argv
, paramstr
, longopts
, NULL
)) != -1) {
198 outputstd("opt:%c\n", opt
);
205 /* syscalls are all disabled at this point. enable the syscall we care about. */
206 do_specific_syscall
= TRUE
;
207 toggle_syscall(optarg
, TRUE
);
211 /* One of the architectures selected*/
214 if (strcmp(optarg
, "64") == 0) {
217 } else if (strcmp(optarg
, "32") == 0) {
221 outputstd("can't parse %s\n", optarg
);
227 user_specified_children
= strtoll(optarg
, NULL
, 10);
228 max_children
= user_specified_children
;
230 if (max_children
== 0) {
231 outputerr("zero children ? WAT?\n");
245 if (!strcmp(optarg
, "vm"))
246 desired_group
= GROUP_VM
;
247 if (!strcmp(optarg
, "vfs"))
248 desired_group
= GROUP_VFS
;
257 show_ioctl_list
= TRUE
;
261 if (!strcmp(optarg
, "off"))
266 show_syscall_list
= TRUE
;
277 /* Set number of syscalls to do */
279 syscalls_todo
= strtoll(optarg
, NULL
, 10);
282 /* Pause after each syscall */
288 do_specific_proto
= TRUE
;
289 specific_proto
= strtol(optarg
, NULL
, 10);
290 specific_proto_optarg
= optarg
;
294 parse_exclude_protos(optarg
);
302 if (do_exclude_syscall
== TRUE
) {
303 outputerr("-r needs to be before any -x options.\n");
306 random_selection
= TRUE
;
307 random_selection_num
= strtol(optarg
, NULL
, 10);
312 seed
= strtol(optarg
, NULL
, 10);
313 user_set_seed
= TRUE
;
322 //Load mask for kernel taint flags.
323 process_taint_arg(optarg
);
324 if (kernel_taint_mask
!= 0xFFFFFFFF)
325 outputstd("Custom kernel taint mask has been specified: 0x%08x (%d).\n",
326 kernel_taint_mask
, kernel_taint_mask
);
334 victim_path
= strdup(optarg
);
335 //FIXME: Later, allow for multiple victim files
339 do_exclude_syscall
= TRUE
;
340 toggle_syscall(optarg
, FALSE
);
348 if (quiet_level
> MAX_LOGLEVEL
)
349 quiet_level
= MAX_LOGLEVEL
;
351 quiet_level
= MAX_LOGLEVEL
- quiet_level
;
353 outputstd("Done parsing arguments.\n");