Skip to content

Commit a153751

Browse files
committed
WIP: better logging
1 parent 4930c31 commit a153751

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
- name: Install dependencies
5858
run: |
5959
sudo apt -y update
60-
sudo apt -y install docbook-xsl gcc libglib2.0-dev xsltproc meson clang valgrind
60+
sudo apt -y install docbook-xsl gcc libglib2.0-dev libjson-glib-dev xsltproc meson clang valgrind
6161
6262
- name: Build
6363
run: |
@@ -80,7 +80,7 @@ jobs:
8080
- name: Install dependencies
8181
run: |
8282
sudo apt -y update
83-
sudo apt -y install docbook-xsl gcc libglib2.0-dev xsltproc meson lcov
83+
sudo apt -y install docbook-xsl gcc libglib2.0-dev libjson-glib-dev xsltproc meson lcov
8484
8585
- name: Build
8686
run: |

meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ project('dfuzzer', 'c',
88
)
99

1010
libgio = dependency('gio-2.0', required : true)
11+
json_glib = dependency('json-glib-1.0', required : true)
1112
xsltproc = find_program('xsltproc', required: false)
1213

1314
subdir('src')
1415

1516
executable(
1617
'dfuzzer',
1718
dfuzzer_sources,
18-
dependencies : [libgio],
19+
dependencies : [libgio, json_glib],
1920
install : true
2021
)
2122

src/dfuzzer.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "rand.h"
3838
#include "util.h"
3939

40+
/* Shared global variables */
41+
char *df_log_dir;
4042

4143
/** Structure containing D-Bus name, object path and interface of process */
4244
static struct fuzzing_target target_proc = { "", "", "" };
@@ -71,7 +73,6 @@ static char *df_execute_cmd;
7173
* written to a [BUS_NAME.log] file */
7274
static int df_full_log_flag;
7375
/** Path to directory containing output logs */
74-
static char *log_dir_name;
7576
static guint64 df_max_iterations = G_MAXUINT32;
7677
static guint64 df_min_iterations = 10;
7778
/** Pointer to a file for full logging */
@@ -94,7 +95,7 @@ int main(int argc, char **argv)
9495
df_parse_parameters(argc, argv);
9596

9697
if (df_full_log_flag) {
97-
log_file_name = strjoina(log_dir_name, "/", target_proc.name);
98+
log_file_name = strjoina(df_log_dir, "/", target_proc.name);
9899
logfile = fopen(log_file_name, "a+");
99100
if(!logfile) {
100101
df_fail("Error opening file %s; detailed logs will not be written\n", log_file_name);
@@ -873,7 +874,7 @@ void df_parse_parameters(int argc, char **argv)
873874
" 'L'\n", argv[0], MAXLEN - 1);
874875
exit(1);
875876
}
876-
log_dir_name = optarg;
877+
df_log_dir = optarg;
877878
df_full_log_flag = 1;
878879
break;
879880
case 'x':

src/dfuzzer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ struct suppression_item {
6767
char *description;
6868
};
6969

70+
extern char *df_log_dir;
71+
7072
int df_process_bus(GBusType bus_type);
7173

7274
/**

src/fuzz.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <errno.h>
2424
#include <fcntl.h>
2525
#include <gio/gio.h>
26+
#include <json-glib/json-glib.h>
2627
#include <stdio.h>
2728
#include <stdlib.h>
2829
#include <string.h>
@@ -48,6 +49,9 @@ static char df_except_counter = 0;
4849
static void df_fuzz_write_log(const struct df_dbus_method *method, GVariant *value);
4950
static int df_exec_cmd_check(const char *cmd);
5051
static int df_fuzz_call_method(const struct df_dbus_method *method, GVariant *value);
52+
static void df_fuzz_dump_reproducer(const char *bus, const char *object, const char *interface,
53+
const char *method, const char *signature, GVariant *value,
54+
const char *type);
5155

5256
guint64 df_get_number_of_iterations(const char *signature) {
5357
guint64 iterations = 0;
@@ -399,6 +403,9 @@ static int df_check_if_exited(const int pid) {
399403
assert(pid > 0);
400404

401405
sprintf(proc_pid, "/proc/%d/status", pid);
406+
/* FIXME: check correctly if the target responds before checking its PID,
407+
* otherwise we might miss the crash */
408+
usleep(50000);
402409

