1 /*
2 * Copyright (c) 2024 The Khronos Group Inc.
3 * Copyright (c) 2024 Valve Corporation
4 * Copyright (c) 2024 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials are
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice(s) and this permission notice shall be included in
14 * all copies or substantial portions of the Materials.
15 *
16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 *
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23 * USE OR OTHER DEALINGS IN THE MATERIALS.
24 *
25 * Author: Charles Giessen <charles@lunarg.com>
26 */
27
28 #include "test_environment.h"
29
30 extern "C" {
31 #include "loader.h"
32 #include "loader_json.h"
33 #include "settings.h"
34 }
35
execute_instance_enumerate_fuzzer(std::filesystem::path const & filename)36 void execute_instance_enumerate_fuzzer(std::filesystem::path const& filename) {
37 FrameworkEnvironment env{};
38 env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
39 ManifestCategory::implicit_layer, ManifestLocation::implicit_layer, "complex_layer.json");
40 env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
41 ManifestCategory::settings, ManifestLocation::settings_location, "vk_loader_settings.json");
42
43 uint32_t pPropertyCount;
44 VkExtensionProperties pProperties = {0};
45
46 env.vulkan_functions.vkEnumerateInstanceExtensionProperties("test_auto", &pPropertyCount, &pProperties);
47 }
execute_instance_create_fuzzer(std::filesystem::path const & filename)48 void execute_instance_create_fuzzer(std::filesystem::path const& filename) {
49 FrameworkEnvironment env{};
50 env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
51 ManifestCategory::implicit_layer, ManifestLocation::implicit_layer, "complex_layer.json");
52 env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
53 ManifestCategory::settings, ManifestLocation::settings_location, "vk_loader_settings.json");
54 env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
55 ManifestCategory::icd, ManifestLocation::driver, "icd_test.json");
56 VkInstance inst = {0};
57 const char* instance_layers[] = {"VK_LAYER_KHRONOS_validation", "VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"};
58 VkApplicationInfo app{};
59 app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
60 app.pNext = NULL;
61 app.pApplicationName = "TEST_APP";
62 app.applicationVersion = 0;
63 app.pEngineName = "TEST_ENGINE";
64 app.engineVersion = 0;
65 app.apiVersion = VK_API_VERSION_1_0;
66
67 VkInstanceCreateInfo inst_info{};
68 inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
69 inst_info.pNext = NULL;
70 inst_info.pApplicationInfo = &app;
71 inst_info.enabledLayerCount = 1;
72 inst_info.ppEnabledLayerNames = (const char* const*)instance_layers;
73 inst_info.enabledExtensionCount = 0;
74 inst_info.ppEnabledExtensionNames = NULL;
75
76 VkResult err = env.vulkan_functions.vkCreateInstance(&inst_info, NULL, &inst);
77 if (err != VK_SUCCESS) {
78 return;
79 }
80
81 env.vulkan_functions.vkDestroyInstance(inst, NULL);
82 }
83
execute_json_load_fuzzer(std::string const & filename)84 void execute_json_load_fuzzer(std::string const& filename) {
85 FrameworkEnvironment env{};
86
87 cJSON* json = NULL;
88 loader_get_json(NULL, filename.c_str(), &json);
89
90 if (json == NULL) {
91 return;
92 }
93 bool out_of_mem = false;
94 char* json_data = loader_cJSON_Print(json, &out_of_mem);
95
96 if (json_data != NULL) {
97 free(json_data);
98 }
99
100 if (json != NULL) {
101 loader_cJSON_Delete(json);
102 }
103 }
execute_setting_fuzzer(std::filesystem::path const & filename)104 void execute_setting_fuzzer(std::filesystem::path const& filename) {
105 FrameworkEnvironment env{};
106
107 env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
108 ManifestCategory::settings, ManifestLocation::settings_location, "vk_loader_settings.json");
109
110 update_global_loader_settings();
111 struct loader_layer_list settings_layers = {0};
112 bool should_search_for_other_layers = true;
113 get_settings_layers(NULL, &settings_layers, &should_search_for_other_layers);
114 loader_delete_layer_list_and_properties(NULL, &settings_layers);
115 }
116
TEST(BadJsonInput,ClusterFuzzTestCase_5599244505186304)117 TEST(BadJsonInput, ClusterFuzzTestCase_5599244505186304) {
118 // Doesn't crash with ASAN or UBSAN
119 // Doesn't reproducibly crash - instance_create_fuzzer: Abrt in loader_cJSON_Delete
120 execute_instance_create_fuzzer("clusterfuzz-testcase-instance_create_fuzzer-5599244505186304");
121 }
TEST(BadJsonInput,ClusterFuzzTestCase_5126563864051712)122 TEST(BadJsonInput, ClusterFuzzTestCase_5126563864051712) {
123 // Doesn't crash with ASAN or UBSAN
124 // Doesn't reproducibly crash - instance_enumerate_fuzzer: Abrt in loader_cJSON_Delete
125 execute_instance_enumerate_fuzzer("clusterfuzz-testcase-instance_enumerate_fuzzer-5126563864051712");
126 }
TEST(BadJsonInput,ClusterFuzzTestCase_6308459683315712)127 TEST(BadJsonInput, ClusterFuzzTestCase_6308459683315712) {
128 // Doesn't crash with ASAN or UBSAN
129 // Doesn't reproducibly crash - instance_enumerate_fuzzer: Null-dereference READ in
130 // combine_settings_layers_with_regular_layers
131 execute_instance_enumerate_fuzzer("clusterfuzz-testcase-instance_enumerate_fuzzer-6308459683315712");
132 }
TEST(BadJsonInput,ClusterFuzzTestCase_6583684169269248)133 TEST(BadJsonInput, ClusterFuzzTestCase_6583684169269248) {
134 // Crashes ASAN
135 // Nullptr dereference in loader_copy_to_new_str
136 execute_instance_enumerate_fuzzer("clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6583684169269248");
137 }
138
TEST(BadJsonInput,ClusterFuzzTestCase_5258042868105216)139 TEST(BadJsonInput, ClusterFuzzTestCase_5258042868105216) {
140 // Doesn't crash with ASAN or UBSAN
141 // Doesn't reproducibly crash - json_load_fuzzer: Abrt in loader_cJSON_Delete
142 execute_json_load_fuzzer("clusterfuzz-testcase-json_load_fuzzer-5258042868105216");
143 }
TEST(BadJsonInput,ClusterFuzzTestCase_5487817455960064)144 TEST(BadJsonInput, ClusterFuzzTestCase_5487817455960064) {
145 // Doesn't crash with ASAN or UBSAN
146 // Doesn't reproducibly crash - json_load_fuzzer: Abrt in std::__Fuzzer::vector<std::__Fuzzer::pair<unsigned int, unsigned
147 // short>, std::__
148 execute_json_load_fuzzer("clusterfuzz-testcase-json_load_fuzzer-5487817455960064");
149 }
TEST(BadJsonInput,ClusterFuzzTestCase_4558978302214144)150 TEST(BadJsonInput, ClusterFuzzTestCase_4558978302214144) {
151 // Does crash with UBSAN and ASAN
152 // loader.c:287: VkResult loader_copy_to_new_str(const struct loader_instance *, const char *, char **): Assertion
153 // `source_str
154 // && dest_str' failed.
155 // instance_create_fuzzer: Null-dereference READ in loader_copy_to_new_str
156 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-4558978302214144");
157 }
TEST(BadJsonInput,ClusterFuzzTestCase_4568454561071104)158 TEST(BadJsonInput, ClusterFuzzTestCase_4568454561071104) {
159 // Does crash with UBSAN and ASAN
160 // Causes hangs - instance_create_fuzzer: Timeout in instance_create_fuzzer
161 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-4568454561071104");
162 }
TEST(BadJsonInput,ClusterFuzzTestCase_4820577276723200)163 TEST(BadJsonInput, ClusterFuzzTestCase_4820577276723200) {
164 // Does crash with UBSAN and ASAN
165 // instance_create_fuzzer: Crash in printf_common
166 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-4820577276723200");
167 }
TEST(BadJsonInput,ClusterFuzzTestCase_5177827962454016)168 TEST(BadJsonInput, ClusterFuzzTestCase_5177827962454016) {
169 // Does crash with UBSAN and ASAN
170 // free(): invalid next size (fast)
171 // instance_create_fuzzer: Abrt in instance_create_fuzzer
172 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-5177827962454016");
173 }
TEST(BadJsonInput,ClusterFuzzTestCase_5198773675425792)174 TEST(BadJsonInput, ClusterFuzzTestCase_5198773675425792) {
175 // Does crash with UBSAN and ASAN
176 // stack-overflow
177 // instance_create_fuzzer: Stack-overflow with empty stacktrace
178 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-5198773675425792");
179 }
TEST(BadJsonInput,ClusterFuzzTestCase_5416197367070720)180 TEST(BadJsonInput, ClusterFuzzTestCase_5416197367070720) {
181 // Does crash with UBSAN and ASAN
182 // free(): invalid next size (fast)
183 // instance_create_fuzzer: Overwrites-const-input in instance_create_fuzzer
184 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-5416197367070720");
185 }
TEST(BadJsonInput,ClusterFuzzTestCase_5494771615137792)186 TEST(BadJsonInput, ClusterFuzzTestCase_5494771615137792) {
187 // Does crash with UBSAN and ASAN
188 // stack-overflow
189 // instance_create_fuzzer: Stack-overflow in verify_meta_layer_component_layers
190 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-5494771615137792");
191 }
TEST(BadJsonInput,ClusterFuzzTestCase_5801855065915392)192 TEST(BadJsonInput, ClusterFuzzTestCase_5801855065915392) {
193 // Does crash with ASAN
194 // Doesn't crash with UBSAN
195 // Causes a leak - instance_create_fuzzer: Direct-leak in print_string_ptr
196 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-5801855065915392");
197 }
TEST(BadJsonInput,ClusterFuzzTestCase_6353004288081920)198 TEST(BadJsonInput, ClusterFuzzTestCase_6353004288081920) {
199 // Does crash with ASAN and UBSAN
200 // Stack overflow due to recursive meta layers
201 execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-6353004288081920");
202 }
TEST(BadJsonInput,ClusterFuzzTestCase_5817896795701248)203 TEST(BadJsonInput, ClusterFuzzTestCase_5817896795701248) {
204 execute_instance_create_fuzzer("clusterfuzz-testcase-instance_create_fuzzer-5817896795701248");
205 }
TEST(BadJsonInput,ClusterFuzzTestCase_6541440380895232)206 TEST(BadJsonInput, ClusterFuzzTestCase_6541440380895232) {
207 execute_instance_create_fuzzer("clusterfuzz-testcase-instance_create_fuzzer-6541440380895232");
208 }
TEST(BadJsonInput,ClusterFuzzTestCase_6465902356791296)209 TEST(BadJsonInput, ClusterFuzzTestCase_6465902356791296) {
210 // Does crash with UBSAN
211 // Doesn't crash with ASAN
212 // Causes an integer overflow - instance_enumerate_fuzzer: Integer-overflow in parse_value
213 execute_instance_enumerate_fuzzer("clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6465902356791296");
214 }
TEST(BadJsonInput,ClusterFuzzTestCase_4512865114259456)215 TEST(BadJsonInput, ClusterFuzzTestCase_4512865114259456) {
216 // Does crash with UBSAN and ASAN
217 // malloc(): invalid size (unsorted)
218 // json_load_fuzzer: Heap-buffer-overflow in parse_string
219 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-4512865114259456");
220 }
TEST(BadJsonInput,ClusterFuzzTestCase_4552015310880768)221 TEST(BadJsonInput, ClusterFuzzTestCase_4552015310880768) {
222 // Does crash with UBSAN
223 // Doesn't crash with ASAN
224 // Causes an integer overflow
225 // json_load_fuzzer: Integer-overflow in parse_value
226 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-4552015310880768");
227 }
TEST(BadJsonInput,ClusterFuzzTestCase_5208693600747520)228 TEST(BadJsonInput, ClusterFuzzTestCase_5208693600747520) {
229 // Does crash with UBSAN and ASAN
230 // Stack overflow
231 // json_load_fuzzer: Stack-overflow in print_value
232 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-5208693600747520");
233 }
TEST(BadJsonInput,ClusterFuzzTestCase_5347670374612992)234 TEST(BadJsonInput, ClusterFuzzTestCase_5347670374612992) {
235 // Doesn't crash with ASAN or UBSAN
236 // No reported leaks in head, crashes in 1.3.269 & 1.3.250
237 // Causes a leak - json_load_fuzzer: Direct-leak in parse_array
238 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-5347670374612992");
239 }
TEST(BadJsonInput,ClusterFuzzTestCase_5392928643547136)240 TEST(BadJsonInput, ClusterFuzzTestCase_5392928643547136) {
241 // Does crash with UBSAN and ASAN
242 // free(): corrupted unsorted chunks
243 // json_load_fuzzer: Abrt in std::__Fuzzer::basic_filebuf<char, std::__Fuzzer::char_traits<char>>::~basic_fil
244 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-5392928643547136");
245 }
TEST(BadJsonInput,ClusterFuzzTestCase_5636386303049728)246 TEST(BadJsonInput, ClusterFuzzTestCase_5636386303049728) {
247 // Does crash with UBSAN and ASAN
248 // terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
249 // json_load_fuzzer: Abrt in json_load_fuzzer
250 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-5636386303049728");
251 }
TEST(BadJsonInput,ClusterFuzzTestCase_6182254813249536)252 TEST(BadJsonInput, ClusterFuzzTestCase_6182254813249536) {
253 // Doesn't crash with ASAN or UBSAN
254 // No leaks reported in main, 1.3.269, nor 1.3.250
255 // Causes a leak - json_load_fuzzer: Indirect-leak in parse_object
256 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-6182254813249536");
257 }
TEST(BadJsonInput,ClusterFuzzTestCase_6265355951996928)258 TEST(BadJsonInput, ClusterFuzzTestCase_6265355951996928) {
259 // Does crash with UBSAN and ASAN
260 // json_load_fuzzer: Null-dereference READ in json_load_fuzzer
261 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-6265355951996928");
262 }
TEST(BadJsonInput,ClusterFuzzTestCase_6363106126659584)263 TEST(BadJsonInput, ClusterFuzzTestCase_6363106126659584) {
264 // Does crash with UBSAN and ASAN
265 // json_load_fuzzer: Overwrites-const-input in json_load_fuzzer
266 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-6363106126659584");
267 }
TEST(BadJsonInput,ClusterFuzzTestCase_6482033715838976)268 TEST(BadJsonInput, ClusterFuzzTestCase_6482033715838976) {
269 // Does crash with UBSAN and ASAN
270 // json_load_fuzzer: Stack-overflow in parse_array
271 execute_json_load_fuzzer("clusterfuzz-testcase-minimized-json_load_fuzzer-6482033715838976");
272 }
TEST(BadJsonInput,ClusterFuzzTestCase_4857714377818112)273 TEST(BadJsonInput, ClusterFuzzTestCase_4857714377818112) {
274 // Does crash with UBSAN and ASAN
275 // settings_fuzzer: Abrt in settings_fuzzer
276 execute_setting_fuzzer("clusterfuzz-testcase-minimized-settings_fuzzer-4857714377818112");
277 }
TEST(BadJsonInput,ClusterFuzzTestCase_5123849246867456)278 TEST(BadJsonInput, ClusterFuzzTestCase_5123849246867456) {
279 // Doesn't crash with ASAN or UBSAN
280 // No leaks reported in main, 1.3.269, nor 1.3.250
281 // Causes a leak - settings_fuzzer: Direct-leak in loader_append_layer_property
282 execute_setting_fuzzer("clusterfuzz-testcase-minimized-settings_fuzzer-5123849246867456");
283 }
284