From cd5904e9ee693590ace60cd3d70a3c14969f8256 Mon Sep 17 00:00:00 2001 From: JJ LJ Date: Tue, 30 Sep 2025 00:40:28 -0400 Subject: [PATCH] Add support for loading ebpf maps via fd arrays --- MODULE.bazel.lock | 41 ++++++++--------------- ebpf_ffi/ebpf.cc | 60 ++++++++++++++++++++++++++-------- ebpf_ffi/ebpf.h | 6 ++-- pkg/ebpf/constants.go | 3 +- pkg/ebpf/st_ld_instructions.go | 20 ++++++++++++ pkg/units/control.go | 4 +++ pkg/units/ffi.go | 10 ++++++ proto/BUILD | 4 +-- proto/btf.proto | 2 ++ proto/ebpf.proto | 50 ++++++++++++++++++++++++++++ proto/ffi.proto | 5 +++ tools/loader.cc | 5 +-- 12 files changed, 161 insertions(+), 49 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index d77c2e4..c6d13b6 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -18,8 +18,8 @@ "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", - "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", - "https://bcr.bazel.build/modules/bazel_features/1.21.0/source.json": "3e8379efaaef53ce35b7b8ba419df829315a880cb0a030e5bb45c96d6d5ecb5f", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc", "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", @@ -49,7 +49,8 @@ "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", - "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.11/source.json": "f7e188b79ebedebfe75e9e1d098b8845226c7992b307e28e1496f23112e8fc29", "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", @@ -76,12 +77,12 @@ "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", - "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", - "https://bcr.bazel.build/modules/rules_cc/0.0.17/source.json": "4db99b3f55c90ab28d14552aa0632533e3e8e5e9aea0f5c24ac0014282c2a7c5", "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/source.json": "d61627377bd7dd1da4652063e368d9366fc9a73920bfa396798ad92172cf645c", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e", @@ -99,8 +100,8 @@ "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", - "https://bcr.bazel.build/modules/rules_java/8.11.0/MODULE.bazel": "c3d280bc5ff1038dcb3bacb95d3f6b83da8dd27bba57820ec89ea4085da767ad", - "https://bcr.bazel.build/modules/rules_java/8.11.0/source.json": "302b52a39259a85aa06ca3addb9787864ca3e03b432a5f964ea68244397e7544", + "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615", + "https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc", "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", @@ -142,15 +143,15 @@ "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" }, "selectedYankedVersions": {}, "moduleExtensions": { "@@gazelle+//:extensions.bzl%go_deps": { "general": { - "bzlTransitiveDigest": "nsDQnndMzdULQ+7W4lHxU3l/gbZHXSnFeUjfvmZ48o8=", + "bzlTransitiveDigest": "VVAAn6/dei08SNCXL9SMBVlvLVFG8ooZSnySVeLbWiA=", "usagesDigest": "50TQe/xPTguieWlBVMDWU2vPCVIoui4gF0lRXjEVGtM=", "recordedFileInputs": { "@@//go.mod": "cd9b505fcce953a8cfbd19cf94e253d1d21575a4b3a2be63b734cf93b435662b", @@ -568,25 +569,9 @@ ] } }, - "@@platforms//host:extension.bzl%host_platform": { - "general": { - "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=", - "usagesDigest": "SeQiIN/f8/Qt9vYQk7qcXp4I4wJeEC0RnQDiaaJ4tb8=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, - "generatedRepoSpecs": { - "host_platform": { - "repoRuleId": "@@platforms//host:extension.bzl%host_platform_repo", - "attributes": {} - } - }, - "recordedRepoMappingEntries": [] - } - }, "@@rules_go+//go:extensions.bzl%go_sdk": { "os:linux,arch:amd64": { - "bzlTransitiveDigest": "jBP0cRKOr+A42aPGunoasOD+vrmMLJIJ8Jwi65DdelE=", + "bzlTransitiveDigest": "SxAVT7Q4rpPYaEceNwyKt2uMO81h49UZbOS6EEiugKA=", "usagesDigest": "9C0KgnNPql7IwwveR5Oa8Jy3lqq523h2IOh9UMhUXKg=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -881,7 +866,7 @@ }, "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { "general": { - "bzlTransitiveDigest": "sFhcgPbDQehmbD1EOXzX4H1q/CD5df8zwG4kp4jbvr8=", + "bzlTransitiveDigest": "OlvsB0HsvxbR8ZN+J9Vf00X/+WVz/Y/5Xrq2LgcVfdo=", "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, diff --git a/ebpf_ffi/ebpf.cc b/ebpf_ffi/ebpf.cc index b695f77..0a9c3cb 100644 --- a/ebpf_ffi/ebpf.cc +++ b/ebpf_ffi/ebpf.cc @@ -14,6 +14,8 @@ #include "ebpf_ffi/ebpf.h" +#include + namespace ebpf_ffi { // This constant was determined arbitrarily, the number of 0's has incremented @@ -44,9 +46,29 @@ int btf_load(void *btf_buff, size_t btf_size, std::string &error) { return btf_fd; } -int load_ebpf_program(EncodedProgram program, size_t size, - std::string &verifier_log, std::string &error) { +uint64_t setup_bpf_maps(std::vector maps) { + size_t fd_array_size = sizeof(int) * maps.size(); + int *fd_array = (int *)malloc(fd_array_size); + if (!fd_array) return 0; + int i = 0; + for (ebpf::EbpfMap map : maps) { + int map_fd = + bpf_create_map(static_cast(map.type()), map.key_size(), + map.value_size(), map.max_entries()); + if (map_fd > 0) { + int j = 0; + for (uint64_t element : map.values()) { + ffi_update_map_element(map_fd, j++, element); + } + } + fd_array[i++] = map_fd; + } + return reinterpret_cast(fd_array); +} + +ValidationResult load_ebpf_program(EncodedProgram program, std::string &error) { struct bpf_insn *insn; + ValidationResult res; union bpf_attr attr = {}; // For the verifier log. @@ -73,22 +95,30 @@ int load_ebpf_program(EncodedProgram program, size_t size, attr.log_buf = (uint64_t)log_buf; attr.log_level = 2; + if (program.maps().size() > 0) { + uint64_t fd_array = setup_bpf_maps(std::vector( + program.maps().begin(), program.maps().end())); + attr.fd_array = fd_array; + res.set_fd_array_addr(fd_array); + } + int program_fd = syscall(SYS_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); if (program_fd < 0) { error = strerror(errno); } + res.set_program_fd(program_fd); - verifier_log = - std::string((const char *)log_buf, strlen((const char *)log_buf)); + res.set_verifier_log( + std::string((const char *)log_buf, strlen((const char *)log_buf))); free(log_buf); - return program_fd; + return res; } struct bpf_result ffi_load_ebpf_program(void *serialized_proto, size_t size, int coverage_enabled, uint64_t coverage_size) { - std::string verifier_log, error_message; + std::string error_message; struct coverage_data cover; memset(&cover, 0, sizeof(struct coverage_data)); @@ -102,15 +132,9 @@ struct bpf_result ffi_load_ebpf_program(void *serialized_proto, size_t size, if (!program.ParseFromString(serialized_proto_string)) { error_message = "Could not parse EncodedProgram proto"; } - int program_fd = - load_ebpf_program(program, size, verifier_log, error_message); - ValidationResult vres; + ValidationResult vres = load_ebpf_program(program, error_message); if (coverage_enabled) get_coverage_and_free_resources(&cover, &vres); - // Start building the validation result proto. - vres.set_verifier_log(verifier_log); - vres.set_program_fd(program_fd); - if (cover.fd != -1) { vres.set_did_collect_coverage(true); vres.set_coverage_size(cover.coverage_size); @@ -119,7 +143,7 @@ struct bpf_result ffi_load_ebpf_program(void *serialized_proto, size_t size, vres.set_did_collect_coverage(false); } - if (program_fd < 0) { + if (vres.program_fd() < 0) { // Return why we failed to load the program. vres.set_bpf_error(error_message); vres.set_is_valid(false); @@ -240,3 +264,11 @@ struct bpf_result ffi_execute_ebpf_program(void *serialized_proto, execution_result.set_did_succeed(true); return serialize_proto(execution_result); } + +void ffi_clean_fd_array(unsigned long long int addr, int size) { + int *fd_array = reinterpret_cast(addr); + for (int i = 0; i < size; i++) { + close(fd_array[size]); + } + free(fd_array); +} diff --git a/ebpf_ffi/ebpf.h b/ebpf_ffi/ebpf.h index 7b60f9f..8a6c409 100644 --- a/ebpf_ffi/ebpf.h +++ b/ebpf_ffi/ebpf.h @@ -30,8 +30,7 @@ extern "C" { // Actual implementation of load program. The split between ffi and // implementation is done so the impl code can be shared with other parts of the // codebase also written in C++. -int load_ebpf_program(EncodedProgram program, size_t size, - std::string &verifier_log, std::string &error); +ValidationResult load_ebpf_program(EncodedProgram program, std::string &error); // Loads a bpf program specified by |prog_buff| with |size| and returns struct // with a serialized ValidationResult proto. @@ -62,5 +61,8 @@ bool execute_ebpf_program(int prog_fd, uint8_t *input, int input_length, // Serialized proto is of type ExecutionRequest. struct bpf_result ffi_execute_ebpf_program(void *serialized_proto, size_t length); + +// Helps clean up any setup map fd array for a program. +void ffi_clean_fd_array(unsigned long long int addr, int size); } #endif // EBPF_FUZZER_EBPF_FFI_EBPF_H_ diff --git a/pkg/ebpf/constants.go b/pkg/ebpf/constants.go index 679d3d8..a1af70c 100644 --- a/pkg/ebpf/constants.go +++ b/pkg/ebpf/constants.go @@ -23,7 +23,8 @@ const ( ) const ( - PseudoMapFD = pb.Reg_R1 + PseudoMapFD = pb.Reg_R1 + PseudoMapIdx = pb.Reg_R5 ) const ( diff --git a/pkg/ebpf/st_ld_instructions.go b/pkg/ebpf/st_ld_instructions.go index 1a649d9..f749c3e 100644 --- a/pkg/ebpf/st_ld_instructions.go +++ b/pkg/ebpf/st_ld_instructions.go @@ -170,6 +170,26 @@ func LdMapByFd(dst pb.Reg, fd int) *pb.Instruction { return newLoadImmOperation(pb.StLdSize_StLdSizeDW, dst, PseudoMapFD, UnusedField, int32(fd), pseudoIns) } +func LdMapByIdx(dst pb.Reg, idx int) *pb.Instruction { + pseudoIns := &pb.Instruction{ + Opcode: &pb.Instruction_MemOpcode{ + MemOpcode: &pb.MemOpcode{ + Mode: 0, + Size: 0, + InstructionClass: 0, + }, + }, + DstReg: 0, + SrcReg: 0, + Offset: 0, + Immediate: 0, + PseudoInstruction: &pb.Instruction_Empty{ + Empty: &pb.Empty{}, + }, + } + return newLoadImmOperation(pb.StLdSize_StLdSizeDW, dst, PseudoMapIdx, UnusedField, int32(idx), pseudoIns) +} + func newAtomicInstruction(dst, src pb.Reg, size pb.StLdSize, offset int16, operation int32) *pb.Instruction { class := pb.InsClass_InsClassStx diff --git a/pkg/units/control.go b/pkg/units/control.go index ee9e7c1..580cbbf 100644 --- a/pkg/units/control.go +++ b/pkg/units/control.go @@ -134,8 +134,12 @@ func (cu *Control) runEbpf(prog *epb.Program) error { Program: encodedProg, Btf: prog.Btf, Function: encodedFuncInfo, + Maps: prog.Maps, } validationResult, err := cu.ffi.ValidateEbpfProgram(encodedProgram) + defer func() { + cu.ffi.CleanFdArray(validationResult.FdArrayAddr, len(prog.Maps)) + }() if err != nil { fmt.Printf("Validation error: %v\n", err) if !cu.strat.OnError(err) { diff --git a/pkg/units/ffi.go b/pkg/units/ffi.go index d289b54..5cb4e99 100644 --- a/pkg/units/ffi.go +++ b/pkg/units/ffi.go @@ -29,6 +29,7 @@ package units //int ffi_create_bpf_map(size_t size); //void ffi_close_fd(int fd); //int ffi_update_map_element(int map_fd, int key, uint64_t value); +//void ffi_clean_fd_array(unsigned long long int addr, int size); import "C" import ( @@ -132,6 +133,15 @@ func (e *FFI) SetMapElement(fd int, key uint32, value uint64) int { return int(C.ffi_update_map_element(C.int(fd), C.int(key), C.ulong(value))) } +// SetMapElement sets the elemnt specified by `key` to `value` in the map +// described by `fd` +func (e *FFI) CleanFdArray(fd_array uint64, size int) { + if fd_array == 0 { + return + } + C.ffi_clean_fd_array(C.ulonglong(fd_array), C.int(size)) +} + // ----------- eBPF -------------- // ValidateProgram passes the program through the bpf verifier without executing // it. Returns feedback to the generator so it can adjust the generation diff --git a/proto/BUILD b/proto/BUILD index 293bfe0..148b277 100644 --- a/proto/BUILD +++ b/proto/BUILD @@ -42,14 +42,14 @@ cc_proto_library( proto_library( name = "ffi_proto", srcs = ["ffi.proto"], - deps = [], + deps = [":ebpf_proto"], ) go_proto_library( name = "ffi_go_proto", importpath = "buzzer/proto/ffi_go_proto", protos = [":ffi_proto"], - deps = [], + deps = [":ebpf_go_proto"], ) cc_proto_library( diff --git a/proto/btf.proto b/proto/btf.proto index 7540242..7696f81 100644 --- a/proto/btf.proto +++ b/proto/btf.proto @@ -18,6 +18,8 @@ syntax = "proto3"; // https://docs.kernel.org/bpf/btf.html package btf; +option go_package = "buzzer/proto/btf_go_proto"; + message Empty {} // List of Supported Types diff --git a/proto/ebpf.proto b/proto/ebpf.proto index 89b79b7..81b6965 100644 --- a/proto/ebpf.proto +++ b/proto/ebpf.proto @@ -20,6 +20,8 @@ import "proto/btf.proto"; // https://www.kernel.org/doc/html/v5.17/bpf/instruction-set.html package ebpf; +option go_package = "buzzer/proto/ebpf_go_proto"; + message Empty {} // Reg each value corresponds to an ebpf register. @@ -165,7 +167,55 @@ message Functions { btf.FuncInfo func_info = 2; } +enum BpfMapType { + UNSPEC = 0; + HASH = 1; + ARRAY = 2; + PROG_ARRAY = 3; + PERF_EVENT_ARRAY = 4; + PERCPU_HASH = 5; + PERCPU_ARRAY = 6; + STACK_TRACE = 7; + CGROUP_ARRAY = 8; + LRU_HASH = 9; + LRU_PERCPU_HASH = 10; + LPM_TRIE = 11; + ARRAY_OF_MAPS = 12; + HASH_OF_MAPS = 13; + DEVMAP = 14; + SOCKMAP = 15; + CPUMAP = 16; + XSKMAP = 17; + SOCKHASH = 18; + CGROUP_STORAGE_DEPRECATED = 19; + CGROUP_STORAGE = 20; + REUSEPORT_SOCKARRAY = 21; + PERCPU_CGROUP_STORAGE_DEPRECATED = 22; + PERCPU_CGROUP_STORAGE = 23; + QUEUE = 24; + STACK = 25; + SK_STORAGE = 26; + DEVMAP_HASH = 27; + STRUCT_OPS = 28; + RINGBUF = 29; + INODE_STORAGE = 30; + TASK_STORAGE = 31; + BLOOM_FILTER = 32; + USER_RINGBUF = 33; + CGRP_STORAGE = 34; + ARENA = 35; +} + +message EbpfMap { + BpfMapType type = 1; + uint32 key_size = 2; + uint32 value_size = 3; + uint32 max_entries = 4; + repeated uint64 values = 5; +} + message Program { bytes btf = 1; repeated Functions functions = 2; + repeated EbpfMap maps = 3; } diff --git a/proto/ffi.proto b/proto/ffi.proto index f14c5ec..4e7bbe1 100644 --- a/proto/ffi.proto +++ b/proto/ffi.proto @@ -14,6 +14,8 @@ syntax = "proto3"; +import "proto/ebpf.proto"; + package ebpf_fuzzer; message ExecutionRequest { @@ -60,6 +62,7 @@ message ValidationResult { repeated uint64 coverage_address = 8; int64 socket_write = 9; // cbpf only int64 socket_read = 10; // cbpf only + uint64 fd_array_addr = 11; } message EncodedProgram { @@ -69,4 +72,6 @@ message EncodedProgram { bytes btf = 2; // Array of bytes with the encoded function info for the program's functions bytes function = 3; + + repeated ebpf.EbpfMap maps = 4; } diff --git a/tools/loader.cc b/tools/loader.cc index 79bbaa5..c3ff9bd 100644 --- a/tools/loader.cc +++ b/tools/loader.cc @@ -42,8 +42,9 @@ int main(int argc, char **argv) { if (!program.ParseFromString(serialized_proto_string)) { std::cout << "Could not parse EncodedProgram proto" << std::endl; } - int prog_fd = load_ebpf_program(program, size, verifier_log, error_message); - std::cout << "Verifier log: " << std::endl << verifier_log; + ValidationResult vres = load_ebpf_program(program, error_message); + std::cout << "Verifier log: " << std::endl << vres.verifier_log(); + int prog_fd = vres.program_fd(); if (prog_fd < 0) { std::cerr << "could not load bpf program: " << error_message << std::endl;