xref: /aosp_15_r20/external/virglrenderer/tests/fuzzer/virgl_drm_fuzzer.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
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