Add Dawn Wire Server LPM Fuzzer [1/N]
Add scaffolding for structured Dawn wire fuzzer. This CL contains a basic fuzzer for Dawn wire server that shows some simple design ideas: 1) A basic protobuf spec that is generated using dawn.json 2) conversion from protobuf message to a dawn wire server command. This is not the complete implementation and serves as a foundation for the fuzzer so that subsequent CLs will be easier to review. Bug: chromium:1374747 Change-Id: Ife1642dda13d01d3308bdd5fe56cf85978399fd3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/109406 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Brendon Tiszka <tiszka@chromium.org>
This commit is contained in:
parent
e4b4c4737e
commit
d0b284b00b
|
@ -111,3 +111,12 @@ The schema of `dawn_wire.json` is a dictionary with the following keys:
|
|||
## OpenGL loader generator
|
||||
|
||||
The code to load OpenGL entrypoints from a `GetProcAddress` function is generated from [`gl.xml`](../third_party/khronos/gl.xml) and the [list of extensions](../src/dawn/native/opengl/supported_extensions.json) it supports.
|
||||
|
||||
|
||||
## Dawn lpmfuzz generator
|
||||
One of Dawn's Fuzzers utilizes the information in [`dawn.json`, `dawn_wire.json`, `dawn_lpm.json`] to generate the `.proto` and `.cpp` files required for a [libprotobuf-mutator fuzzer](https://github.com/google/libprotobuf-mutator) that fuzzes Dawn Wire Server's stack with more effectiveness in some areas than plain libfuzzer.
|
||||
|
||||
At this time it is used to generate:
|
||||
|
||||
- the `dawn_lpm.proto` file used to describe the grammar for the fuzzer
|
||||
- the serializer `DawnLPMSerializer.cpp` that takes an arbitrary number of protobuf structures that were defined in `dawn_lpm.proto` and serializes them to be passed to `DawnWireServer::HandleCommands`.
|
||||
|
|
|
@ -80,3 +80,25 @@ template("dawn_json_generator") {
|
|||
forward_variables_from(invoker, "*", [ "target" ])
|
||||
}
|
||||
}
|
||||
|
||||
template("dawn_json_lpm_generator") {
|
||||
dawn_generator(target_name) {
|
||||
script = "${dawn_root}/generator/dawn_json_generator.py"
|
||||
|
||||
# The base arguments for the generator: from this dawn.json, generate this
|
||||
# target using templates in this directory.
|
||||
args = [
|
||||
"--dawn-json",
|
||||
rebase_path("${dawn_root}/dawn.json", root_build_dir),
|
||||
"--wire-json",
|
||||
rebase_path("${dawn_root}/dawn_wire.json", root_build_dir),
|
||||
"--lpm-json",
|
||||
rebase_path("${dawn_root}/src/dawn/fuzzers/lpmfuzz/dawn_lpm.json",
|
||||
root_build_dir),
|
||||
"--targets",
|
||||
invoker.target,
|
||||
]
|
||||
|
||||
forward_variables_from(invoker, "*", [ "target" ])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -777,7 +777,7 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
def add_commandline_arguments(self, parser):
|
||||
allowed_targets = [
|
||||
'dawn_headers', 'cpp_headers', 'cpp', 'proc', 'mock_api', 'wire',
|
||||
'native_utils'
|
||||
'native_utils', 'dawn_lpmfuzz_cpp', 'dawn_lpmfuzz_proto'
|
||||
]
|
||||
|
||||
parser.add_argument('--dawn-json',
|
||||
|
@ -788,6 +788,10 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
default=None,
|
||||
type=str,
|
||||
help='The DAWN WIRE JSON definition to use.')
|
||||
parser.add_argument("--lpm-json",
|
||||
default=None,
|
||||
type=str,
|
||||
help='The DAWN LPM FUZZER definitions to use.')
|
||||
parser.add_argument(
|
||||
'--targets',
|
||||
required=True,
|
||||
|
@ -795,6 +799,7 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
help=
|
||||
'Comma-separated subset of targets to output. Available targets: '
|
||||
+ ', '.join(allowed_targets))
|
||||
|
||||
def get_file_renders(self, args):
|
||||
with open(args.dawn_json) as f:
|
||||
loaded_json = json.loads(f.read())
|
||||
|
@ -806,6 +811,11 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
with open(args.wire_json) as f:
|
||||
wire_json = json.loads(f.read())
|
||||
|
||||
lpm_json = None
|
||||
if args.lpm_json:
|
||||
with open(args.lpm_json) as f:
|
||||
lpm_json = json.loads(f.read())
|
||||
|
||||
renders = []
|
||||
|
||||
params_dawn = parse_json(loaded_json,
|
||||
|
@ -1025,12 +1035,53 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
'src/dawn/wire/server/ServerPrototypes_autogen.inc',
|
||||
wire_params))
|
||||
|
||||
if 'dawn_lpmfuzz_proto' in targets:
|
||||
params_dawn_wire = parse_json(loaded_json,
|
||||
enabled_tags=['dawn', 'deprecated'],
|
||||
disabled_tags=['native'])
|
||||
additional_params = compute_wire_params(params_dawn_wire,
|
||||
wire_json)
|
||||
|
||||
lpm_params = [
|
||||
RENDER_PARAMS_BASE, params_dawn_wire, {}, additional_params
|
||||
]
|
||||
|
||||
renders.append(
|
||||
FileRender('dawn/fuzzers/lpmfuzz/dawn_lpm.proto',
|
||||
'src/dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.proto',
|
||||
lpm_params))
|
||||
|
||||
if 'dawn_lpmfuzz_cpp' in targets:
|
||||
params_dawn_wire = parse_json(loaded_json,
|
||||
enabled_tags=['dawn', 'deprecated'],
|
||||
disabled_tags=['native'])
|
||||
additional_params = compute_wire_params(params_dawn_wire,
|
||||
wire_json)
|
||||
|
||||
lpm_params = [
|
||||
RENDER_PARAMS_BASE, params_dawn_wire, {}, additional_params
|
||||
]
|
||||
|
||||
renders.append(
|
||||
FileRender(
|
||||
'dawn/fuzzers/lpmfuzz/DawnLPMSerializer.cpp',
|
||||
'src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.cpp',
|
||||
lpm_params))
|
||||
|
||||
renders.append(
|
||||
FileRender(
|
||||
'dawn/fuzzers/lpmfuzz/DawnLPMSerializer.h',
|
||||
'src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h',
|
||||
lpm_params))
|
||||
|
||||
return renders
|
||||
|
||||
def get_dependencies(self, args):
|
||||
deps = [os.path.abspath(args.dawn_json)]
|
||||
if args.wire_json != None:
|
||||
deps += [os.path.abspath(args.wire_json)]
|
||||
if args.lpm_json != None:
|
||||
deps += [os.path.abspath(args.lpm_json)]
|
||||
return deps
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMFuzzer.h"
|
||||
#include "dawn/wire/Wire.h"
|
||||
#include "dawn/wire/WireClient.h"
|
||||
#include "dawn/wire/WireCmd_autogen.h"
|
||||
#include "dawn/wire/client/ApiObjects_autogen.h"
|
||||
#include "dawn/webgpu.h"
|
||||
#include "dawn/wire/client/Client.h"
|
||||
|
||||
|
||||
namespace dawn::wire {
|
||||
|
||||
void SerializedData(const fuzzing::Program& program, dawn::wire::ChunkedCommandSerializer serializer) {
|
||||
DawnLPMObjectIdProvider provider;
|
||||
|
||||
for (const fuzzing::Command& command : program.commands()) {
|
||||
switch (command.command_case()) {
|
||||
|
||||
{% for command in cmd_records["command"] %}
|
||||
case fuzzing::Command::k{{command.name.CamelCase()}}: {
|
||||
{{ command.name.CamelCase() }}Cmd {{ 'cmd' }};
|
||||
// TODO(chromium:1374747): Populate command buffer with serialized code from generated
|
||||
// protobuf structures. Currently, this will nullptr-deref constantly.
|
||||
memset(&{{ 'cmd' }}, 0, sizeof({{ command.name.CamelCase() }}Cmd));
|
||||
serializer.SerializeCommand(cmd, provider);
|
||||
break;
|
||||
}
|
||||
{% endfor %}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dawn::wire
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_DAWN_FUZZERS_DAWNLPMSERIALIZER_H_
|
||||
#define SRC_DAWN_FUZZERS_DAWNLPMSERIALIZER_H_
|
||||
|
||||
#include "dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.pb.h"
|
||||
#include "dawn/wire/ChunkedCommandSerializer.h"
|
||||
#include "dawn/wire/WireCmd_autogen.h"
|
||||
|
||||
namespace dawn::wire {
|
||||
|
||||
class DawnLPMObjectIdProvider : public ObjectIdProvider {
|
||||
private:
|
||||
|
||||
// Implementation of the ObjectIdProvider interface
|
||||
{% for type in by_category["object"] %}
|
||||
WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const final {
|
||||
*out = reinterpret_cast<uintptr_t>(object);
|
||||
return WireResult::Success;
|
||||
}
|
||||
WireResult GetOptionalId({{as_cType(type.name)}} object, ObjectId* out) const final {
|
||||
*out = reinterpret_cast<uintptr_t>(object);
|
||||
return WireResult::Success;
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
};
|
||||
|
||||
void SerializedData(const fuzzing::Program& program,
|
||||
dawn::wire::ChunkedCommandSerializer serializer);
|
||||
|
||||
} // namespace dawn::wire
|
||||
|
||||
#endif // SRC_DAWN_FUZZERS_DAWNLPMSERIALIZER_H_
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto2";
|
||||
package fuzzing;
|
||||
|
||||
{% for command in cmd_records["command"] %}
|
||||
message {{command.name.CamelCase()}} {}
|
||||
{% endfor %}
|
||||
|
||||
message Command {
|
||||
oneof command {
|
||||
{% for command in cmd_records["command"] %}
|
||||
{{command.name.CamelCase()}} {{command.name.camelCase()}} = {{ loop.index }};
|
||||
{% endfor %}
|
||||
}
|
||||
}
|
||||
|
||||
message Program {
|
||||
repeated Command commands = 1;
|
||||
}
|
|
@ -12,9 +12,12 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build_overrides/build.gni")
|
||||
import("../../../scripts/dawn_overrides_with_defaults.gni")
|
||||
|
||||
import("//build_overrides/build.gni")
|
||||
import("${dawn_root}/scripts/dawn_features.gni")
|
||||
import("${dawn_root}/src/dawn/fuzzers/dawn_fuzzers.gni")
|
||||
|
||||
# We only have libfuzzer in Chromium builds but if we build fuzzer targets only
|
||||
# there, we would risk breaking fuzzer targets all the time when making changes
|
||||
# to Dawn. To avoid that, we make fuzzer targets compile in standalone builds
|
||||
|
@ -110,6 +113,68 @@ dawn_fuzzer_test("dawn_wire_server_and_vulkan_backend_fuzzer") {
|
|||
additional_configs = [ "${dawn_root}/src/dawn/common:internal_config" ]
|
||||
}
|
||||
|
||||
if (is_dawn_lpm_fuzzer && build_with_chromium && dawn_use_swiftshader) {
|
||||
import("//third_party/protobuf/proto_library.gni")
|
||||
import("${dawn_root}/generator/dawn_generator.gni")
|
||||
|
||||
dawn_json_lpm_generator("dawn_lpmfuzz_cpp") {
|
||||
target = "dawn_lpmfuzz_cpp"
|
||||
outputs = [
|
||||
"src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.cpp",
|
||||
"src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h",
|
||||
]
|
||||
}
|
||||
|
||||
dawn_json_lpm_generator("dawn_lpmfuzz_proto") {
|
||||
target = "dawn_lpmfuzz_proto"
|
||||
outputs = [ "src/dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.proto" ]
|
||||
}
|
||||
|
||||
proto_library("dawn_lpm_proto") {
|
||||
proto_in_dir = "//"
|
||||
sources = get_target_outputs(":dawn_lpmfuzz_proto")
|
||||
|
||||
use_protobuf_full = true
|
||||
deps = [
|
||||
":dawn_lpmfuzz_proto",
|
||||
"//third_party/protobuf:protobuf_full",
|
||||
]
|
||||
}
|
||||
|
||||
copy("copy_dawn_lpm_proto_outputs") {
|
||||
# Hardcoded filenames because we can't get_target_outputs from a proto_library
|
||||
# TODO(tiszka): crbug.com/1410213
|
||||
sources = [
|
||||
"$root_out_dir/gen/$root_out_dir/gen/third_party/dawn/src/dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.pb.cc",
|
||||
"$root_out_dir/gen/$root_out_dir/gen/third_party/dawn/src/dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.pb.h",
|
||||
]
|
||||
outputs = [ "$root_out_dir/gen/third_party/dawn/src/dawn/fuzzers/lpmfuzz/{{source_file_part}}" ]
|
||||
deps = [ ":dawn_lpm_proto" ]
|
||||
}
|
||||
|
||||
dawn_fuzzer_test("dawn_lpm_fuzzer_and_vulkan_backend") {
|
||||
sources = get_target_outputs(":dawn_lpmfuzz_cpp")
|
||||
sources += [
|
||||
"lpmfuzz/DawnLPMFuzzer.cpp",
|
||||
"lpmfuzz/DawnLPMFuzzer.h",
|
||||
"lpmfuzz/DawnLPMFuzzerAndVulkanBackend.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":copy_dawn_lpm_proto_outputs",
|
||||
":dawn_lpmfuzz_cpp",
|
||||
"${dawn_root}/src/dawn:cpp",
|
||||
"${dawn_root}/src/dawn:proc",
|
||||
"${dawn_root}/src/dawn/common",
|
||||
"${dawn_root}/src/dawn/native:static",
|
||||
"${dawn_root}/src/dawn/utils",
|
||||
"${dawn_root}/src/dawn/wire:static",
|
||||
"//third_party/dawn/src/dawn/fuzzers:dawn_lpm_proto",
|
||||
"//third_party/libprotobuf-mutator",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# A group target to build all the fuzzers
|
||||
group("fuzzers") {
|
||||
testonly = true
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# Copyright 2023 The Dawn Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Build flag for dawn lpm fuzzers
|
||||
|
||||
declare_args() {
|
||||
is_dawn_lpm_fuzzer = false
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#define INSTANCE_OBJECT_ID 1
|
|
@ -0,0 +1,133 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "dawn/common/Assert.h"
|
||||
#include "dawn/common/Log.h"
|
||||
#include "dawn/common/SystemUtils.h"
|
||||
#include "dawn/dawn_proc.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMConstants.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMFuzzer.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.pb.h"
|
||||
#include "dawn/native/DawnNative.h"
|
||||
#include "dawn/utils/SystemUtils.h"
|
||||
#include "dawn/utils/TerribleCommandBuffer.h"
|
||||
#include "dawn/webgpu_cpp.h"
|
||||
#include "dawn/wire/ChunkedCommandSerializer.h"
|
||||
#include "dawn/wire/WireClient.h"
|
||||
#include "dawn/wire/WireServer.h"
|
||||
#include "testing/libfuzzer/libfuzzer_exports.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class DevNull : public dawn::wire::CommandSerializer {
|
||||
public:
|
||||
size_t GetMaximumAllocationSize() const override {
|
||||
// Some fuzzer bots have a 2GB allocation limit. Pick a value reasonably below that.
|
||||
return 1024 * 1024 * 1024;
|
||||
}
|
||||
void* GetCmdSpace(size_t size) override {
|
||||
if (size > buf.size()) {
|
||||
buf.resize(size);
|
||||
}
|
||||
return buf.data();
|
||||
}
|
||||
bool Flush() override { return true; }
|
||||
|
||||
private:
|
||||
std::vector<char> buf;
|
||||
};
|
||||
|
||||
std::unique_ptr<dawn::native::Instance> sInstance;
|
||||
WGPUProcDeviceCreateSwapChain sOriginalDeviceCreateSwapChain = nullptr;
|
||||
static bool (*sAdapterSupported)(const dawn::native::Adapter&) = nullptr;
|
||||
|
||||
WGPUSwapChain ErrorDeviceCreateSwapChain(WGPUDevice device,
|
||||
WGPUSurface surface,
|
||||
const WGPUSwapChainDescriptor*) {
|
||||
WGPUSwapChainDescriptor desc = {};
|
||||
// A 0 implementation will trigger a swapchain creation error.
|
||||
desc.implementation = 0;
|
||||
return sOriginalDeviceCreateSwapChain(device, surface, &desc);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int DawnLPMFuzzer::Initialize(int* argc, char*** argv) {
|
||||
// TODO(crbug.com/1038952): The Instance must be static because destructing the vkInstance with
|
||||
// Swiftshader crashes libFuzzer. When this is fixed, move this into Run so that error injection
|
||||
// for adapter discovery can be fuzzed.
|
||||
sInstance = std::make_unique<dawn::native::Instance>();
|
||||
sInstance->DiscoverDefaultAdapters();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DawnLPMFuzzer::Run(const fuzzing::Program& program,
|
||||
bool (*AdapterSupported)(const dawn::native::Adapter&)) {
|
||||
sAdapterSupported = AdapterSupported;
|
||||
|
||||
DawnProcTable procs = dawn::native::GetProcs();
|
||||
|
||||
// Swapchains receive a pointer to an implementation. The fuzzer will pass garbage in so we
|
||||
// intercept calls to create swapchains and make sure they always return error swapchains.
|
||||
// This is ok for fuzzing because embedders of dawn_wire would always define their own
|
||||
// swapchain handling.
|
||||
sOriginalDeviceCreateSwapChain = procs.deviceCreateSwapChain;
|
||||
procs.deviceCreateSwapChain = ErrorDeviceCreateSwapChain;
|
||||
|
||||
// Override requestAdapter to find an adapter that the fuzzer supports.
|
||||
procs.instanceRequestAdapter = [](WGPUInstance cInstance,
|
||||
const WGPURequestAdapterOptions* options,
|
||||
WGPURequestAdapterCallback callback, void* userdata) {
|
||||
std::vector<dawn::native::Adapter> adapters = sInstance->GetAdapters();
|
||||
for (dawn::native::Adapter adapter : adapters) {
|
||||
if (sAdapterSupported(adapter)) {
|
||||
WGPUAdapter cAdapter = adapter.Get();
|
||||
dawn::native::GetProcs().adapterReference(cAdapter);
|
||||
callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(WGPURequestAdapterStatus_Unavailable, nullptr, "No supported adapter.", userdata);
|
||||
};
|
||||
|
||||
dawnProcSetProcs(&procs);
|
||||
|
||||
DevNull devNull;
|
||||
dawn::wire::WireServerDescriptor serverDesc = {};
|
||||
serverDesc.procs = &procs;
|
||||
serverDesc.serializer = &devNull;
|
||||
|
||||
std::unique_ptr<dawn::wire::WireServer> wireServer(new dawn_wire::WireServer(serverDesc));
|
||||
wireServer->InjectInstance(sInstance->Get(), INSTANCE_OBJECT_ID, 0);
|
||||
|
||||
static utils::TerribleCommandBuffer* mCommandBuffer = new utils::TerribleCommandBuffer();
|
||||
static dawn::wire::ChunkedCommandSerializer mSerializer =
|
||||
dawn::wire::ChunkedCommandSerializer(mCommandBuffer);
|
||||
mCommandBuffer->SetHandler(wireServer.get());
|
||||
|
||||
dawn::wire::SerializedData(program, mSerializer);
|
||||
|
||||
mCommandBuffer->Flush();
|
||||
|
||||
// Note: Deleting the server will release all created objects.
|
||||
// Deleted devices will wait for idle on destruction.
|
||||
wireServer = nullptr;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_DAWN_FUZZERS_DAWNLPMFUZZER_H_
|
||||
#define SRC_DAWN_FUZZERS_DAWNLPMFUZZER_H_
|
||||
|
||||
#include "dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.pb.h"
|
||||
#include "dawn/webgpu_cpp.h"
|
||||
|
||||
namespace dawn::native {
|
||||
|
||||
class Adapter;
|
||||
|
||||
} // namespace dawn::native
|
||||
|
||||
namespace DawnLPMFuzzer {
|
||||
|
||||
int Initialize(int* argc, char*** argv);
|
||||
|
||||
int Run(const fuzzing::Program& program, bool (*AdapterSupported)(const dawn::native::Adapter&));
|
||||
} // namespace DawnLPMFuzzer
|
||||
|
||||
#endif // SRC_DAWN_FUZZERS_DAWNLPMFUZZER_H_
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dawn/common/GPUInfo.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMFuzzer.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.pb.h"
|
||||
#include "dawn/native/DawnNative.h"
|
||||
#include "testing/libfuzzer/libfuzzer_exports.h"
|
||||
#include "testing/libfuzzer/proto/lpm_interface.h"
|
||||
|
||||
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
|
||||
return DawnLPMFuzzer::Initialize(argc, argv);
|
||||
}
|
||||
|
||||
DEFINE_PROTO_FUZZER(const fuzzing::Program& program) {
|
||||
DawnLPMFuzzer::Run(program, [](const dawn::native::Adapter& adapter) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
||||
return gpu_info::IsGoogleSwiftshader(properties.vendorID, properties.deviceID);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"_comment": [
|
||||
"Copyright 2023 The Dawn Authors",
|
||||
"",
|
||||
"Licensed under the Apache License, Version 2.0 (the \"License\");",
|
||||
"you may not use this file except in compliance with the License.",
|
||||
"You may obtain a copy of the License at",
|
||||
"",
|
||||
" http://www.apache.org/licenses/LICENSE-2.0",
|
||||
"",
|
||||
"Unless required by applicable law or agreed to in writing, software",
|
||||
"distributed under the License is distributed on an \"AS IS\" BASIS,",
|
||||
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
|
||||
"See the License for the specific language governing permissions and",
|
||||
"limitations under the License."
|
||||
],
|
||||
|
||||
"_doc": "See docs/dawn/codegen.md"
|
||||
}
|
Loading…
Reference in New Issue