403410
f = fopen(proc_pid, "r");
404411
if (!f) {
@@ -533,6 +540,8 @@ int df_fuzz_test_method(
533540
df_fuzz_write_log(method, value);
534541
}
535542

543+
df_fuzz_dump_reproducer(name, obj, intf, method->name, method->signature, value, "fail");
544+
536545
df_fail(" reproducer: %sdfuzzer -v -n %s -o %s -i %s -t %s",
537546
ansi_yellow(), name, obj, intf, method->name);
538547
if (buf_size_flg)
@@ -625,3 +634,74 @@ static int df_fuzz_call_method(const struct df_dbus_method *method, GVariant *va
625634

626635
return 0;
627636
}
637+
638+
static void df_fuzz_dump_reproducer(const char *bus, const char *object, const char *interface,
639+
const char *method, const char *signature, GVariant *value,
640+
const char *type)
641+
{
642+
g_autoptr(JsonBuilder) builder = NULL;
643+
g_autoptr(JsonNode) root = NULL;
644+
g_autoptr(JsonGenerator) generator = NULL;
645+
g_autoptr (GError) error = NULL;
646+
g_autofree gchar *filename = NULL;
647+
648+
/* No log dir set, don't dump anything */
649+
if (!df_log_dir)
650+
return;
651+
652+
assert(bus);
653+
assert(object);
654+
assert(method);
655+
assert(signature);
656+
assert(value);
657+
658+
/* Generate a JSON tree
659+
*
660+
* Current structure:
661+
* {
662+
* "bus": <bus_name>,
663+
* "object": <object_name>,
664+
* "interface": <interface_name>,
665+
* "method": <method_name>,
666+
* "payload": {
667+
* "signature": <signature>,
668+
* "data": <serialized_gvariant>
669+
* }
670+
* }
671+
*/
672+
builder = json_builder_new();
673+
json_builder_begin_object(builder);
674+
675+
json_builder_set_member_name(builder, "bus");
676+
json_builder_add_string_value(builder, bus);
677+
json_builder_set_member_name(builder, "object");
678+
json_builder_add_string_value(builder, object);
679+
json_builder_set_member_name(builder, "interface");
680+
json_builder_add_string_value(builder, interface);
681+
json_builder_set_member_name(builder, "method");
682+
json_builder_add_string_value(builder, method);
683+
684+
json_builder_set_member_name(builder, "payload");
685+
json_builder_begin_object(builder);
686+
json_builder_set_member_name(builder, "signature");
687+
json_builder_add_string_value(builder, signature);
688+
json_builder_set_member_name(builder, "data");
689+
json_builder_add_value(builder, json_gvariant_serialize(value));
690+
json_builder_end_object(builder);
691+
692+
json_builder_end_object(builder);
693+
694+
/* Serialize the whole JSON tree */
695+
root = json_builder_get_root(builder);
696+
generator = json_generator_new();
697+
json_generator_set_root(generator, root);
698+
json_generator_set_pretty(generator, TRUE);
699+
700+
/* Dump it into a file */
701+
filename = g_strdup_printf("%s/%s-%s-%"G_GINT64_FORMAT"-%s.json", df_log_dir,
702+
bus, method, g_get_real_time(), type);
703+
if (!json_generator_to_file(generator, filename, &error))
704+
df_fail("Failed to dump reproducer into file '%s': %s\n", filename, error->message);
705+
706+
df_fail(" Wrote the reproducer into file '%s'\n", filename);
707+
}

0 commit comments

Comments
 (0)