Coverage Report

Created: 2025-07-11 06:49

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