1 /*
2 * Copyright 2021 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include <stdbool.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10
11 #include "os/os_misc.h"
12 #include "virglrenderer.h"
13 #include "virglrenderer_hw.h"
14
15 int
16 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
17
18 struct fuzz_renderer {
19 bool initialized;
20 };
21
22 static void
fuzz_atexit_callback(void)23 fuzz_atexit_callback(void)
24 {
25 virgl_renderer_cleanup(NULL);
26 }
27
28 static void
fuzz_debug_callback(UNUSED const char * fmt,UNUSED va_list ap)29 fuzz_debug_callback(UNUSED const char *fmt, UNUSED va_list ap)
30 {
31 /* no logging */
32 }
33
34 static struct fuzz_renderer *
fuzz_renderer_get(void)35 fuzz_renderer_get(void)
36 {
37 static struct fuzz_renderer renderer;
38 if (renderer.initialized)
39 return &renderer;
40
41 int ret =
42 virgl_renderer_init(NULL, VIRGL_RENDERER_VENUS | VIRGL_RENDERER_NO_VIRGL, NULL);
43 if (ret)
44 abort();
45
46 virgl_set_debug_callback(fuzz_debug_callback);
47
48 atexit(fuzz_atexit_callback);
49
50 renderer.initialized = true;
51 return &renderer;
52 }
53
54 static uint32_t
fuzz_context_create(UNUSED struct fuzz_renderer * renderer)55 fuzz_context_create(UNUSED struct fuzz_renderer *renderer)
56 {
57 const uint32_t ctx_id = 1;
58 const char name[] = "virgl_venus_fuzzer";
59 int ret = virgl_renderer_context_create_with_flags(ctx_id, VIRGL_RENDERER_CAPSET_VENUS,
60 sizeof(name), name);
61 if (ret)
62 abort();
63
64 return ctx_id;
65 }
66
67 static void
fuzz_context_destroy(UNUSED struct fuzz_renderer * renderer,uint32_t ctx_id)68 fuzz_context_destroy(UNUSED struct fuzz_renderer *renderer, uint32_t ctx_id)
69 {
70 virgl_renderer_context_destroy(ctx_id);
71 }
72
73 static void
fuzz_context_submit(UNUSED struct fuzz_renderer * renderer,uint32_t ctx_id,const uint8_t * data,size_t size)74 fuzz_context_submit(UNUSED struct fuzz_renderer *renderer,
75 uint32_t ctx_id,
76 const uint8_t *data,
77 size_t size)
78 {
79 virgl_renderer_submit_cmd((void *)data, ctx_id, size / 4);
80 }
81
82 int
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)83 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
84 {
85 struct fuzz_renderer *renderer = fuzz_renderer_get();
86
87 const uint32_t ctx_id = fuzz_context_create(renderer);
88 fuzz_context_submit(renderer, ctx_id, data, size);
89 fuzz_context_destroy(renderer, ctx_id);
90
91 return 0;
92 }
93