From 1e187dd6e216f1e29078f971334d602e3d05c688 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 23 Jun 2022 16:09:39 +0200 Subject: [PATCH 1/3] tree-wide: cleanup the constant naming & location --- src/dfuzzer.c | 26 +++++++++++++------------- src/dfuzzer.h | 8 +------- src/fuzz.h | 10 +++++++++- src/rand.c | 4 ++-- src/rand.h | 16 ++-------------- 5 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/dfuzzer.c b/src/dfuzzer.c index 85f683c..143a0cb 100644 --- a/src/dfuzzer.c +++ b/src/dfuzzer.c @@ -39,7 +39,7 @@ /* Shared global variables */ /** Maximum buffer size for generated strings by rand module (in Bytes) */ -guint64 df_buf_size = MAX_BUF_LEN; +guint64 df_buf_size = MAX_BUFFER_LENGTH; int df_verbose_flag; int df_debug_flag; @@ -54,7 +54,7 @@ static int df_list_names; /** Tested process PID */ static int df_pid = -1; /** NULL terminated struct of methods names which will be skipped from testing */ -static struct suppression_item *suppressions[MAXLEN]; +static struct suppression_item *suppressions[MAX_SUPPRESSIONS]; /** If -s option is passed 1, otherwise 0 */ static int df_supflg; /** Suppression file #1 */ @@ -771,25 +771,25 @@ void df_parse_parameters(int argc, char **argv) while ((c = getopt_long(argc, argv, "n:o:i:m:b:t:e:L:x:y:f:I:p:sdvlhV", options, NULL)) >= 0) { switch (c) { case 'n': - if (strlen(optarg) >= MAXLEN) { + if (strlen(optarg) >= MAX_OBJECT_PATH_LENGTH) { df_fail("%s: maximum %d characters for option --" - " 'n'\n", argv[0], MAXLEN - 1); + " 'n'\n", argv[0], MAX_OBJECT_PATH_LENGTH - 1); exit(1); } target_proc.name = optarg; break; case 'o': - if (strlen(optarg) >= MAXLEN) { + if (strlen(optarg) >= MAX_OBJECT_PATH_LENGTH) { df_fail("%s: maximum %d characters for option --" - " 'o'\n", argv[0], MAXLEN - 1); + " 'o'\n", argv[0], MAX_OBJECT_PATH_LENGTH - 1); exit(1); } target_proc.obj_path = optarg; break; case 'i': - if (strlen(optarg) >= MAXLEN) { + if (strlen(optarg) >= MAX_OBJECT_PATH_LENGTH) { df_fail("%s: maximum %d characters for option --" - " 'i'\n", argv[0], MAXLEN - 1); + " 'i'\n", argv[0], MAX_OBJECT_PATH_LENGTH - 1); exit(1); } target_proc.interface = optarg; @@ -804,8 +804,8 @@ void df_parse_parameters(int argc, char **argv) exit(1); } - if (df_buf_size < MINLEN) { - df_fail("Error: at least %d bytes required for the -%c option\n", MINLEN, c); + if (df_buf_size < MIN_BUFFER_LENGTH) { + df_fail("Error: at least %d bytes required for the -%c option\n", MIN_BUFFER_LENGTH, c); exit(1); } @@ -845,9 +845,9 @@ void df_parse_parameters(int argc, char **argv) break; case 'L': //we need at least 1 more char than usual for directory separator - if (strlen(optarg) >= MAXLEN -1) { + if (strlen(optarg) >= MAX_OBJECT_PATH_LENGTH -1) { df_fail("%s: maximum %d characters for option --" - " 'L'\n", argv[0], MAXLEN - 1); + " 'L'\n", argv[0], MAX_OBJECT_PATH_LENGTH - 1); exit(1); } log_dir_name = optarg; @@ -1011,7 +1011,7 @@ int df_load_suppressions(void) df_verbose("Found suppressions for bus: '%s'\n", target_proc.name); i = 0; - while (i < (MAXLEN - 1) && (n = getline(&line, &len, f)) > 0) { + while (i < (MAX_SUPPRESSIONS - 1) && (n = getline(&line, &len, f)) > 0) { g_autoptr(char) suppression = NULL, description = NULL; char *p; diff --git a/src/dfuzzer.h b/src/dfuzzer.h index b30ad3e..58f5e44 100644 --- a/src/dfuzzer.h +++ b/src/dfuzzer.h @@ -25,12 +25,6 @@ #include #include -/** Minimal buffer size for generated strings */ -#define MINLEN 512 - -/** Maximum length of strings containing D-Bus name, interface and object path */ -#define MAXLEN 256 - #define DF_BUS_ROOT_NODE "/" enum { @@ -44,7 +38,7 @@ enum { /** Structure containing D-Bus name, object path and interface of process. */ struct fuzzing_target { - /* names on D-Bus have the most MAXLEN characters */ + /* names on D-Bus have the most MAX_OBJECT_PATH_LENGTH characters */ /** Bus name */ char *name; /** Object path */ diff --git a/src/fuzz.h b/src/fuzz.h index 3dc19f5..e09cab9 100644 --- a/src/fuzz.h +++ b/src/fuzz.h @@ -21,8 +21,16 @@ #ifndef FUZZ_H #define FUZZ_H +/** Minimal buffer size for generated strings */ +#define MIN_BUFFER_LENGTH 512 +/** Maximum buffer size for generated strings, default is cca 50 kB */ +#define MAX_BUFFER_LENGTH 50000 +/** Maximum length of strings containing D-Bus object path */ +#define MAX_OBJECT_PATH_LENGTH 256 /** Maximum length of D-Bus signature string */ -#define MAXSIG 255 +#define MAX_SIGNATURE_LENGTH 255 +#define MAX_SUPPRESSIONS 256 + /** Maximum amount of unimportant exceptions for one method; if reached * testing continues with a next method */ diff --git a/src/rand.c b/src/rand.c index 0ece784..83e3312 100644 --- a/src/rand.c +++ b/src/rand.c @@ -485,7 +485,7 @@ int df_rand_dbus_objpath_string(gchar **buf, guint64 iteration) /** * @function Allocates memory for pseudo-random signature string of size * counted by adding 1 to size variable on every call of function to maximum - * size of MAXSIG. On every call pseudo-random signature string is generated + * size of MAX_SIGNATURE_LENGTH. On every call pseudo-random signature string is generated * by random access into global variable df_sig_def which contains all D-Bus * signatures and copying signature into buf buffer. * Warning: buf should be freed outside this module by callee of this @@ -501,7 +501,7 @@ int df_rand_dbus_signature_string(gchar **buf, guint64 iteration) g_autoptr(gchar) ret = NULL; uint16_t size, i = 0; - size = (iteration % MAXSIG) + 1; + size = (iteration % MAX_SIGNATURE_LENGTH) + 1; ret = g_try_new(gchar, size + 1); if (!ret) diff --git a/src/rand.h b/src/rand.h index 75229d9..54d8b1e 100644 --- a/src/rand.h +++ b/src/rand.h @@ -22,18 +22,6 @@ #include "fuzz.h" -/** Minimal buffer size for generated strings */ -#define MINLEN 512 - -/** Maximum buffer size for generated strings, default is cca 50 kB */ -#define MAX_BUF_LEN 50000 - -/** Maximum length of strings containing D-Bus object path */ -#define MAXLEN 256 - -/** Maximum length of D-Bus signature string */ -#define MAXSIG 255 - #define OBJECT_PATH_VALID_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "abcdefghijklmnopqrstuvwxyz" \ "0123456789_" @@ -114,7 +102,7 @@ int df_rand_string(gchar **buf, guint64 iteration); /** * @function Allocates memory for pseudo-random object path string of size * counted by adding 1 to size variable on every call of function to maximum - * size of MAXLEN. On every call pseudo-random object path string is generated + * size of MAX_OBJECT_PATH_LENGTH. On every call pseudo-random object path string is generated * into buf buffer. * Warning: buf should be freed outside this module by callee of this * function. @@ -127,7 +115,7 @@ int df_rand_dbus_objpath_string(gchar **buf, guint64 iteration); /** * @function Allocates memory for pseudo-random signature string of size * counted by adding 1 to size variable on every call of function to maximum - * size of MAXSIG. On every call pseudo-random signature string is generated + * size of MAX_SIGNATURE_LENGTH. On every call pseudo-random signature string is generated * by random access into global variable df_sig_def which contains all D-Bus * signatures and copying signature into buf buffer. * Warning: buf should be freed outside this module by callee of this From 99ae9ce53f79bc663efeed542876e87ebb30cc52 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 23 Jun 2022 16:45:11 +0200 Subject: [PATCH 2/3] rand: make pseudo-random variants a bit more variable Until now all pseudo-random variants were always strings. Since a true variant can contain any _complete_ type, let's use at least any _basic_ type, for now. Extending this to any complete type must wait until we can generate arbitrary signatures. --- src/fuzz.c | 178 +-------------------------------------------- src/fuzz.h | 7 +- src/rand.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/rand.h | 3 + 4 files changed, 202 insertions(+), 194 deletions(-) diff --git a/src/fuzz.c b/src/fuzz.c index f53a49f..745ca51 100644 --- a/src/fuzz.c +++ b/src/fuzz.c @@ -51,7 +51,8 @@ static void df_fuzz_write_log(const struct df_dbus_method *method, GVariant *val static int df_exec_cmd_check(const char *cmd); static int df_fuzz_call_method(const struct df_dbus_method *method, GVariant *value); -guint64 df_get_number_of_iterations(const char *signature) { +guint64 df_get_number_of_iterations(const char *signature) +{ guint64 iterations = 0; guint32 multiplier = 1, current_nest_level = 0; @@ -117,181 +118,6 @@ guint64 df_get_number_of_iterations(const char *signature) { return CLAMP(iterations, 10, G_MAXUINT64); } -/* Generate a GVariant with random data for a basic (non-compound) type - * - * Note: variant itself is treated as a basic type, since it's a bit special and - * cannot be iterated on - */ -GVariant *df_generate_random_basic(const GVariantType *type, guint64 iteration) { - g_autoptr(char) ssig = NULL; - - if (!type) { - g_assert_not_reached(); - return NULL; - } - - ssig = g_variant_type_dup_string(type); - - if (g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) - return g_variant_new(ssig, df_rand_gboolean(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) - return g_variant_new(ssig, df_rand_guint8(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) - return g_variant_new(ssig, df_rand_gint16(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) - return g_variant_new(ssig, df_rand_guint16(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) - return g_variant_new(ssig, df_rand_gint32(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) - return g_variant_new(ssig, df_rand_guint32(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) - return g_variant_new(ssig, df_rand_gint64(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) - return g_variant_new(ssig, df_rand_guint64(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_HANDLE)) - return g_variant_new(ssig, df_rand_unixFD(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_DOUBLE)) - return g_variant_new(ssig, df_rand_gdouble(iteration)); - else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING)) { - g_autoptr(char) str = NULL; - - if (df_rand_string(&str, iteration) < 0) { - df_fail("Failed to generate a random string\n"); - return NULL; - } - - return g_variant_new(ssig, str); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_OBJECT_PATH)) { - g_autoptr(char) obj_path = NULL; - - if (df_rand_dbus_objpath_string(&obj_path, iteration) < 0) { - df_fail("Failed to generate a random object path\n"); - return NULL; - } - - return g_variant_new(ssig, obj_path); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_SIGNATURE)) { - g_autoptr(char) sig_str = NULL; - - if (df_rand_dbus_signature_string(&sig_str, iteration) < 0) { - df_fail("Failed to generate a random signature string\n"); - return NULL; - } - - return g_variant_new(ssig, sig_str); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_VARIANT)) { - GVariant *variant = NULL; - - if (df_rand_GVariant(&variant, iteration) < 0) { - df_fail("Failed to generate a random GVariant\n"); - return NULL; - } - - return g_variant_new(ssig, variant); - } else { - df_fail("Invalid basic type: %s\n", ssig); - g_assert_not_reached(); - } - - return NULL; -} - -GVariant *df_generate_random_from_signature(const char *signature, guint64 iteration) -{ - g_autoptr(GVariantType) type = NULL; - g_autoptr(GVariantBuilder) builder = NULL; - - if (!signature || - !g_variant_is_signature(signature) || - !g_variant_type_string_is_valid(signature)) { - df_fail("Invalid signature: %s\n", signature); - return NULL; - } - - type = g_variant_type_new(signature); - /* Leaf nodes */ - if (g_variant_type_is_basic(type) || g_variant_type_is_variant(type)) - return df_generate_random_basic(type, iteration); - - builder = g_variant_builder_new(type); - - for (const GVariantType *iter = g_variant_type_first(type); - iter; - iter = g_variant_type_next(iter)) { - - g_autoptr(char) ssig = NULL; - - ssig = g_variant_type_dup_string(iter); - - if (g_variant_type_is_basic(iter) || g_variant_type_is_variant(iter)) { - /* Basic type, generate a random value - * Note: treat 'variant' as a basic type, since it can't - * be iterated on by g_variant_type_{first,next}() - */ - GVariant *basic; - - basic = df_generate_random_basic(iter, iteration); - if (!basic) - return NULL; - - g_variant_builder_add_value(builder, basic); - } else if (g_variant_type_is_tuple(iter)) { - /* Tuple */ - GVariant *tuple = NULL; - - tuple = df_generate_random_from_signature(ssig, iteration); - if (!tuple) - return NULL; - - g_variant_builder_add_value(builder, tuple); - } else if (g_variant_type_is_array(iter)) { - /* Array */ - g_autoptr(char) array_signature = NULL; - const GVariantType *array_type = NULL; - int nest_level = 0; - - /* Open the "main" array container */ - g_variant_builder_open(builder, iter); - - /* Resolve all levels of arrays (e.g. aaaai) */ - for (array_type = g_variant_type_element(iter); - g_variant_type_is_array(array_type); - array_type = g_variant_type_element(array_type)) { - - /* Open an container for each nested array */ - g_variant_builder_open(builder, array_type); - nest_level++; - } - - array_signature = g_variant_type_dup_string(array_type); - - /* Create a pseudo-randomly sized array */ - for (size_t i = 0; i < df_rand_array_size(iteration); i++) { - GVariant *array_item = NULL; - - array_item = df_generate_random_from_signature(array_signature, iteration); - if (!array_item) - return NULL; - - g_variant_builder_add_value(builder, array_item); - } - - /* Close container of each array level */ - for (int i = 0; i < nest_level; i++) - g_variant_builder_close(builder); - - /* Close the "main" array container */ - g_variant_builder_close(builder); - } else { - /* TODO: maybe */ - df_fail("Not implemented: %s\n", ssig); - return NULL; - } - } - - return g_variant_builder_end(builder); -} - /** * @function Saves pointer on D-Bus interface proxy for this module to be * able to call methods through this proxy during fuzz testing. diff --git a/src/fuzz.h b/src/fuzz.h index e09cab9..344258f 100644 --- a/src/fuzz.h +++ b/src/fuzz.h @@ -31,6 +31,11 @@ #define MAX_SIGNATURE_LENGTH 255 #define MAX_SUPPRESSIONS 256 +/* Basic (non-container) types which can appear in a signature + * + * https://dbus.freedesktop.org/doc/dbus-specification.html#id-1.3.8 + */ +#define SIGNATURE_BASIC_TYPES "ybnqiuxtdsogh" /** Maximum amount of unimportant exceptions for one method; if reached * testing continues with a next method */ @@ -69,8 +74,6 @@ G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(df_dbus_method_t, df_dbus_method_clear) G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(df_dbus_property_t, df_dbus_property_clear) guint64 df_get_number_of_iterations(const char *signature); -GVariant *df_generate_random_basic(const GVariantType *type, guint64 iteration); -GVariant *df_generate_random_from_signature(const char *signature, guint64 iteration); /** * @function Saves pointer on D-Bus interface proxy for this module to be * able to call methods through this proxy during fuzz testing. Also saves diff --git a/src/rand.c b/src/rand.c index 83e3312..d90c1c3 100644 --- a/src/rand.c +++ b/src/rand.c @@ -19,12 +19,13 @@ */ #include #include +#include +#include +#include #include #include #include -#include #include -#include #include "rand.h" #include "dfuzzer.h" @@ -82,6 +83,183 @@ int df_rand_load_external_dictionary(const char *filename) return 0; } +/* Generate a GVariant with random data for a basic (non-compound) type + * + * Note: variant itself is treated as a basic type, since it's a bit special and + * cannot be iterated on + */ +GVariant *df_generate_random_basic(const GVariantType *type, guint64 iteration) +{ + g_autoptr(char) ssig = NULL; + + if (!type) { + g_assert_not_reached(); + return NULL; + } + + ssig = g_variant_type_dup_string(type); + + if (g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) + return g_variant_new(ssig, df_rand_gboolean(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) + return g_variant_new(ssig, df_rand_guint8(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) + return g_variant_new(ssig, df_rand_gint16(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) + return g_variant_new(ssig, df_rand_guint16(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) + return g_variant_new(ssig, df_rand_gint32(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) + return g_variant_new(ssig, df_rand_guint32(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) + return g_variant_new(ssig, df_rand_gint64(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) + return g_variant_new(ssig, df_rand_guint64(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_HANDLE)) + return g_variant_new(ssig, df_rand_unixFD(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_DOUBLE)) + return g_variant_new(ssig, df_rand_gdouble(iteration)); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING)) { + g_autoptr(char) str = NULL; + + if (df_rand_string(&str, iteration) < 0) { + df_fail("Failed to generate a random string\n"); + return NULL; + } + + return g_variant_new(ssig, str); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_OBJECT_PATH)) { + g_autoptr(char) obj_path = NULL; + + if (df_rand_dbus_objpath_string(&obj_path, iteration) < 0) { + df_fail("Failed to generate a random object path\n"); + return NULL; + } + + return g_variant_new(ssig, obj_path); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_SIGNATURE)) { + g_autoptr(char) sig_str = NULL; + + if (df_rand_dbus_signature_string(&sig_str, iteration) < 0) { + df_fail("Failed to generate a random signature string\n"); + return NULL; + } + + return g_variant_new(ssig, sig_str); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_VARIANT)) { + GVariant *variant = NULL; + + if (df_rand_GVariant(&variant, iteration) < 0) { + df_fail("Failed to generate a random GVariant\n"); + return NULL; + } + + return g_variant_new(ssig, variant); + } else { + df_fail("Invalid basic type: %s\n", ssig); + g_assert_not_reached(); + } + + return NULL; +} + +GVariant *df_generate_random_from_signature(const char *signature, guint64 iteration) +{ + g_autoptr(GVariantType) type = NULL; + g_autoptr(GVariantBuilder) builder = NULL; + + if (!signature || + !g_variant_is_signature(signature) || + !g_variant_type_string_is_valid(signature)) { + df_fail("Invalid signature: %s\n", signature); + return NULL; + } + + type = g_variant_type_new(signature); + /* Leaf nodes */ + if (g_variant_type_is_basic(type) || g_variant_type_is_variant(type)) + return df_generate_random_basic(type, iteration); + + builder = g_variant_builder_new(type); + + for (const GVariantType *iter = g_variant_type_first(type); + iter; + iter = g_variant_type_next(iter)) { + + g_autoptr(char) ssig = NULL; + + ssig = g_variant_type_dup_string(iter); + + if (g_variant_type_is_basic(iter) || g_variant_type_is_variant(iter)) { + /* Basic type, generate a random value + * Note: treat 'variant' as a basic type, since it can't + * be iterated on by g_variant_type_{first,next}() + */ + GVariant *basic; + + basic = df_generate_random_basic(iter, iteration); + if (!basic) + return NULL; + + g_variant_builder_add_value(builder, basic); + } else if (g_variant_type_is_tuple(iter)) { + /* Tuple */ + GVariant *tuple = NULL; + + tuple = df_generate_random_from_signature(ssig, iteration); + if (!tuple) + return NULL; + + g_variant_builder_add_value(builder, tuple); + } else if (g_variant_type_is_array(iter)) { + /* Array */ + g_autoptr(char) array_signature = NULL; + const GVariantType *array_type = NULL; + int nest_level = 0; + + /* Open the "main" array container */ + g_variant_builder_open(builder, iter); + + /* Resolve all levels of arrays (e.g. aaaai) */ + for (array_type = g_variant_type_element(iter); + g_variant_type_is_array(array_type); + array_type = g_variant_type_element(array_type)) { + + /* Open an container for each nested array */ + g_variant_builder_open(builder, array_type); + nest_level++; + } + + array_signature = g_variant_type_dup_string(array_type); + + /* Create a pseudo-randomly sized array */ + for (size_t i = 0; i < df_rand_array_size(iteration); i++) { + GVariant *array_item = NULL; + + array_item = df_generate_random_from_signature(array_signature, iteration); + if (!array_item) + return NULL; + + g_variant_builder_add_value(builder, array_item); + } + + /* Close container of each array level */ + for (int i = 0; i < nest_level; i++) + g_variant_builder_close(builder); + + /* Close the "main" array container */ + g_variant_builder_close(builder); + } else { + /* TODO: maybe */ + df_fail("Not implemented: %s\n", ssig); + return NULL; + } + } + + return g_variant_builder_end(builder); +} + + size_t df_rand_array_size(guint64 iteration) { /* Generate an empty array on the first iteration */ @@ -497,7 +675,7 @@ int df_rand_dbus_objpath_string(gchar **buf, guint64 iteration) int df_rand_dbus_signature_string(gchar **buf, guint64 iteration) { /* TODO: support arrays ('a') and other complex types */ - static const char valid_signature_chars[] = "ybnqiuxtdsogvh"; + static const char *valid_signature_chars = SIGNATURE_BASIC_TYPES "v"; g_autoptr(gchar) ret = NULL; uint16_t size, i = 0; @@ -516,23 +694,21 @@ int df_rand_dbus_signature_string(gchar **buf, guint64 iteration) return 0; } -/** - * @function Creates Gvariant containing pseudo-random string. At the beginning - * strings from global array df_str_def are used. - * @param var Address of pointer on GVariant where new Gvariant value - * will be stored - * @return 0 on success, -1 on error - */ +/* Create a GVariant containing a random basic type + * + * TODO: add support for any complete type once we're able to generate + * arbitrary signatures + * */ int df_rand_GVariant(GVariant **var, guint64 iteration) { - g_autoptr(gchar) str = NULL; - int r; + char sig[2]; - r = df_rand_string(&str, iteration); - if (r < 0) - return r; + sig[0] = SIGNATURE_BASIC_TYPES[rand() % strlen(SIGNATURE_BASIC_TYPES)]; + sig[1] = 0; - *var = g_variant_new("s", str); + *var = df_generate_random_basic(G_VARIANT_TYPE(sig), iteration); + if (!*var) + return -1; return 0; } diff --git a/src/rand.h b/src/rand.h index 54d8b1e..a3cfca0 100644 --- a/src/rand.h +++ b/src/rand.h @@ -38,6 +38,9 @@ struct external_dictionary { void df_rand_init(); int df_rand_load_external_dictionary(const char *filename); +GVariant *df_generate_random_basic(const GVariantType *type, guint64 iteration); +GVariant *df_generate_random_from_signature(const char *signature, guint64 iteration); + size_t df_rand_array_size(guint64 iteration); /** From 8f5e1623f3499b2c1134cff3d4b316b83aa28679 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 23 Jun 2022 17:59:24 +0200 Subject: [PATCH 3/3] test: check if the received signature is valid --- src/dfuzzer-test-server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dfuzzer-test-server.c b/src/dfuzzer-test-server.c index 79b7d90..56dacbb 100644 --- a/src/dfuzzer-test-server.c +++ b/src/dfuzzer-test-server.c @@ -164,6 +164,7 @@ static void handle_method_call( g_variant_get(parameters, "(iu&g@a{ss}@a(uiyo))", &i, &u, &str, NULL, NULL); g_printf("%s: signature size: %zu\n", method_name, strlen(str)); + g_assert_true(g_variant_is_signature(str)); response = g_strdup_printf("%s", str); g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", response));