diff --git a/fuzz/fuzz_go.py b/fuzz/fuzz_go.py new file mode 100644 index 0000000000..7c3486f37d --- /dev/null +++ b/fuzz/fuzz_go.py @@ -0,0 +1,73 @@ +# Copyright (C) 2023 Intel Corporation +# SPDX-License-Identifier: GPL-3.0-or-later + +import sys +import tempfile +from pathlib import Path + +import atheris +import atheris_libprotobuf_mutator +from google.protobuf.json_format import MessageToDict + +import fuzz.generated.go_mod_pb2 as go_mod_pb2 +from cve_bin_tool.cvedb import CVEDB +from cve_bin_tool.log import LOGGER + +with atheris.instrument_imports(): + from cve_bin_tool.parsers.go import GoParser + +cve_db = CVEDB() +logger = LOGGER.getChild("Fuzz") + + +def GoModBuilder(data): + json_data = MessageToDict( + data, preserving_proto_field_name=True, including_default_value_fields=True + ) + + with open(file_path, "w") as f: + module_name = json_data.get("module_name", "") + go_version = json_data.get("go_version", "") + + f.write(f"module {module_name}\n") + f.write(f"go {go_version}\n") + + f.write("require (\n") + for dependency in json_data.get("require", []): + module_name = dependency.get("module_name", "") + version = dependency.get("version", "") + f.write(f"{module_name} {version}\n") + f.write(")\n") + + f.write("replace (\n") + for replacement in json_data.get("replace", []): + old_module = replacement.get("old_module", "") + old_version = replacement.get("old_version", "") + new_module = replacement.get("new_module", "") + new_version = replacement.get("new_version", "") + f.write(f"{old_module} {old_version} => {new_module} {new_version}\n") + f.write(")\n") + + f.write("exclude (\n") + for exclusion in json_data.get("exclude", []): + module_name = exclusion.get("module_name", "") + version = exclusion.get("version", "") + f.write(f"{module_name} {version}\n") + f.write(")\n") + + +def TestParseData(data): + try: + GoModBuilder(data) + + go_parser = GoParser(cve_db, logger) + go_parser.run_checker(file_path) + + except SystemExit: + return + + +file_path = str(Path(tempfile.mkdtemp(prefix="cve-bin-tool-")) / "go.mod") + +atheris_libprotobuf_mutator.Setup(sys.argv, TestParseData, proto=go_mod_pb2.GoModFile) +atheris.Fuzz() diff --git a/fuzz/generated/go_mod_pb2.py b/fuzz/generated/go_mod_pb2.py new file mode 100644 index 0000000000..3e892b1f67 --- /dev/null +++ b/fuzz/generated/go_mod_pb2.py @@ -0,0 +1,32 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: go_mod.proto +# Protobuf Python Version: 4.24.0-main +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x0cgo_mod.proto"\x94\x03\n\tGoModFile\x12\x13\n\x0bmodule_name\x18\x01 \x01(\t\x12\x12\n\ngo_version\x18\x02 \x01(\x02\x12,\n\x07require\x18\x03 \x03(\x0b\x32\x1b.GoModFile.ModuleDependency\x12)\n\x07\x65xclude\x18\x04 \x03(\x0b\x32\x18.GoModFile.ModuleExclude\x12-\n\x07replace\x18\x05 \x03(\x0b\x32\x1c.GoModFile.ModuleReplacement\x1a\x38\n\x10ModuleDependency\x12\x13\n\x0bmodule_name\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\x02\x1a\x65\n\x11ModuleReplacement\x12\x12\n\nold_module\x18\x01 \x01(\t\x12\x13\n\x0bold_version\x18\x02 \x01(\x02\x12\x12\n\nnew_module\x18\x03 \x01(\t\x12\x13\n\x0bnew_version\x18\x04 \x01(\x02\x1a\x35\n\rModuleExclude\x12\x13\n\x0bmodule_name\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\x02\x62\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "go_mod_pb2", _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals["_GOMODFILE"]._serialized_start = 17 + _globals["_GOMODFILE"]._serialized_end = 421 + _globals["_GOMODFILE_MODULEDEPENDENCY"]._serialized_start = 207 + _globals["_GOMODFILE_MODULEDEPENDENCY"]._serialized_end = 263 + _globals["_GOMODFILE_MODULEREPLACEMENT"]._serialized_start = 265 + _globals["_GOMODFILE_MODULEREPLACEMENT"]._serialized_end = 366 + _globals["_GOMODFILE_MODULEEXCLUDE"]._serialized_start = 368 + _globals["_GOMODFILE_MODULEEXCLUDE"]._serialized_end = 421 +# @@protoc_insertion_point(module_scope) diff --git a/fuzz/proto_files/go_mod.proto b/fuzz/proto_files/go_mod.proto new file mode 100644 index 0000000000..1a46d4e7d5 --- /dev/null +++ b/fuzz/proto_files/go_mod.proto @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: GPL-3.0-or-later + +syntax = "proto3"; + +message GoModFile { + message ModuleDependency { + string module_name = 1; + float version = 2; + } + message ModuleReplacement { + string old_module = 1; + float old_version = 2; + string new_module = 3; + float new_version = 4; + } + message ModuleExclude { + string module_name = 1; + float version = 2; + } + string module_name = 1; + float go_version = 2; + repeated ModuleDependency require = 3; + repeated ModuleExclude exclude = 4; + repeated ModuleReplacement replace = 5; + +} \ No newline at end of file