xref: /aosp_15_r20/external/virglrenderer/vtest/vtest_fuzzer.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker // Copyright 2019 The Chromium OS Authors. All rights reserved.
2*bbecb9d1SAndroid Build Coastguard Worker //
3*bbecb9d1SAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without
4*bbecb9d1SAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are
5*bbecb9d1SAndroid Build Coastguard Worker // met:
6*bbecb9d1SAndroid Build Coastguard Worker //
7*bbecb9d1SAndroid Build Coastguard Worker //    * Redistributions of source code must retain the above copyright
8*bbecb9d1SAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer.
9*bbecb9d1SAndroid Build Coastguard Worker //    * Redistributions in binary form must reproduce the above
10*bbecb9d1SAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following disclaimer
11*bbecb9d1SAndroid Build Coastguard Worker // in the documentation and/or other materials provided with the
12*bbecb9d1SAndroid Build Coastguard Worker // distribution.
13*bbecb9d1SAndroid Build Coastguard Worker //    * Neither the name of Google Inc. nor the names of its
14*bbecb9d1SAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived from
15*bbecb9d1SAndroid Build Coastguard Worker // this software without specific prior written permission.
16*bbecb9d1SAndroid Build Coastguard Worker //
17*bbecb9d1SAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*bbecb9d1SAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*bbecb9d1SAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*bbecb9d1SAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*bbecb9d1SAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*bbecb9d1SAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*bbecb9d1SAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*bbecb9d1SAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*bbecb9d1SAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*bbecb9d1SAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*bbecb9d1SAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*bbecb9d1SAndroid Build Coastguard Worker 
29*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
30*bbecb9d1SAndroid Build Coastguard Worker #include <signal.h>
31*bbecb9d1SAndroid Build Coastguard Worker #include <stdbool.h>
32*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
33*bbecb9d1SAndroid Build Coastguard Worker #include <stdlib.h>
34*bbecb9d1SAndroid Build Coastguard Worker #include <sys/types.h>
35*bbecb9d1SAndroid Build Coastguard Worker #include <sys/socket.h>
36*bbecb9d1SAndroid Build Coastguard Worker #include <netinet/in.h>
37*bbecb9d1SAndroid Build Coastguard Worker #include <sys/un.h>
38*bbecb9d1SAndroid Build Coastguard Worker #include <fcntl.h>
39*bbecb9d1SAndroid Build Coastguard Worker #include <getopt.h>
40*bbecb9d1SAndroid Build Coastguard Worker #include <string.h>
41*bbecb9d1SAndroid Build Coastguard Worker 
42*bbecb9d1SAndroid Build Coastguard Worker #include "util.h"
43*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_memory.h"
44*bbecb9d1SAndroid Build Coastguard Worker #include "vtest.h"
45*bbecb9d1SAndroid Build Coastguard Worker #include "vtest_protocol.h"
46*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer.h"
47*bbecb9d1SAndroid Build Coastguard Worker 
48*bbecb9d1SAndroid Build Coastguard Worker int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
49*bbecb9d1SAndroid Build Coastguard Worker 
50*bbecb9d1SAndroid Build Coastguard Worker #ifndef CLEANUP_EACH_INPUT
51*bbecb9d1SAndroid Build Coastguard Worker // eglInitialize leaks unless eglTeriminate is called (which only happens
52*bbecb9d1SAndroid Build Coastguard Worker // with CLEANUP_EACH_INPUT), so suppress leak detection on everything
53*bbecb9d1SAndroid Build Coastguard Worker // allocated by it.
54*bbecb9d1SAndroid Build Coastguard Worker 
55*bbecb9d1SAndroid Build Coastguard Worker #if !defined(__has_feature)
56*bbecb9d1SAndroid Build Coastguard Worker #define __has_feature(x) 0
57*bbecb9d1SAndroid Build Coastguard Worker #endif
58*bbecb9d1SAndroid Build Coastguard Worker 
59*bbecb9d1SAndroid Build Coastguard Worker #if __has_feature(address_sanitizer)
60*bbecb9d1SAndroid Build Coastguard Worker const char* __lsan_default_suppressions(void);
61*bbecb9d1SAndroid Build Coastguard Worker 
__lsan_default_suppressions()62*bbecb9d1SAndroid Build Coastguard Worker const char* __lsan_default_suppressions() {
63*bbecb9d1SAndroid Build Coastguard Worker    return "leak:dri2_initialize_surfaceless\n";
64*bbecb9d1SAndroid Build Coastguard Worker }
65*bbecb9d1SAndroid Build Coastguard Worker #endif // __has_feature(address_sanitizer)
66*bbecb9d1SAndroid Build Coastguard Worker 
67*bbecb9d1SAndroid Build Coastguard Worker #endif // !CLEANUP_EACH_INPUT
68*bbecb9d1SAndroid Build Coastguard Worker 
69*bbecb9d1SAndroid Build Coastguard Worker typedef int (*vtest_cmd_fptr_t)(uint32_t);
70*bbecb9d1SAndroid Build Coastguard Worker 
71*bbecb9d1SAndroid Build Coastguard Worker static vtest_cmd_fptr_t vtest_commands[] = {
72*bbecb9d1SAndroid Build Coastguard Worker    NULL /* CMD ids starts at 1 */,
73*bbecb9d1SAndroid Build Coastguard Worker    vtest_send_caps,
74*bbecb9d1SAndroid Build Coastguard Worker    vtest_create_resource,
75*bbecb9d1SAndroid Build Coastguard Worker    vtest_resource_unref,
76*bbecb9d1SAndroid Build Coastguard Worker    vtest_transfer_get_nop,
77*bbecb9d1SAndroid Build Coastguard Worker    vtest_transfer_put_nop,
78*bbecb9d1SAndroid Build Coastguard Worker    vtest_submit_cmd,
79*bbecb9d1SAndroid Build Coastguard Worker    NULL, /* VCMD_RESOURCE_BUSY_WAIT is determined by VTEST_FUZZER_FENCES */
80*bbecb9d1SAndroid Build Coastguard Worker    NULL, /* VCMD_CREATE_RENDERER is a specific case */
81*bbecb9d1SAndroid Build Coastguard Worker    vtest_send_caps2,
82*bbecb9d1SAndroid Build Coastguard Worker    vtest_ping_protocol_version,
83*bbecb9d1SAndroid Build Coastguard Worker    vtest_protocol_version,
84*bbecb9d1SAndroid Build Coastguard Worker    vtest_create_resource2,
85*bbecb9d1SAndroid Build Coastguard Worker    vtest_transfer_get2_nop,
86*bbecb9d1SAndroid Build Coastguard Worker    vtest_transfer_put2_nop,
87*bbecb9d1SAndroid Build Coastguard Worker };
88*bbecb9d1SAndroid Build Coastguard Worker 
vtest_fuzzer_run_renderer(int out_fd,struct vtest_input * input,int ctx_flags,bool wait_fences)89*bbecb9d1SAndroid Build Coastguard Worker static void vtest_fuzzer_run_renderer(int out_fd, struct vtest_input *input,
90*bbecb9d1SAndroid Build Coastguard Worker                                       int ctx_flags, bool wait_fences)
91*bbecb9d1SAndroid Build Coastguard Worker {
92*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *context = NULL;
93*bbecb9d1SAndroid Build Coastguard Worker    int ret;
94*bbecb9d1SAndroid Build Coastguard Worker    uint32_t header[VTEST_HDR_SIZE];
95*bbecb9d1SAndroid Build Coastguard Worker 
96*bbecb9d1SAndroid Build Coastguard Worker    vtest_commands[VCMD_RESOURCE_BUSY_WAIT] = wait_fences ?
97*bbecb9d1SAndroid Build Coastguard Worker       vtest_resource_busy_wait : vtest_resource_busy_wait_nop;
98*bbecb9d1SAndroid Build Coastguard Worker 
99*bbecb9d1SAndroid Build Coastguard Worker    do {
100*bbecb9d1SAndroid Build Coastguard Worker       ret = input->read(input, &header, sizeof(header));
101*bbecb9d1SAndroid Build Coastguard Worker       if (ret < 0 || (size_t)ret < sizeof(header)) {
102*bbecb9d1SAndroid Build Coastguard Worker          break;
103*bbecb9d1SAndroid Build Coastguard Worker       }
104*bbecb9d1SAndroid Build Coastguard Worker 
105*bbecb9d1SAndroid Build Coastguard Worker       if (!context) {
106*bbecb9d1SAndroid Build Coastguard Worker          /* The first command MUST be VCMD_CREATE_RENDERER */
107*bbecb9d1SAndroid Build Coastguard Worker          if (header[1] != VCMD_CREATE_RENDERER) {
108*bbecb9d1SAndroid Build Coastguard Worker             break;
109*bbecb9d1SAndroid Build Coastguard Worker          }
110*bbecb9d1SAndroid Build Coastguard Worker 
111*bbecb9d1SAndroid Build Coastguard Worker          ret = vtest_init_renderer(false, ctx_flags, NULL);
112*bbecb9d1SAndroid Build Coastguard Worker          if (ret >= 0) {
113*bbecb9d1SAndroid Build Coastguard Worker             ret = vtest_create_context(input, out_fd, header[0], &context);
114*bbecb9d1SAndroid Build Coastguard Worker          }
115*bbecb9d1SAndroid Build Coastguard Worker          if (ret >= 0) {
116*bbecb9d1SAndroid Build Coastguard Worker             ret = vtest_lazy_init_context(context);
117*bbecb9d1SAndroid Build Coastguard Worker          }
118*bbecb9d1SAndroid Build Coastguard Worker          if (ret < 0) {
119*bbecb9d1SAndroid Build Coastguard Worker             break;
120*bbecb9d1SAndroid Build Coastguard Worker          }
121*bbecb9d1SAndroid Build Coastguard Worker          vtest_set_current_context(context);
122*bbecb9d1SAndroid Build Coastguard Worker          vtest_poll_resource_busy_wait();
123*bbecb9d1SAndroid Build Coastguard Worker          continue;
124*bbecb9d1SAndroid Build Coastguard Worker       }
125*bbecb9d1SAndroid Build Coastguard Worker 
126*bbecb9d1SAndroid Build Coastguard Worker       vtest_poll_resource_busy_wait();
127*bbecb9d1SAndroid Build Coastguard Worker       if (header[1] <= 0 || header[1] >= ARRAY_SIZE(vtest_commands)) {
128*bbecb9d1SAndroid Build Coastguard Worker          break;
129*bbecb9d1SAndroid Build Coastguard Worker       }
130*bbecb9d1SAndroid Build Coastguard Worker 
131*bbecb9d1SAndroid Build Coastguard Worker       if (vtest_commands[header[1]] == NULL) {
132*bbecb9d1SAndroid Build Coastguard Worker          break;
133*bbecb9d1SAndroid Build Coastguard Worker       }
134*bbecb9d1SAndroid Build Coastguard Worker 
135*bbecb9d1SAndroid Build Coastguard Worker       ret = vtest_commands[header[1]](header[0]);
136*bbecb9d1SAndroid Build Coastguard Worker       if (ret < 0) {
137*bbecb9d1SAndroid Build Coastguard Worker          break;
138*bbecb9d1SAndroid Build Coastguard Worker       }
139*bbecb9d1SAndroid Build Coastguard Worker    } while (1);
140*bbecb9d1SAndroid Build Coastguard Worker 
141*bbecb9d1SAndroid Build Coastguard Worker    if (context) {
142*bbecb9d1SAndroid Build Coastguard Worker       vtest_destroy_context(context);
143*bbecb9d1SAndroid Build Coastguard Worker    }
144*bbecb9d1SAndroid Build Coastguard Worker    vtest_cleanup_renderer();
145*bbecb9d1SAndroid Build Coastguard Worker }
146*bbecb9d1SAndroid Build Coastguard Worker 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)147*bbecb9d1SAndroid Build Coastguard Worker int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
148*bbecb9d1SAndroid Build Coastguard Worker {
149*bbecb9d1SAndroid Build Coastguard Worker    /* Limit unbounded allocations under fuzzer default limits. */
150*bbecb9d1SAndroid Build Coastguard Worker    vtest_set_max_length(256 * 1024 * 1024);
151*bbecb9d1SAndroid Build Coastguard Worker 
152*bbecb9d1SAndroid Build Coastguard Worker    int out_fd = open("/dev/null", O_WRONLY);
153*bbecb9d1SAndroid Build Coastguard Worker 
154*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_buffer buffer;
155*bbecb9d1SAndroid Build Coastguard Worker    buffer.buffer = (char *)data;
156*bbecb9d1SAndroid Build Coastguard Worker    buffer.size = size;
157*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_input input;
158*bbecb9d1SAndroid Build Coastguard Worker    input.data.buffer = &buffer;
159*bbecb9d1SAndroid Build Coastguard Worker    input.read = vtest_buf_read;
160*bbecb9d1SAndroid Build Coastguard Worker 
161*bbecb9d1SAndroid Build Coastguard Worker    vtest_fuzzer_run_renderer(out_fd, &input,
162*bbecb9d1SAndroid Build Coastguard Worker                              VIRGL_RENDERER_USE_EGL |
163*bbecb9d1SAndroid Build Coastguard Worker                              VIRGL_RENDERER_USE_SURFACELESS |
164*bbecb9d1SAndroid Build Coastguard Worker                              (getenv("VTEST_FUZZER_USE_GL") != NULL ?
165*bbecb9d1SAndroid Build Coastguard Worker                               0 : VIRGL_RENDERER_USE_GLES),
166*bbecb9d1SAndroid Build Coastguard Worker                              getenv("VTEST_FUZZER_FENCES") != NULL);
167*bbecb9d1SAndroid Build Coastguard Worker 
168*bbecb9d1SAndroid Build Coastguard Worker    close(out_fd);
169*bbecb9d1SAndroid Build Coastguard Worker 
170*bbecb9d1SAndroid Build Coastguard Worker    return 0;
171*bbecb9d1SAndroid Build Coastguard Worker }
172