diff options
author | Rob Clark <robdclark@chromium.org> | 2022-04-27 14:07:27 -0700 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-05-02 20:50:00 +0000 |
commit | df12c3835bcd327e4ea8f655617442931c86e16e (patch) | |
tree | d6de10f71df34638c374549e60f7384f78c3a57f /tests | |
parent | 112191419e1c38df43eba0514a0e5354a3ce1a09 (diff) |
drm: Add fuzzer support
This can be run on hw other than what the drm native context supports
using mesa's drm-shim. Ie. to fuzz the msm backend, you can LD_PRELOAD
libfreedreno_noop_drm_shim.so from mesa built with freedreno enabled
and -Dtools=drm-shim enable.
Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Part-of: <https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/795>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/fuzzer/meson.build | 10 | ||||
-rw-r--r-- | tests/fuzzer/virgl_drm_fuzzer.c | 120 |
2 files changed, 130 insertions, 0 deletions
diff --git a/tests/fuzzer/meson.build b/tests/fuzzer/meson.build index 7c9a10d..5ea892c 100644 --- a/tests/fuzzer/meson.build +++ b/tests/fuzzer/meson.build @@ -41,3 +41,13 @@ if with_venus dependencies : [libvirglrenderer_dep] ) endif + +if with_drm + virgl_drm_fuzzer = executable( + 'virgl_drm_fuzzer', + 'virgl_drm_fuzzer.c', + c_args : [ '-fsanitize=fuzzer' ], + link_args : [ '-fsanitize=fuzzer' ], + dependencies : [libvirglrenderer_dep] + ) +endif diff --git a/tests/fuzzer/virgl_drm_fuzzer.c b/tests/fuzzer/virgl_drm_fuzzer.c new file mode 100644 index 0000000..5be865b --- /dev/null +++ b/tests/fuzzer/virgl_drm_fuzzer.c @@ -0,0 +1,120 @@ +/* + * Copyright 2021 Google LLC + * SPDX-License-Identifier: MIT + */ + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include "util/macros.h" +#include "virglrenderer.h" +#include "virglrenderer_hw.h" + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +struct fuzz_renderer { + bool initialized; +}; + +static void +fuzz_atexit_callback(void) +{ + virgl_renderer_cleanup(NULL); +} + +static void +fuzz_debug_callback(UNUSED const char *fmt, UNUSED va_list ap) +{ + /* no logging */ +} + +static void +fuzz_write_context_fence(UNUSED void *cookie, + UNUSED uint32_t ctx_id, + UNUSED uint64_t queue_id, + UNUSED void *fence_cookie) +{ + +} + + +static struct virgl_renderer_callbacks callbacks = { + .version = 3, + .write_context_fence = fuzz_write_context_fence, +}; + +static struct fuzz_renderer * +fuzz_renderer_get(void) +{ + static struct fuzz_renderer renderer; + if (renderer.initialized) + return &renderer; + + int flags = VIRGL_RENDERER_NO_VIRGL | VIRGL_RENDERER_DRM | + VIRGL_RENDERER_ASYNC_FENCE_CB; + int ret = + virgl_renderer_init(NULL, flags, &callbacks); + if (ret) + abort(); + + virgl_set_debug_callback(fuzz_debug_callback); + + atexit(fuzz_atexit_callback); + + renderer.initialized = true; + return &renderer; +} + +static uint32_t +fuzz_context_create(UNUSED struct fuzz_renderer *renderer) +{ + const uint32_t ctx_id = 1; + const char name[] = "virgl_drm_fuzzer"; + int ret = virgl_renderer_context_create_with_flags(ctx_id, VIRGL_RENDERER_CAPSET_DRM, + sizeof(name), name); + if (ret) + abort(); + + return ctx_id; +} + +static void +fuzz_context_destroy(UNUSED struct fuzz_renderer *renderer, uint32_t ctx_id) +{ + virgl_renderer_context_destroy(ctx_id); +} + +static void +fuzz_context_submit(UNUSED struct fuzz_renderer *renderer, + uint32_t ctx_id, + const uint8_t *data, + size_t size) +{ + /* We'll not be able to hit some codepaths without shmem buffer setup.. + * but we'd also like to hit any potential errors that could come from + * malicious input before shmem is setup. So run the same input twice, + * once before and once after shmem setup. + */ + virgl_renderer_submit_cmd((void *)data, ctx_id, size / 4); + virgl_renderer_resource_create_blob(&(struct virgl_renderer_resource_create_blob_args){ + .res_handle = 1, + .ctx_id = ctx_id, + .size = 0x1000, + }); + virgl_renderer_submit_cmd((void *)data, ctx_id, size / 4); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct fuzz_renderer *renderer = fuzz_renderer_get(); + + const uint32_t ctx_id = fuzz_context_create(renderer); + fuzz_context_submit(renderer, ctx_id, data, size); + fuzz_context_destroy(renderer, ctx_id); + + return 0; +} |