Skip to content

Commit 77f3b5a

Browse files
committed
WIP: better logging
1 parent 3a59dbc commit 77f3b5a

File tree

5 files changed

+89
-6
lines changed

5 files changed

+89
-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);
@@ -874,7 +875,7 @@ void df_parse_parameters(int argc, char **argv)
874875
" 'L'\n", argv[0], MAXLEN - 1);
875876
exit(1);
876877
}
877-
log_dir_name = optarg;
878+
df_log_dir = optarg;
878879
df_full_log_flag = 1;
879880
break;
880881
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: 79 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,8 @@ 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 */
402408

403409
f = fopen(proc_pid, "r");
404410
if (!f) {
@@ -539,6 +545,8 @@ int df_fuzz_test_method(
539545
df_fuzz_write_log(method, value);
540546
}
541547

548+
df_fuzz_dump_reproducer(name, obj, intf, method->name, method->signature, value, "fail");
549+
542550
df_fail(" reproducer: %sdfuzzer -v -n %s -o %s -i %s -t %s",
543551
ansi_yellow(), name, obj, intf, method->name);
544552
if (buf_size_flg)
@@ -633,3 +641,74 @@ static int df_fuzz_call_method(const struct df_dbus_method *method, GVariant *va
633641

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

0 commit comments

Comments
 (0)