1*bbecb9d1SAndroid Build Coastguard Worker /*
2*bbecb9d1SAndroid Build Coastguard Worker * Copyright 2021 Google LLC
3*bbecb9d1SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*bbecb9d1SAndroid Build Coastguard Worker */
5*bbecb9d1SAndroid Build Coastguard Worker
6*bbecb9d1SAndroid Build Coastguard Worker #include <stdbool.h>
7*bbecb9d1SAndroid Build Coastguard Worker #include <stddef.h>
8*bbecb9d1SAndroid Build Coastguard Worker #include <stdint.h>
9*bbecb9d1SAndroid Build Coastguard Worker #include <stdlib.h>
10*bbecb9d1SAndroid Build Coastguard Worker
11*bbecb9d1SAndroid Build Coastguard Worker #include "util/macros.h"
12*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer.h"
13*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer_hw.h"
14*bbecb9d1SAndroid Build Coastguard Worker
15*bbecb9d1SAndroid Build Coastguard Worker int
16*bbecb9d1SAndroid Build Coastguard Worker LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
17*bbecb9d1SAndroid Build Coastguard Worker
18*bbecb9d1SAndroid Build Coastguard Worker struct fuzz_renderer {
19*bbecb9d1SAndroid Build Coastguard Worker bool initialized;
20*bbecb9d1SAndroid Build Coastguard Worker };
21*bbecb9d1SAndroid Build Coastguard Worker
22*bbecb9d1SAndroid Build Coastguard Worker static void
fuzz_atexit_callback(void)23*bbecb9d1SAndroid Build Coastguard Worker fuzz_atexit_callback(void)
24*bbecb9d1SAndroid Build Coastguard Worker {
25*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_cleanup(NULL);
26*bbecb9d1SAndroid Build Coastguard Worker }
27*bbecb9d1SAndroid Build Coastguard Worker
28*bbecb9d1SAndroid Build Coastguard Worker static void
fuzz_debug_callback(UNUSED const char * fmt,UNUSED va_list ap)29*bbecb9d1SAndroid Build Coastguard Worker fuzz_debug_callback(UNUSED const char *fmt, UNUSED va_list ap)
30*bbecb9d1SAndroid Build Coastguard Worker {
31*bbecb9d1SAndroid Build Coastguard Worker /* no logging */
32*bbecb9d1SAndroid Build Coastguard Worker }
33*bbecb9d1SAndroid Build Coastguard Worker
34*bbecb9d1SAndroid Build Coastguard Worker static void
fuzz_write_context_fence(UNUSED void * cookie,UNUSED uint32_t ctx_id,UNUSED uint32_t ring_idx,UNUSED uint64_t fence_id)35*bbecb9d1SAndroid Build Coastguard Worker fuzz_write_context_fence(UNUSED void *cookie,
36*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint32_t ctx_id,
37*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint32_t ring_idx,
38*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint64_t fence_id)
39*bbecb9d1SAndroid Build Coastguard Worker {
40*bbecb9d1SAndroid Build Coastguard Worker
41*bbecb9d1SAndroid Build Coastguard Worker }
42*bbecb9d1SAndroid Build Coastguard Worker
43*bbecb9d1SAndroid Build Coastguard Worker
44*bbecb9d1SAndroid Build Coastguard Worker static struct virgl_renderer_callbacks callbacks = {
45*bbecb9d1SAndroid Build Coastguard Worker .version = 3,
46*bbecb9d1SAndroid Build Coastguard Worker .write_context_fence = fuzz_write_context_fence,
47*bbecb9d1SAndroid Build Coastguard Worker };
48*bbecb9d1SAndroid Build Coastguard Worker
49*bbecb9d1SAndroid Build Coastguard Worker static struct fuzz_renderer *
fuzz_renderer_get(void)50*bbecb9d1SAndroid Build Coastguard Worker fuzz_renderer_get(void)
51*bbecb9d1SAndroid Build Coastguard Worker {
52*bbecb9d1SAndroid Build Coastguard Worker static struct fuzz_renderer renderer;
53*bbecb9d1SAndroid Build Coastguard Worker if (renderer.initialized)
54*bbecb9d1SAndroid Build Coastguard Worker return &renderer;
55*bbecb9d1SAndroid Build Coastguard Worker
56*bbecb9d1SAndroid Build Coastguard Worker int flags = VIRGL_RENDERER_NO_VIRGL | VIRGL_RENDERER_DRM |
57*bbecb9d1SAndroid Build Coastguard Worker VIRGL_RENDERER_ASYNC_FENCE_CB;
58*bbecb9d1SAndroid Build Coastguard Worker int ret =
59*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_init(NULL, flags, &callbacks);
60*bbecb9d1SAndroid Build Coastguard Worker if (ret)
61*bbecb9d1SAndroid Build Coastguard Worker abort();
62*bbecb9d1SAndroid Build Coastguard Worker
63*bbecb9d1SAndroid Build Coastguard Worker virgl_set_debug_callback(fuzz_debug_callback);
64*bbecb9d1SAndroid Build Coastguard Worker
65*bbecb9d1SAndroid Build Coastguard Worker atexit(fuzz_atexit_callback);
66*bbecb9d1SAndroid Build Coastguard Worker
67*bbecb9d1SAndroid Build Coastguard Worker renderer.initialized = true;
68*bbecb9d1SAndroid Build Coastguard Worker return &renderer;
69*bbecb9d1SAndroid Build Coastguard Worker }
70*bbecb9d1SAndroid Build Coastguard Worker
71*bbecb9d1SAndroid Build Coastguard Worker static uint32_t
fuzz_context_create(UNUSED struct fuzz_renderer * renderer)72*bbecb9d1SAndroid Build Coastguard Worker fuzz_context_create(UNUSED struct fuzz_renderer *renderer)
73*bbecb9d1SAndroid Build Coastguard Worker {
74*bbecb9d1SAndroid Build Coastguard Worker const uint32_t ctx_id = 1;
75*bbecb9d1SAndroid Build Coastguard Worker const char name[] = "virgl_drm_fuzzer";
76*bbecb9d1SAndroid Build Coastguard Worker int ret = virgl_renderer_context_create_with_flags(ctx_id, VIRGL_RENDERER_CAPSET_DRM,
77*bbecb9d1SAndroid Build Coastguard Worker sizeof(name), name);
78*bbecb9d1SAndroid Build Coastguard Worker if (ret)
79*bbecb9d1SAndroid Build Coastguard Worker abort();
80*bbecb9d1SAndroid Build Coastguard Worker
81*bbecb9d1SAndroid Build Coastguard Worker return ctx_id;
82*bbecb9d1SAndroid Build Coastguard Worker }
83*bbecb9d1SAndroid Build Coastguard Worker
84*bbecb9d1SAndroid Build Coastguard Worker static void
fuzz_context_destroy(UNUSED struct fuzz_renderer * renderer,uint32_t ctx_id)85*bbecb9d1SAndroid Build Coastguard Worker fuzz_context_destroy(UNUSED struct fuzz_renderer *renderer, uint32_t ctx_id)
86*bbecb9d1SAndroid Build Coastguard Worker {
87*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_context_destroy(ctx_id);
88*bbecb9d1SAndroid Build Coastguard Worker }
89*bbecb9d1SAndroid Build Coastguard Worker
90*bbecb9d1SAndroid Build Coastguard Worker static void
fuzz_context_submit(UNUSED struct fuzz_renderer * renderer,uint32_t ctx_id,const uint8_t * data,size_t size)91*bbecb9d1SAndroid Build Coastguard Worker fuzz_context_submit(UNUSED struct fuzz_renderer *renderer,
92*bbecb9d1SAndroid Build Coastguard Worker uint32_t ctx_id,
93*bbecb9d1SAndroid Build Coastguard Worker const uint8_t *data,
94*bbecb9d1SAndroid Build Coastguard Worker size_t size)
95*bbecb9d1SAndroid Build Coastguard Worker {
96*bbecb9d1SAndroid Build Coastguard Worker /* We'll not be able to hit some codepaths without shmem buffer setup..
97*bbecb9d1SAndroid Build Coastguard Worker * but we'd also like to hit any potential errors that could come from
98*bbecb9d1SAndroid Build Coastguard Worker * malicious input before shmem is setup. So run the same input twice,
99*bbecb9d1SAndroid Build Coastguard Worker * once before and once after shmem setup.
100*bbecb9d1SAndroid Build Coastguard Worker */
101*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_submit_cmd((void *)data, ctx_id, size / 4);
102*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_resource_create_blob(&(struct virgl_renderer_resource_create_blob_args){
103*bbecb9d1SAndroid Build Coastguard Worker .res_handle = 1,
104*bbecb9d1SAndroid Build Coastguard Worker .ctx_id = ctx_id,
105*bbecb9d1SAndroid Build Coastguard Worker .size = 0x1000,
106*bbecb9d1SAndroid Build Coastguard Worker });
107*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_submit_cmd((void *)data, ctx_id, size / 4);
108*bbecb9d1SAndroid Build Coastguard Worker }
109*bbecb9d1SAndroid Build Coastguard Worker
110*bbecb9d1SAndroid Build Coastguard Worker int
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)111*bbecb9d1SAndroid Build Coastguard Worker LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
112*bbecb9d1SAndroid Build Coastguard Worker {
113*bbecb9d1SAndroid Build Coastguard Worker struct fuzz_renderer *renderer = fuzz_renderer_get();
114*bbecb9d1SAndroid Build Coastguard Worker
115*bbecb9d1SAndroid Build Coastguard Worker const uint32_t ctx_id = fuzz_context_create(renderer);
116*bbecb9d1SAndroid Build Coastguard Worker fuzz_context_submit(renderer, ctx_id, data, size);
117*bbecb9d1SAndroid Build Coastguard Worker fuzz_context_destroy(renderer, ctx_id);
118*bbecb9d1SAndroid Build Coastguard Worker
119*bbecb9d1SAndroid Build Coastguard Worker return 0;
120*bbecb9d1SAndroid Build Coastguard Worker }
121