Commit f5ec79f5 authored by Alexander Bulekov's avatar Alexander Bulekov Committed by Thomas Huth
Browse files

fuzz: Expect the cmdline in a freeable GString



In the initial FuzzTarget, get_init_cmdline returned a char *. With this
API, we had no guarantee about where the string came from. For example,
i440fx-qtest-reboot-fuzz simply returned a pointer to a string literal,
while the QOS-based targets build the arguments out in a GString an
return the gchar *str pointer. Since we did not try to free the cmdline,
we have a leak for any targets that do not simply return string
literals. Clean up this mess by forcing fuzz-targets to return
a GString, that we can free.

Signed-off-by: default avatarAlexander Bulekov <alxndr@bu.edu>
Message-Id: <20200714174616.20709-1-alxndr@bu.edu>
Reviewed-by: default avatarDarren Kenny <darren.kenny@oracle.com>
Signed-off-by: default avatarThomas Huth <thuth@redhat.com>
parent 15c51f72
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -199,16 +199,15 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
    }

    /* Run QEMU's softmmu main with the fuzz-target dependent arguments */
    const char *init_cmdline = fuzz_target->get_init_cmdline(fuzz_target);
    init_cmdline = g_strdup_printf("%s -qtest /dev/null -qtest-log %s",
                                   init_cmdline,
                                   getenv("QTEST_LOG") ? "/dev/fd/2"
                                                       : "/dev/null");

    GString *cmd_line = fuzz_target->get_init_cmdline(fuzz_target);
    g_string_append_printf(cmd_line,
                           " -qtest /dev/null -qtest-log %s",
                           getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null");

    /* Split the runcmd into an argv and argc */
    wordexp_t result;
    wordexp(init_cmdline, &result, 0);
    wordexp(cmd_line->str, &result, 0);
    g_string_free(cmd_line, true);

    qemu_init(result.we_wordc, result.we_wordv, NULL);

+3 −3
Original line number Diff line number Diff line
@@ -50,10 +50,10 @@ typedef struct FuzzTarget {


    /*
     * returns the arg-list that is passed to qemu/softmmu init()
     * Cannot be NULL
     * Returns the arguments that are passed to qemu/softmmu init(). Freed by
     * the caller.
     */
    const char* (*get_init_cmdline)(struct FuzzTarget *);
    GString *(*get_init_cmdline)(struct FuzzTarget *);

    /*
     * will run once, prior to running qemu/softmmu init.
+2 −2
Original line number Diff line number Diff line
@@ -158,9 +158,9 @@ static void i440fx_fuzz_qos_fork(QTestState *s,

static const char *i440fx_qtest_argv = TARGET_NAME " -machine accel=qtest"
                                       " -m 0 -display none";
static const char *i440fx_argv(FuzzTarget *t)
static GString *i440fx_argv(FuzzTarget *t)
{
    return i440fx_qtest_argv;
    return g_string_new(i440fx_qtest_argv);
}

static void fork_init(void)
+3 −3
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ void *qos_allocate_objects(QTestState *qts, QGuestAllocator **p_alloc)
    return allocate_objects(qts, current_path + 1, p_alloc);
}

static const char *qos_build_main_args(void)
static GString *qos_build_main_args(void)
{
    char **path = fuzz_path_vec;
    QOSGraphNode *test_node;
@@ -88,7 +88,7 @@ static const char *qos_build_main_args(void)
    /* Prepend the arguments that we need */
    g_string_prepend(cmd_line,
            TARGET_NAME " -display none -machine accel=qtest -m 64 ");
    return cmd_line->str;
    return cmd_line;
}

/*
@@ -189,7 +189,7 @@ static void walk_path(QOSGraphNode *orig_path, int len)
    g_free(path_str);
}

static const char *qos_get_cmdline(FuzzTarget *t)
static GString *qos_get_cmdline(FuzzTarget *t)
{
    /*
     * Set a global variable that we use to identify the qos_path for our