8 #include "params.h" // logging, monochrome, quiet_level
12 #include "arch.h" //PAGE_MASK
13 #include "maps.h" //pages
14 #include "syscall.h" //syscalls
20 static FILE *mainlogfile
;
21 static bool logfiles_opened
= FALSE
;
23 void open_logfiles(void)
28 logfilename
= malloc(64);
29 sprintf(logfilename
, "trinity.log");
31 mainlogfile
= fopen(logfilename
, "a");
33 outputerr("## couldn't open logfile %s\n", logfilename
);
38 sprintf(logfilename
, "trinity-child%u.log", i
);
40 shm
->logfiles
[i
] = fopen(logfilename
, "a");
41 if (!shm
->logfiles
[i
]) {
42 outputerr("## couldn't open logfile %s\n", logfilename
);
47 logfiles_opened
= TRUE
;
50 void close_logfiles(void)
55 if (shm
->logfiles
[i
] != NULL
)
56 fclose(shm
->logfiles
[i
]);
59 static FILE * find_logfile_handle(void)
68 if (pid
== shm
->mainpid
)
71 if (pid
== watchdog_pid
)
74 i
= find_pid_slot(pid
);
75 if (i
!= PIDSLOT_NOT_FOUND
)
76 return shm
->logfiles
[i
];
78 /* try one more time. FIXME: This is awful. */
82 i
= find_pid_slot(pid
);
83 if (i
!= PIDSLOT_NOT_FOUND
)
84 return shm
->logfiles
[i
];
86 outputerr("## Couldn't find logfile for pid %d\n", pid
);
88 outputerr("## Logfiles for pids: ");
90 outputerr("%p ", shm
->logfiles
[j
]);
96 unsigned int highest_logfile(void)
101 if (logging
== FALSE
)
104 file
= shm
->logfiles
[max_children
- 1];
115 if (logging
== FALSE
)
118 for_each_pidslot(i
) {
121 ret
= fflush(shm
->logfiles
[i
]);
123 outputerr("## logfile flushing failed! %s\n", strerror(errno
));
127 fd
= fileno(shm
->logfiles
[i
]);
131 outputerr("## fsyncing logfile %d failed. %s\n", i
, strerror(errno
));
135 (void)fflush(mainlogfile
);
136 fsync(fileno(mainlogfile
));
139 static void output_arg(unsigned int argnum
, struct syscallentry
*entry
, FILE *fd
, bool mono
, int childno
)
141 enum argtype type
= 0;
142 const char *name
= NULL
;
143 unsigned long reg
= 0;
146 case 1: type
= entry
->arg1type
;
147 name
= entry
->arg1name
;
148 reg
= shm
->syscall
[childno
].a1
;
150 case 2: type
= entry
->arg2type
;
151 name
= entry
->arg2name
;
152 reg
= shm
->syscall
[childno
].a2
;
154 case 3: type
= entry
->arg3type
;
155 name
= entry
->arg3name
;
156 reg
= shm
->syscall
[childno
].a3
;
158 case 4: type
= entry
->arg4type
;
159 name
= entry
->arg4name
;
160 reg
= shm
->syscall
[childno
].a4
;
162 case 5: type
= entry
->arg5type
;
163 name
= entry
->arg5name
;
164 reg
= shm
->syscall
[childno
].a5
;
166 case 6: type
= entry
->arg6type
;
167 name
= entry
->arg6name
;
168 reg
= shm
->syscall
[childno
].a6
;
177 fprintf(fd
, "%s=", name
);
181 fprintf(fd
, "\"%s\"", (char *) reg
);
186 fprintf(fd
, "%ld", (long) reg
);
190 fprintf(fd
, "%o", (mode_t
) reg
);
194 case ARG_NON_NULL_ADDRESS
:
197 fprintf(fd
, "0x%lx", reg
);
201 /* Although generic sanitise has set this to a map struct,
202 * common_set_mmap_ptr_len() will subsequently set it to the ->ptr
203 * in the per syscall ->sanitise routine. */
204 fprintf(fd
, "%p", (void *) reg
);
208 fprintf(fd
, "0x%lx [page_rand]", reg
);
213 fprintf(fd
, "0x%lx", reg
);
220 case ARG_RANDOM_LONG
:
222 case ARG_SOCKADDRLEN
:
223 if (((long) reg
< -16384) || ((long) reg
> 16384)) {
224 /* Print everything outside -16384 and 16384 as hex. */
225 fprintf(fd
, "0x%lx", reg
);
227 /* Print everything else as signed decimal. */
228 fprintf(fd
, "%ld", (long) reg
);
234 if ((reg
& PAGE_MASK
) == (unsigned long) page_zeros
)
235 fprintf(fd
, "[page_zeros]");
236 if ((reg
& PAGE_MASK
) == (unsigned long) page_rand
)
237 fprintf(fd
, "[page_rand]");
238 if ((reg
& PAGE_MASK
) == (unsigned long) page_0xff
)
239 fprintf(fd
, "[page_0xff]");
240 if ((reg
& PAGE_MASK
) == (unsigned long) page_allocs
)
241 fprintf(fd
, "[page_allocs]");
243 if (entry
->decode
!= NULL
) {
246 str
= entry
->decode(argnum
, childno
);
248 fprintf(fd
, "%s", str
);
254 static FILE *robust_find_logfile_handle(void)
258 if ((logging
== TRUE
) && (logfiles_opened
)) {
259 handle
= find_logfile_handle();
263 outputerr("## child logfile handle was null logging to main!\n");
264 (void)fflush(stdout
);
266 shm
->logfiles
[j
] = mainlogfile
;
268 handle
= find_logfile_handle();
275 * level defines whether it gets displayed to the screen with printf.
277 * 0 = everything, even all the registers
278 * 1 = Watchdog prints syscall count
279 * 2 = Just the reseed values
282 void output(unsigned char level
, const char *fmt
, ...)
288 char outputbuf
[BUFSIZE
];
290 char watchdog_prefix
[]="[watchdog]";
291 char init_prefix
[]="[init]";
292 char main_prefix
[]="[main]";
293 char child_prefix
[]="[childNN:1234567890]";
295 if (logging
== FALSE
&& level
>= quiet_level
)
298 /* prefix preparation */
300 if (pid
== watchdog_pid
)
301 prefix
= watchdog_prefix
;
304 prefix
= init_prefix
;
306 if (pid
== shm
->mainpid
)
307 prefix
= main_prefix
;
309 if (prefix
== NULL
) {
312 slot
= find_pid_slot(pid
);
313 sprintf(child_prefix
, "[child%u:%u]", slot
, pid
);
314 prefix
= child_prefix
;
317 /* formatting output */
319 n
= vsnprintf(outputbuf
, sizeof(outputbuf
), fmt
, args
);
322 outputerr("## Something went wrong in output() [%d]\n", n
);
326 /* stdout output if needed */
327 if (quiet_level
> level
) {
328 printf("%s %s", prefix
, outputbuf
);
329 (void)fflush(stdout
);
332 /* go on with file logs only if enabled */
333 if (logging
== FALSE
)
336 handle
= robust_find_logfile_handle();
340 /* If we've specified monochrome, we can just dump the buffer into
341 * the logfile as is, because there shouldn't be any ANSI codes
342 * in the buffer to be stripped out. */
343 if (monochrome
== FALSE
) {
344 char monobuf
[BUFSIZE
];
345 unsigned int len
, i
, j
;
347 /* copy buffer, sans ANSI codes */
348 len
= strlen(outputbuf
);
349 for (i
= 0, j
= 0; (i
< len
) && (i
+ 2 < BUFSIZE
) && (j
< BUFSIZE
); i
++) {
350 if (outputbuf
[i
] == '\e') {
351 if (outputbuf
[i
+ 2] == '1')
352 i
+= 6; // ANSI_COLOUR
354 i
+= 3; // ANSI_RESET
356 monobuf
[j
] = outputbuf
[i
];
361 fprintf(handle
, "%s %s", prefix
, monobuf
);
363 fprintf(handle
, "%s %s", prefix
, outputbuf
);
366 (void)fflush(handle
);
370 * Used as a way to consolidated all printf calls if someones one to redirect it to somewhere else.
371 * note: this function ignores quiet_level since it main purpose is error output.
373 void outputerr(const char *fmt
, ...)
378 vfprintf(stderr
, fmt
, args
);
382 void outputstd(const char *fmt
, ...)
387 vfprintf(stdout
, fmt
, args
);
391 static void output_syscall_prefix_to_fd(const unsigned int childno
, const pid_t pid
, const unsigned int syscallnr
, FILE *fd
, bool mono
)
393 struct syscallentry
*entry
;
396 entry
= syscalls
[syscallnr
].entry
;
398 fprintf(fd
, "[child%u:%u] [%lu] %s", childno
, pid
, shm
->child_op_count
[childno
],
399 (shm
->syscall
[childno
].do32bit
== TRUE
) ? "[32BIT] " : "");
401 if (syscallnr
> max_nr_syscalls
)
402 fprintf(fd
, "%u", syscallnr
);
404 fprintf(fd
, "%s", entry
->name
);
409 for (i
= 1; i
< entry
->num_args
+ 1; i
++)
410 output_arg(i
, entry
, fd
, mono
, childno
);
417 /* This function is always called from a fuzzing child. */
418 void output_syscall_prefix(const unsigned int childno
, const unsigned int syscallnr
)
423 /* Exit if should not continue at all. */
424 if (logging
== FALSE
&& quiet_level
< MAX_LOGLEVEL
)
428 /* Find the log file handle */
429 log_handle
= robust_find_logfile_handle();
431 /* do not output any ascii control symbols to files */
432 if ((logging
== TRUE
) && (log_handle
!= NULL
))
433 output_syscall_prefix_to_fd(childno
, pid
, syscallnr
, log_handle
, TRUE
);
435 /* Output to stdout only if -q param is not specified */
436 if (quiet_level
== MAX_LOGLEVEL
)
437 output_syscall_prefix_to_fd(childno
, pid
, syscallnr
, stdout
, monochrome
);
440 static void output_syscall_postfix_err(unsigned long ret
, int errno_saved
, FILE *fd
, bool mono
)
443 fprintf(fd
, "= %ld (%s)", (long) ret
, strerror(errno_saved
));
449 static void output_syscall_postfix_success(unsigned long ret
, FILE *fd
, bool mono
)
452 if ((unsigned long)ret
> 10000)
453 fprintf(fd
, "= 0x%lx", ret
);
455 fprintf(fd
, "= %ld", (long) ret
);
461 void output_syscall_postfix(unsigned long ret
, int errno_saved
, bool err
)
465 /* Exit if should not continue at all. */
466 if (logging
== FALSE
&& quiet_level
< MAX_LOGLEVEL
)
469 /* Find the log file handle */
470 log_handle
= robust_find_logfile_handle();
473 if ((logging
== TRUE
) && (log_handle
!= NULL
))
474 output_syscall_postfix_err(ret
, errno_saved
, log_handle
, TRUE
);
475 if (quiet_level
== MAX_LOGLEVEL
)
476 output_syscall_postfix_err(ret
, errno_saved
, stdout
, monochrome
);
478 if ((logging
== TRUE
) && (log_handle
!= NULL
))
479 output_syscall_postfix_success(ret
, log_handle
, TRUE
);
480 if (quiet_level
== MAX_LOGLEVEL
)
481 output_syscall_postfix_success(ret
, stdout
, monochrome
);
485 void debugf(const char *fmt
, ...)