From 014f46e54c8103a32f7645c2684505bf7770aa0a Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Fri, 13 May 2022 16:32:59 +0200 Subject: [PATCH] fuzz: distinguish between reading/writing properties in logs Also, reorder the for/loop statements, because I have no idea why I put them like I did in the first place, and check if the remote side is alive even after just reading a property. ``` Interface: org.freedesktop.dfuzzerInterface PASS [P] read_only (read) PASS [P] write_only (write) FAIL [P] crash_on_write (write) - unexpected response while writing to a property [RE-CONNECTED TO PID: 2479535] PASS [P] read_write (read) PASS [P] read_write (write) PASS [M] df_hello ... ``` Addresses: https://github.com/matusmarhefka/dfuzzer/pull/86#pullrequestreview-971808731 --- src/dfuzzer-test-server.c | 8 ++++--- src/fuzz.c | 49 +++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/dfuzzer-test-server.c b/src/dfuzzer-test-server.c index fc7e794..ed028b9 100644 --- a/src/dfuzzer-test-server.c +++ b/src/dfuzzer-test-server.c @@ -97,6 +97,7 @@ static const gchar introspection_xml[] = " " " " " " +" " " " " " ""; @@ -180,11 +181,12 @@ static GVariant *handle_get_property( g_printf("->[handle_get_property] %s\n", property_name); - if (g_str_equal(property_name, "read_only")) { + if (g_str_equal(property_name, "read_only")) response = g_variant_new("(s)", prop_read_only); - } else if (g_str_equal(property_name, "read_write")) { + else if (g_str_equal(property_name, "crash_on_read")) + test_abort(); + else if (g_str_equal(property_name, "read_write")) response = g_variant_new("(iu)", prop_read_write.i, prop_read_write.u); - } return response; } diff --git a/src/fuzz.c b/src/fuzz.c index 8db8e3a..b24f3d6 100644 --- a/src/fuzz.c +++ b/src/fuzz.c @@ -455,7 +455,7 @@ int df_fuzz_test_method( df_debug(" Method: %s%s %s => %"G_GUINT64_FORMAT" iterations%s\n", ansi_bold(), method->name, method->signature, iterations, ansi_normal()); - df_verbose(" %s...", method->name); + df_verbose(" [M] %s...", method->name); df_except_counter = 0; @@ -709,11 +709,6 @@ int df_fuzz_test_property(GDBusConnection *dcon, const struct df_dbus_property * g_autoptr(GDBusProxy) pproxy = NULL; int r; - df_debug(" Property: %s%s %s => %"G_GUINT64_FORMAT" iterations%s\n", ansi_bold(), - property->name, property->signature, iterations, ansi_normal()); - - df_verbose(" [P] %s...", property->name); - /* Create a "property proxy" * See: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties */ @@ -727,8 +722,14 @@ int df_fuzz_test_property(GDBusConnection *dcon, const struct df_dbus_property * * For performance reasons read readable property only twice, since that * should be enough to trigger most of the issues. */ - for (guint8 i = 0; i < 2; i++) { - if (property->is_readable) { + iterations = 2; + if (property->is_readable) { + df_debug(" Property: %s%s %s (read) => %"G_GUINT64_FORMAT" iterations%s\n", ansi_bold(), + property->name, property->signature, iterations, ansi_normal()); + + df_verbose(" [P] %s (read)...", property->name); + + for (guint8 i = 0; i < iterations; i++) { r = df_fuzz_get_property(pproxy, interface, property); if (r < 0) { df_fail("%s %sFAIL%s [P] %s - unexpected response while reading a property\n", @@ -736,6 +737,19 @@ int df_fuzz_test_property(GDBusConnection *dcon, const struct df_dbus_property * return 1; } } + + /* Check if the remote side is still alive */ + r = df_check_if_exited(pid); + if (r < 0) + return df_fail_ret(-1, "Error while reading process' stat file: %m\n"); + else if (r == 0) { + df_fail("%s %sFAIL%s [P] %s (read) - process %d exited\n", + ansi_cr(), ansi_red(), ansi_normal(), property->name, pid); + return 1; + } + + df_verbose("%s %sPASS%s [P] %s (read)\n", + ansi_cr(), ansi_green(), ansi_normal(), property->name); } /* Try to write a random value to the property if it's writable @@ -744,8 +758,13 @@ int df_fuzz_test_property(GDBusConnection *dcon, const struct df_dbus_property * * dictionaries doing the "full" loop is mostly a waste of time. */ iterations = CLAMP(iterations, 1, 16); - for (guint64 i = 0; i < iterations; i++) { - if (property->is_writable) { + if (property->is_writable) { + df_debug(" Property: %s%s %s (write) => %"G_GUINT64_FORMAT" iterations%s\n", ansi_bold(), + property->name, property->signature, iterations, ansi_normal()); + + df_verbose(" [P] %s (write)...", property->name); + + for (guint64 i = 0; i < iterations; i++) { g_autoptr(GVariant) value = NULL; /* Create a random GVariant based on method's signature */ @@ -757,7 +776,7 @@ int df_fuzz_test_property(GDBusConnection *dcon, const struct df_dbus_property * value = g_variant_ref_sink(value); r = df_fuzz_set_property(pproxy, interface, property, value); if (r < 0) { - df_fail("%s %sFAIL%s [P] %s - unexpected response while writing to a property\n", + df_fail("%s %sFAIL%s [P] %s (write) - unexpected response while writing to a property\n", ansi_cr(), ansi_red(), ansi_normal(), property->name); return 1; } @@ -768,14 +787,14 @@ int df_fuzz_test_property(GDBusConnection *dcon, const struct df_dbus_property * if (r < 0) return df_fail_ret(-1, "Error while reading process' stat file: %m\n"); else if (r == 0) { - df_fail("%s %sFAIL%s [P] %s - process %d exited\n", + df_fail("%s %sFAIL%s [P] %s (write) - process %d exited\n", ansi_cr(), ansi_red(), ansi_normal(), property->name, pid); return 1; } - } - df_verbose("%s %sPASS%s [P] %s\n", - ansi_cr(), ansi_green(), ansi_normal(), property->name); + df_verbose("%s %sPASS%s [P] %s (write)\n", + ansi_cr(), ansi_green(), ansi_normal(), property->name); + } return 0; }