Skip to content

Commit 3414ed7

Browse files
authored
vulkan-loader: add new fuzzers for settings enumeration of extensions and creation of instance (#11153)
This commit provide new fuzzers and updates seed corpuses for Vulkan-Loader project: - settings fuzzer - extension enumeration fuzzer - instance creation fuzzer
1 parent 876d043 commit 3414ed7

File tree

6 files changed

+309
-7
lines changed

6 files changed

+309
-7
lines changed

projects/vulkan-loader/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ RUN apt-get update && \
2929
# Vulkan-Loader depends on the header file in Vulkan-Headers
3030
RUN git clone https://github.com/khronosgroup/Vulkan-Headers vulkan-headers
3131
RUN git clone https://github.com/khronosgroup/Vulkan-Loader vulkan-loader
32-
COPY *_fuzzer.c *.sh $SRC/
32+
COPY fuzzers/*_fuzzer.c *.sh $SRC/
3333
WORKDIR $SRC/vulkan-loader

projects/vulkan-loader/build.sh

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@ make -j4
2323

2424
ar rcs $OUT/libvulkan.a $SRC/vulkan-loader/build/loader/CMakeFiles/vulkan.dir/*.o
2525

26-
$CC $CXXFLAGS -I$SRC/vulkan-loader/loader \
27-
-I$SRC/vulkan-loader/loader/generated \
28-
-I$SRC/vulkan-headers/include \
29-
-c $SRC/json_load_fuzzer.c -o json_load_fuzzer.o
26+
for fuzzers in $(find $SRC -name '*_fuzzer.c'); do
27+
fuzz_basename=$(basename -s .c $fuzzers)
28+
$CC $CXXFLAGS -I$SRC/vulkan-loader/loader \
29+
-I$SRC/vulkan-loader/loader/generated \
30+
-I$SRC/vulkan-headers/include \
31+
-c $fuzzers -o $fuzz_basename.o
3032

31-
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE json_load_fuzzer.o \
32-
-o $OUT/json_load_fuzzer -lpthread $OUT/libvulkan.a
33+
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzz_basename.o \
34+
-o $OUT/$fuzz_basename -lpthread $OUT/libvulkan.a
3335

36+
zip -q $OUT/${fuzz_basename}_seed_corpus.zip $SRC/vulkan-loader/tests/corpus/*
37+
done
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include <stdint.h>
14+
#include <stdio.h>
15+
#include <stdlib.h>
16+
17+
#include "cJSON.h"
18+
#include "loader.h"
19+
20+
/*
21+
* Create config files for given path and data.
22+
*/
23+
int create_config_file(const char* config_path, const char* config_filename, const uint8_t* data, size_t size) {
24+
char filename[512];
25+
char path[256];
26+
char command[256];
27+
28+
sprintf(path, "%s/%s", getenv("HOME"), config_path);
29+
sprintf(command, "mkdir -p %s", path);
30+
31+
system(command);
32+
33+
sprintf(filename, "%s/%s", path, config_filename);
34+
35+
FILE *fp = fopen(filename, "wb");
36+
if (!fp) {
37+
return 1;
38+
}
39+
fwrite(data, size, 1, fp);
40+
fclose(fp);
41+
42+
return 0;
43+
}
44+
45+
/*
46+
* Remove config file
47+
*/
48+
void remove_config_file(const char* config_path, const char* config_filename) {
49+
char filename[512];
50+
sprintf(filename, "%s/%s/%s", getenv("HOME"), config_path, config_filename);
51+
unlink(filename);
52+
}
53+
54+
/*
55+
* Targets the instance creation.
56+
*/
57+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
58+
setenv("HOME", "/tmp", 1);
59+
60+
// Create implicit layer configuration file
61+
int result = create_config_file(".local/share/vulkan/implicit_layer.d", "complex_layer.json", data, size);
62+
if (result) {
63+
return 0;
64+
}
65+
66+
// Create loader configuration file
67+
result = create_config_file(".local/share/vulkan/loader_settings.d", "vk_loader_settings.json", data, size);
68+
if (result) {
69+
return 0;
70+
}
71+
72+
// Create icd configuration file
73+
result = create_config_file(".local/share/vulkan/icd.d", "icd_test.json", data, size);
74+
if (result) {
75+
return 0;
76+
}
77+
78+
setenv("VK_LOADER_LAYERS_ENABLE", "all", 1);
79+
80+
81+
VkInstance inst = {0};
82+
char *instance_layers[] = {
83+
"VK_LAYER_KHRONOS_validation",
84+
"VK_LAYER_test_layer_1",
85+
"VK_LAYER_test_layer_2"
86+
};
87+
const VkApplicationInfo app = {
88+
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
89+
.pNext = NULL,
90+
.pApplicationName = "TEST_APP",
91+
.applicationVersion = 0,
92+
.pEngineName = "TEST_ENGINE",
93+
.engineVersion = 0,
94+
.apiVersion = VK_API_VERSION_1_0,
95+
};
96+
VkInstanceCreateInfo inst_info = {
97+
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
98+
.pNext = NULL,
99+
.pApplicationInfo = &app,
100+
.enabledLayerCount = 1,
101+
.ppEnabledLayerNames = (const char *const *)instance_layers,
102+
.enabledExtensionCount = 0,
103+
.ppEnabledExtensionNames = NULL,
104+
};
105+
VkResult err = vkCreateInstance(&inst_info, NULL, &inst);
106+
if (err != VK_SUCCESS) {
107+
goto out;
108+
}
109+
110+
vkDestroyInstance(inst, NULL);
111+
112+
out:
113+
// Clean up config files
114+
remove_config_file(".local/share/vulkan/implicit_layer.d", "complex_layer.json");
115+
remove_config_file(".local/share/vulkan/loader_settings.d", "vk_loader_settings.json");
116+
remove_config_file(".local/share/vulkan/icd.d", "icd_test.json");
117+
118+
return 0;
119+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include <stdint.h>
14+
#include <stdio.h>
15+
#include <stdlib.h>
16+
17+
#include "cJSON.h"
18+
#include "loader.h"
19+
20+
/*
21+
* Create config files for given path and data.
22+
*/
23+
int create_config_file(const char* config_path, const char* config_filename, const uint8_t* data, size_t size) {
24+
char filename[512];
25+
char path[256];
26+
char command[256];
27+
28+
sprintf(path, "%s/%s", getenv("HOME"), config_path);
29+
sprintf(command, "mkdir -p %s", path);
30+
31+
system(command);
32+
33+
sprintf(filename, "%s/%s", path, config_filename);
34+
35+
FILE *fp = fopen(filename, "wb");
36+
if (!fp) {
37+
return 1;
38+
}
39+
fwrite(data, size, 1, fp);
40+
fclose(fp);
41+
42+
return 0;
43+
}
44+
45+
/*
46+
* Remove config file
47+
*/
48+
void remove_config_file(const char* config_path, const char* config_filename) {
49+
char filename[512];
50+
sprintf(filename, "%s/%s/%s", getenv("HOME"), config_path, config_filename);
51+
unlink(filename);
52+
}
53+
54+
/*
55+
* Targets the instance extension enumeration.
56+
*/
57+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
58+
setenv("HOME", "/tmp", 1);
59+
60+
// Create implicit layer configuration file
61+
int result = create_config_file(".local/share/vulkan/implicit_layer.d", "complex_layer.json", data, size);
62+
if (result) {
63+
return 0;
64+
}
65+
66+
// Create loader configuration file
67+
result = create_config_file(".local/share/vulkan/loader_settings.d", "vk_loader_settings.json", data, size);
68+
if (result) {
69+
return 0;
70+
}
71+
72+
setenv("VK_LOADER_LAYERS_ENABLE", "all", 1);
73+
74+
uint32_t pPropertyCount;
75+
VkExtensionProperties pProperties = {0};
76+
77+
vkEnumerateInstanceExtensionProperties("test_auto", &pPropertyCount, &pProperties);
78+
79+
// Clean up config files
80+
remove_config_file(".local/share/vulkan/implicit_layer.d", "complex_layer.json");
81+
remove_config_file(".local/share/vulkan/loader_settings.d", "vk_loader_settings.json");
82+
83+
return 0;
84+
}

