diff --git a/dotnet/fuzz/BUILD.bazel b/dotnet/fuzz/BUILD.bazel index ac2b2d02b..7de7897d5 100644 --- a/dotnet/fuzz/BUILD.bazel +++ b/dotnet/fuzz/BUILD.bazel @@ -1,13 +1,27 @@ load("@rules_cc//cc:defs.bzl", "cc_binary") load("@rules_dx//libs/starlark:fuzz.bzl", "dx_fuzz_binary") load("@rules_dx//quality:fixtures.bzl", "real_source_target") +load("@rules_dx//rust/rules:defs.bzl", "rust_binary") + +_SUPPORTED = select({ + "@platforms//os:linux": [], + "//conditions:default": ["@platforms//:incompatible"], +}) + +rust_binary( + name = "instrument", + srcs = ["instrument/main.rs"], + crate_name = "instrument", + crate_root = "instrument/main.rs", + visibility = ["//visibility:public"], +) cc_binary( name = "libfuzzer_dotnet_bin", srcs = ["@dx_libfuzzer_dotnet//:libfuzzer-dotnet.cc"], copts = ["-fsanitize=fuzzer"], linkopts = ["-fsanitize=fuzzer"], - target_compatible_with = ["@platforms//os:linux"], + target_compatible_with = _SUPPORTED, testonly = True, visibility = ["//visibility:private"], ) @@ -15,7 +29,7 @@ cc_binary( dx_fuzz_binary( name = "libfuzzer_dotnet", binary = ":libfuzzer_dotnet_bin", - target_compatible_with = ["@platforms//os:linux"], + target_compatible_with = _SUPPORTED, testonly = True, visibility = ["//visibility:public"], ) diff --git a/dotnet/fuzz/instrument/main.rs b/dotnet/fuzz/instrument/main.rs new file mode 100644 index 000000000..0afbf596f --- /dev/null +++ b/dotnet/fuzz/instrument/main.rs @@ -0,0 +1,31 @@ +//! Copies an assembly and runs SharpFuzz on the copy: `instrument `. + +use std::process::{Command, ExitCode}; +use std::{env, fs}; + +fn main() -> ExitCode { + let args: Vec = env::args().skip(1).collect(); + let [sharpfuzz, input, output] = args.as_slice() else { + eprintln!("usage: instrument "); + return ExitCode::from(2); + }; + if let Err(err) = fs::copy(input, output).and_then(|_| { + let mut perms = fs::metadata(output)?.permissions(); + perms.set_readonly(false); + fs::set_permissions(output, perms) + }) { + eprintln!("instrument: copying {input} to {output}: {err}"); + return ExitCode::from(1); + } + match Command::new(sharpfuzz).arg(output).status() { + Ok(status) if status.success() => ExitCode::SUCCESS, + Ok(status) => { + eprintln!("instrument: sharpfuzz failed: {status}"); + ExitCode::from(1) + } + Err(err) => { + eprintln!("instrument: running {sharpfuzz}: {err}"); + ExitCode::from(1) + } + } +} diff --git a/families/dotnet/MODULE.bazel.lock b/families/dotnet/MODULE.bazel.lock index 9b4551caf..fcef354fd 100644 --- a/families/dotnet/MODULE.bazel.lock +++ b/families/dotnet/MODULE.bazel.lock @@ -257,6 +257,8 @@ "https://bcr.bazel.build/modules/gcc_toolchain/0.13.0/MODULE.bazel": "8912be8684729c2814e922aa3555d163d1c6e7dbf620e72753fe44f3761250e4", "https://bcr.bazel.build/modules/gcc_toolchain/0.13.0/source.json": "41e8693ad56244dde548f7711126deda72eeff630f66f5e2d8403227d4a78097", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/google_benchmark/1.9.5/MODULE.bazel": "8a85cfd90b1e45e6e68f1aa2aa9efce3c04add57df732571d7fd54c07e7c5143", + "https://bcr.bazel.build/modules/google_benchmark/1.9.5/source.json": "0bd357fd9db30ee31d5eb4c78b1086ce3d79b4423ce76de19e8a2fa7b2fa2e10", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", @@ -269,6 +271,8 @@ "https://bcr.bazel.build/modules/jq.bzl/0.4.0/source.json": "52ec7530c4618e03f634b30ff719814a68d7d39c235938b7aa2abbfe1eb1c52c", "https://bcr.bazel.build/modules/jsoncpp/1.9.6.bcr.2/MODULE.bazel": "64f508885f907ac2518039b3d0c5c1703a8f6137d9f5d635067ba93d33c2670a", "https://bcr.bazel.build/modules/jsoncpp/1.9.6.bcr.2/source.json": "13199fa0a267ca46814e9e6ab313a71890c8f1822e57376fdc23a2d2cd384051", + "https://bcr.bazel.build/modules/libpfm/4.11.0.bcr.1/MODULE.bazel": "e5362dadc90aab6724c83a2cc1e67cbed9c89a05d97fb1f90053c8deb1e445c8", + "https://bcr.bazel.build/modules/libpfm/4.11.0.bcr.1/source.json": "0646414d9037f8aad148781dd760bec90b0b25ac12fda5e03f8aadbd6b9c61e6", "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", "https://bcr.bazel.build/modules/libxml2/2.15.3/MODULE.bazel": "a6bffafd8aa8b0c13eaa4bf25d55be188ec8548549395f03e98c39bab264adaa", "https://bcr.bazel.build/modules/libxml2/2.15.4/MODULE.bazel": "8d0bca5635a3ba19dddd0fcf0578b032f3c127f597e7f6b24cec3462bf10b824", @@ -417,6 +421,8 @@ "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", "https://bcr.bazel.build/modules/rules_rust/0.75.0/MODULE.bazel": "77452ad75faf65400abc8d0956033d5732c68d39478c9ac064288d3f484f6e34", "https://bcr.bazel.build/modules/rules_rust/0.75.0/source.json": "6205a2156646606f99828f217931f4cd5c68f3ada35916dab6601020358bfc63", + "https://bcr.bazel.build/modules/rules_rust_prost/0.75.0/MODULE.bazel": "352c97c54b4938acaae4f5be9cf380845d56ce6f062cf161f78059764f7d901a", + "https://bcr.bazel.build/modules/rules_rust_prost/0.75.0/source.json": "fdd8bb6bd5fca6d0f672a2438312016e91c8010fdd9c9355a8eec4f503aa5ac5", "https://bcr.bazel.build/modules/rules_rust_wasm_bindgen/0.75.0/MODULE.bazel": "2da21af41a035b2c603b2b8fe768d63746df1bae69fadd2d762c0436cd601ac8", "https://bcr.bazel.build/modules/rules_rust_wasm_bindgen/0.75.0/source.json": "f0ce711d9162d4fda731e58d2939358d70bc35ac641c9890f998e6852842cec2", "https://bcr.bazel.build/modules/rules_scala/7.4.1/MODULE.bazel": "74174791015794a463fb0f1e5b68d281dbb64d0afea01a539b21abe922eab79d", @@ -17586,7 +17592,7 @@ "@@rules_zig+//zig:extensions.bzl%zig": { "general": { "bzlTransitiveDigest": "vTeQKV6Xl5RuIpCwuarKlx1FwNYsPvKFOklJop5h/mI=", - "usagesDigest": "G3RaphUrcukF6Utq5kIh8yMCfhYZTf1FZHFUaUmNuy0=", + "usagesDigest": "QF0FP4iBd3UL3eOAQ/3YQ/7Y7gdmVPz2aHt0+5zCriE=", "recordedInputs": [ "REPO_MAPPING:rules_zig+,bazel_skylib bazel_skylib+", "REPO_MAPPING:rules_zig+,bazel_tools bazel_tools", @@ -17997,22 +18003,6 @@ "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "notice_version": "3" }, - "@@rules_dx+//ocaml/toolchain:repos.bzl%ocaml": { - "691408b00730fcedbd3e30ccdb42c388a83fd304/astring.0.8.5": { - "needs": [ - "ocamlfind", - "ocamlbuild", - "topkg" - ], - "sha256": "865692630c07c3ab87c66cdfc2734c0fdfc9c34a57f8e89ffec7c7d15e7a70fa", - "src": "https://erratique.ch/software/astring/releases/astring-0.8.5.tbz" - }, - "691408b00730fcedbd3e30ccdb42c388a83fd304/either.1.0.0": { - "needs": [], - "sha256": "bf674de3312dee7b7215f07df1e8a96eb3d679164b8a918cdd95b8d97e505884", - "src": "https://github.com/mirage/either/releases/download/1.0.0/either-1.0.0.tbz" - } - }, "@@rules_go+//go:extensions.bzl%go_sdk": { "1.22.4": { "aix_ppc64": [ diff --git a/families/dotnet/csharp/rules/sharpfuzz.bzl b/families/dotnet/csharp/rules/sharpfuzz.bzl index 47fab83f0..2c4f8ed7b 100644 --- a/families/dotnet/csharp/rules/sharpfuzz.bzl +++ b/families/dotnet/csharp/rules/sharpfuzz.bzl @@ -8,7 +8,10 @@ SHARPFUZZ = [ Label("@paket.main//sharpfuzz"), ] -_LINUX = ["@platforms//os:linux"] +_SUPPORTED = select({ + "@platforms//os:linux": [], + "//conditions:default": ["@platforms//:incompatible"], +}) DxSharpFuzzInfo = provider( doc = "A target's runtime info with first-party assemblies instrumented by SharpFuzz.", @@ -29,12 +32,12 @@ def _aspect_impl(target, ctx): libs = [] for dll in runtime.libs: copy = ctx.actions.declare_file("{}_sharpfuzz/{}".format(ctx.label.name, dll.basename)) - ctx.actions.run_shell( + ctx.actions.run( inputs = [dll], outputs = [copy], + executable = ctx.executable._instrument, tools = [ctx.executable._sharpfuzz], - command = 'cp "$1" "$2" && chmod u+w "$2" && "$3" "$2"', - arguments = [dll.path, copy.path, ctx.executable._sharpfuzz.path], + arguments = [ctx.executable._sharpfuzz.path, dll.path, copy.path], mnemonic = "SharpFuzzInstrument", progress_message = "Instrumenting %{output} with SharpFuzz", ) @@ -61,6 +64,11 @@ dx_sharpfuzz_aspect = aspect( implementation = _aspect_impl, attr_aspects = ["deps"], attrs = { + "_instrument": attr.label( + default = Label("@rules_dx//dotnet/fuzz:instrument"), + executable = True, + cfg = "exec", + ), "_sharpfuzz": attr.label( default = Label("@paket.main//sharpfuzz.commandline/tools:sharpfuzz"), executable = True, @@ -111,7 +119,7 @@ def sharpfuzz_fuzz(name, binary, srcs, deps, visibility, tags, kwargs): ) instrumented.append(":" + wrapped) kwargs = dict(kwargs) - kwargs["target_compatible_with"] = kwargs.get("target_compatible_with", _LINUX) + kwargs["target_compatible_with"] = kwargs.get("target_compatible_with", _SUPPORTED) binary( name = name, srcs = srcs,