Coverage Report

Created: 2025-08-10 07:03

/src/instance_create_advanced_fuzzer.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright 2025 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
#include "fuzz_header.h"
21
22
6
int LLVMFuzzerInitialize(int *argc, char ***argv) {
23
6
  setenv("HOME", "/tmp", 1);
24
6
  system("mkdir -p $HOME/.local/share/vulkan/implicit_layer.d");
25
6
  system("mkdir -p $HOME/.local/share/vulkan/loader_settings.d");
26
6
  system("mkdir -p $HOME/.local/share/vulkan/icd.d");
27
6
  return 0;
28
6
}
29
30
/*
31
 * Create config files for given path and data.
32
 */
33
7.75k
int create_config_file(const char* config_path, const char* config_filename, const uint8_t* data, size_t size) {
34
7.75k
  char filename[512];
35
7.75k
  char path[256];
36
  // char command[256];
37
38
7.75k
  sprintf(path, "%s/%s", getenv("HOME"), config_path);
39
  //sprintf(command, "mkdir -p %s", path);
40
41
  //system(command);
42
43
7.75k
  sprintf(filename, "%s/%s", path, config_filename);
44
45
7.75k
  FILE *fp = fopen(filename, "wb");
46
7.75k
  if (!fp) {
47
0
    return 1;
48
0
  }
49
7.75k
  fwrite(data, size, 1, fp);
50
7.75k
  fclose(fp);
51
52
7.75k
  return 0;
53
7.75k
}
54
55
/*
56
 * Remove config file
57
 */
58
7.75k
void remove_config_file(const char* config_path, const char* config_filename) {
59
7.75k
  char filename[512];
60
7.75k
  sprintf(filename, "%s/%s/%s", getenv("HOME"), config_path, config_filename);
61
7.75k
  unlink(filename);
62
7.75k
}
63
64
/*
65
 * Targets the instance creation.
66
 */
67
134
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
68
134
  if (size < 3*sizeof(size_t)) {
69
0
    return 0;
70
0
  }
71
72
  // Split the loaders into two different parts so the files
73
  // are independently seeded with fuzz data.
74
134
  size_t first_size = (*(size_t*)data) % 40000;
75
134
  size_t second_size = (*(size_t*)(data + sizeof(size_t))) % 40000;
76
134
  size_t third_size = (*(size_t*)(data + 2*sizeof(size_t))) % 40000;
77
78
134
  data += 3*sizeof(size_t); // Move past the first two integers
79
134
  size -= 3*sizeof(size_t); // Adjust size to account for the first two integers
80
134
  size_t total_size_needed = first_size + second_size + third_size;
81
134
  if (size <= total_size_needed) {
82
0
    return 0;
83
0
  }
84
134
  int result = create_config_file(".local/share/vulkan/implicit_layer.d", "complex_layer.json", data, first_size);
85
134
  if (result) {
86
0
    return 0;
87
0
  }
88
89
134
  data += first_size;
90
134
  size -= first_size;
91
134
  result = create_config_file(".local/share/vulkan/loader_settings.d", "vk_loader_settings.json", data, second_size);
92
134
  if (result) {
93
0
    return 0;
94
0
  }
95
96
134
  data += second_size;
97
134
  size -= second_size;
98
134
  result = create_config_file(".local/share/vulkan/loader_settings.d", "icd_test.json", data, third_size);
99
134
  if (result) {
100
0
    return 0;
101
0
  }
102
134
  data += third_size;
103
134
  size -= third_size;
104
105
134
  fuzz_init(data, size);
106
107
134
  setenv("VK_LOADER_LAYERS_ENABLE", "all", 1);
108
109
110
134
  VkInstance inst = {0};
111
134
  char *instance_layers[] = {
112
134
    "VK_LAYER_KHRONOS_validation",
113
134
    "VK_LAYER_test_layer_1",
114
134
    "VK_LAYER_test_layer_2"
115
134
  };
116
134
  const VkApplicationInfo app = {
117
134
      .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
118
134
      .pNext = NULL,
119
134
      .pApplicationName = "TEST_APP",
120
134
      .applicationVersion = 0,
121
134
      .pEngineName = "TEST_ENGINE",
122
134
      .engineVersion = 0,
123
134
      .apiVersion = VK_API_VERSION_1_0,
124
134
  };
125
134
  VkInstanceCreateInfo inst_info = {
126
134
      .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
127
134
      .pNext = NULL,
128
134
      .pApplicationInfo = &app,
129
134
      .enabledLayerCount = 1,
130
134
      .ppEnabledLayerNames = (const char *const *)instance_layers,
131
134
      .enabledExtensionCount = 0,
132
134
      .ppEnabledExtensionNames = NULL,
133
134
  };
134
134
  VkResult err = vkCreateInstance(&inst_info, NULL, &inst);
135
134
  if (err != VK_SUCCESS) {
136
134
    goto out;
137
134
  }
138
0
  else {
139
140
0
  }
141
142
0
  vkDestroyInstance(inst, NULL);
143
144
134
out:
145
  // Clean up config files
146
134
  remove_config_file(".local/share/vulkan/implicit_layer.d", "complex_layer.json");
147
134
  remove_config_file(".local/share/vulkan/loader_settings.d", "vk_loader_settings.json");
148
134
  remove_config_file(".local/share/vulkan/icd.d", "icd_test.json");
149
150
151
134
  fuzz_cleanup();
152
153
134
  return 0;
154
0
}