projects/vulkan-loader/json_load_fuzzer.c renamed to projects/vulkan-loader/fuzzers/json_load_fuzzer.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,22 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
3333

3434
cJSON *json = NULL;
3535
loader_get_json(NULL, filename, &json);
36+
37+
if (json == NULL) {
38+
goto out;
39+
}
40+
41+
char *json_data = loader_cJSON_Print(json);
42+
43+
if (json_data != NULL) {
44+
free(json_data);
45+
}
46+
3647
if (json != NULL) {
3748
free(json);
3849
}
50+
51+
out:
3952
unlink(filename);
4053

4154
return 0;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include <stdint.h>
14+
#include <stdio.h>
15+
#include <stdlib.h>
16+
17+
#include "cJSON.h"
18+
#include "loader.h"
19+
20+
/*
21+
* Create config files for given path and data.
22+
*/
23+
int create_config_file(const char* config_path, const char* config_filename, const uint8_t* data, size_t size) {
24+
char filename[512];
25+
char path[256];
26+
char command[256];
27+
28+
sprintf(path, "%s/%s", getenv("HOME"), config_path);
29+
sprintf(command, "mkdir -p %s", path);
30+
31+
system(command);
32+
33+
sprintf(filename, "%s/%s", path, config_filename);
34+
35+
FILE *fp = fopen(filename, "wb");
36+
if (!fp) {
37+
return 1;
38+
}
39+
fwrite(data, size, 1, fp);
40+
fclose(fp);
41+
42+
return 0;
43+
}
44+
45+
/*
46+
* Remove config file
47+
*/
48+
void remove_config_file(const char* config_path, const char* config_filename) {
49+
char filename[512];
50+
sprintf(filename, "%s/%s/%s", getenv("HOME"), config_path, config_filename);
51+
unlink(filename);
52+
}
53+
54+
/*
55+
* Targets the settings parser.
56+
*/
57+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
58+
setenv("HOME", "/tmp", 1);
59+
60+
// Create loader configuration file
61+
int result = create_config_file(".local/share/vulkan/loader_settings.d", "vk_loader_settings.json", data, size);
62+
if (result) {
63+
return 0;
64+
}
65+
66+
update_global_loader_settings();
67+
update_global_loader_settings();
68+
get_current_settings_and_lock(NULL);
69+
release_current_settings_lock(NULL);
70+
struct loader_layer_list settings_layers = {0};
71+
72+
bool should_search_for_other_layers = true;
73+
get_settings_layers(NULL, &settings_layers, &should_search_for_other_layers);
74+
should_skip_logging_global_messages(0);
75+
update_global_loader_settings();
76+
teardown_global_loader_settings();
77+
78+
// Clean up config file
79+
remove_config_file(".local/share/vulkan/loader_settings.d", "vk_loader_settings.json");
80+
81+
return 0;
82+
}

0 commit comments

Comments
 (0)