Increase instruction count limit (#1152)

* Increase bound on instruction count

And align more with other platforms

Signed-off-by: Dave Thaler <dthaler@microsoft.com>

* Fix compiler error

Signed-off-by: Dave Thaler <dthaler@microsoft.com>
This commit is contained in:
Dave Thaler 2022-05-31 16:02:05 -07:00 коммит произвёл GitHub
Родитель 709ee13c12
Коммит ee166b5717
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 148 добавлений и 128 удалений

Просмотреть файл

@ -17,7 +17,7 @@ ebpf_server_verify_and_load_program(
{
ebpf_result_t result;
if (info->byte_code_size == 0) {
if (info->instruction_count == 0) {
return EBPF_INVALID_ARGUMENT;
}
@ -31,8 +31,8 @@ ebpf_server_verify_and_load_program(
info->execution_type,
info->map_count,
info->handle_map,
info->byte_code_size,
info->byte_code,
info->instruction_count,
reinterpret_cast<ebpf_inst*>(info->instructions),
const_cast<const char**>(logs),
logs_size);

Просмотреть файл

@ -293,39 +293,6 @@ extern "C"
ebpf_result_t
ebpf_object_set_execution_type(_In_ struct bpf_object* object, ebpf_execution_type_t execution_type);
/**
* @brief Load an eBPF program from raw instructions.
*
* @param[in] program_type The eBPF program type.
* @param[in] program_name The eBPF program name.
* @param[in] execution_type The execution type to use for this program. If
* EBPF_EXECUTION_ANY is specified, execution type will be decided by a
* system-wide policy.
* @param[in] byte_code The eBPF program byte code.
* @param[in] byte_code_size Size in bytes (not instruction count) of the
* eBPF program byte code.
* @param[out] log_buf The buffer in which to write log messages.
* @param[in] log_buf_sz Size in bytes of the caller's log buffer.
* @param[out] program_fd Returns a file descriptor for the program.
* The caller should call _close() on the fd to close this when done.
*
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_ARGUMENT One or more parameters are incorrect.
* @retval EBPF_NO_MEMORY Out of memory.
* @retval EBPF_VERIFICATION_FAILED The program failed verification.
* @retval EBPF_FAILED Some other error occured.
*/
ebpf_result_t
ebpf_program_load_bytes(
_In_ const ebpf_program_type_t* program_type,
_In_opt_z_ const char* program_name,
ebpf_execution_type_t execution_type,
_In_reads_(byte_code_size) const uint8_t* byte_code,
uint32_t byte_code_size,
_Out_writes_opt_(log_buf_sz) char* log_buf,
size_t log_buf_sz,
_Out_ fd_t* program_fd);
/**
* @brief Attach an eBPF program.
*

Просмотреть файл

@ -215,9 +215,14 @@ load_byte_code(
result = EBPF_NO_MEMORY;
goto Exit;
}
size_t ebpf_bytes = raw_program.prog.size() * sizeof(ebpf_inst);
program->byte_code = (uint8_t*)calloc(1, ebpf_bytes);
if (program->byte_code == nullptr) {
size_t instruction_count = raw_program.prog.size();
if (instruction_count > UINT32_MAX) {
result = EBPF_NO_MEMORY;
goto Exit;
}
size_t ebpf_bytes = instruction_count * sizeof(ebpf_inst);
program->instructions = (ebpf_inst*)calloc(1, ebpf_bytes);
if (program->instructions == nullptr) {
result = EBPF_NO_MEMORY;
goto Exit;
}
@ -234,12 +239,9 @@ load_byte_code(
int i = 0;
for (ebpf_inst instruction : raw_program.prog) {
char* buffer = (char*)&instruction;
for (int j = 0; j < sizeof(ebpf_inst) && i < ebpf_bytes; i++, j++) {
program->byte_code[i] = buffer[j];
}
program->instructions[i++] = instruction;
}
program->byte_code_size = static_cast<uint32_t>(ebpf_bytes);
program->instruction_count = (uint32_t)instruction_count;
programs.emplace_back(program);
program = nullptr;
}

Просмотреть файл

@ -17,8 +17,8 @@ typedef struct bpf_program
struct bpf_object* object;
char* section_name;
char* program_name;
uint8_t* byte_code;
uint32_t byte_code_size;
struct ebpf_inst* instructions;
uint32_t instruction_count;
ebpf_program_type_t program_type;
ebpf_attach_type_t attach_type;
ebpf_handle_t handle;
@ -541,3 +541,36 @@ ebpf_api_elf_enumerate_sections(
bool verbose,
_Outptr_result_maybenull_ ebpf_section_info_t** infos,
_Outptr_result_maybenull_z_ const char** error_message);
/**
* @brief Load an eBPF programs from raw instructions.
*
* @param[in] program_type The eBPF program type.
* @param[in] program_name The eBPF program name.
* @param[in] execution_type The execution type to use for this program. If
* EBPF_EXECUTION_ANY is specified, execution type will be decided by a
* system-wide policy.
* @param[in] instructions The eBPF program byte code.
* @param[in] instruction_count Number of instructions in the
* eBPF program byte code.
* @param[out] log_buffer The buffer in which to write log messages.
* @param[in] log_buffer_size Size in bytes of the caller's log buffer.
* @param[out] program_fd Returns a file descriptor for the program.
* The caller should call _close() on the fd to close this when done.
*
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_ARGUMENT One or more parameters are incorrect.
* @retval EBPF_NO_MEMORY Out of memory.
* @retval EBPF_VERIFICATION_FAILED The program failed verification.
* @retval EBPF_FAILED Some other error occured.
*/
ebpf_result_t
ebpf_program_load_bytes(
_In_ const ebpf_program_type_t* program_type,
_In_opt_z_ const char* program_name,
ebpf_execution_type_t execution_type,
_In_reads_(instruction_count) const ebpf_inst* instructions,
uint32_t instruction_count,
_Out_writes_opt_(log_buffer_size) char* log_buffer,
size_t log_buffer_size,
_Out_ fd_t* program_fd);

Просмотреть файл

@ -1271,7 +1271,7 @@ clean_up_ebpf_program(_In_ _Post_invalid_ ebpf_program_t* program)
ebpf_assert(program);
ebpf_program_unload(program);
free(program->byte_code);
free(program->instructions);
free(program->program_name);
free(program->section_name);
free((void*)program->log_buffer);
@ -2242,15 +2242,15 @@ ebpf_program_load_bytes(
_In_ const ebpf_program_type_t* program_type,
_In_opt_z_ const char* program_name,
ebpf_execution_type_t execution_type,
_In_reads_(byte_code_size) const uint8_t* byte_code,
uint32_t byte_code_size,
_In_reads_(instruction_count) const ebpf_inst* instructions,
uint32_t instruction_count,
_Out_writes_opt_(log_buffer_size) char* log_buffer,
size_t log_buffer_size,
_Out_ fd_t* program_fd)
{
EBPF_LOG_ENTRY();
ebpf_assert(program_type);
ebpf_assert(byte_code);
ebpf_assert(instructions);
ebpf_assert(program_fd);
ebpf_assert(log_buffer || !log_buffer_size);
@ -2280,20 +2280,18 @@ ebpf_program_load_bytes(
load_info.program_type = *program_type;
load_info.program_handle = reinterpret_cast<file_handle_t>(program_handle);
load_info.execution_type = execution_type;
load_info.byte_code = const_cast<uint8_t*>(byte_code);
load_info.byte_code_size = byte_code_size;
load_info.instructions = (ebpf_instruction_t*)instructions;
load_info.instruction_count = instruction_count;
load_info.execution_context = execution_context_kernel_mode;
// Resolve map handles in byte code.
std::vector<original_fd_handle_map_t> handle_map;
const ebpf_inst* instructions = reinterpret_cast<const ebpf_inst*>(byte_code);
const ebpf_inst* instruction_end = reinterpret_cast<const ebpf_inst*>(byte_code + byte_code_size);
for (size_t index = 0; index < byte_code_size / sizeof(ebpf_inst); index++) {
for (size_t index = 0; index < instruction_count; index++) {
const ebpf_inst& first_instruction = instructions[index];
if (first_instruction.opcode != INST_OP_LDDW_IMM) {
continue;
}
if (&instructions[index + 1] >= instruction_end) {
if (index + 1 >= instruction_count) {
result = EBPF_INVALID_ARGUMENT;
break;
}
@ -2388,8 +2386,8 @@ _ebpf_object_load_programs(_Inout_ struct bpf_object* object)
load_info.program_type = program->program_type;
load_info.program_handle = reinterpret_cast<file_handle_t>(program->handle);
load_info.execution_type = object->execution_type;
load_info.byte_code = program->byte_code;
load_info.byte_code_size = program->byte_code_size;
load_info.instructions = reinterpret_cast<ebpf_instruction_t*>(program->instructions);
load_info.instruction_count = program->instruction_count;
load_info.execution_context = execution_context_kernel_mode;
load_info.map_count = (uint32_t)object->maps.size();

Просмотреть файл

@ -90,8 +90,7 @@ _get_bpf_attach_type(const ebpf_attach_type_t* type)
int
bpf_load_program_xattr(const struct bpf_load_program_attr* load_attr, char* log_buf, size_t log_buf_sz)
{
size_t byte_code_size = load_attr->insns_cnt * sizeof(struct ebpf_inst);
if (byte_code_size < 1 || byte_code_size > UINT32_MAX) {
if (load_attr->insns_cnt < 1 || load_attr->insns_cnt > UINT32_MAX) {
return libbpf_err(-EINVAL);
}
@ -105,8 +104,8 @@ bpf_load_program_xattr(const struct bpf_load_program_attr* load_attr, char* log_
program_type,
load_attr->name,
EBPF_EXECUTION_ANY,
(const uint8_t*)load_attr->insns,
(uint32_t)byte_code_size,
reinterpret_cast<const ebpf_inst*>(load_attr->insns),
(uint32_t)load_attr->insns_cnt,
log_buf,
log_buf_sz,
&program_fd);
@ -168,8 +167,8 @@ bpf_prog_load(
program_type,
prog_name,
EBPF_EXECUTION_ANY,
(const uint8_t*)insns,
(uint32_t)(insn_cnt * sizeof(ebpf_inst)),
reinterpret_cast<const ebpf_inst*>(insns),
(uint32_t)insn_cnt,
log_buffer,
log_buffer_size,
&program_fd);
@ -231,7 +230,7 @@ bpf_program__section_name(const struct bpf_program* program)
size_t
bpf_program__size(const struct bpf_program* program)
{
return program->byte_code_size;
return program->instruction_count * sizeof(ebpf_inst);
}
const char*

Просмотреть файл

@ -708,6 +708,12 @@ _ebpf_program_load_byte_code(
goto Done;
}
// ubpf currently requires the byte count to fit in a uint32_t.
if (instruction_count > UINT32_MAX / sizeof(ebpf_instruction_t)) {
return_value = EBPF_PROGRAM_TOO_LARGE;
goto Done;
}
program->code_or_vm.vm = ubpf_create();
if (!program->code_or_vm.vm) {
return_value = EBPF_NO_MEMORY;

Просмотреть файл

@ -18,12 +18,14 @@ extern "C"
#include "verifier_service.h"
#include "windows_platform.hpp"
#define MAX_CODE_SIZE_IN_BYTES (32 * 1024) // 32 KB
// Maximum size of JIT'ed native code.
#define MAX_NATIVE_CODE_SIZE_IN_BYTES (32 * 1024) // 32 KB
static ebpf_result_t
_build_helper_id_to_address_map(
ebpf_handle_t program_handle,
ebpf_code_buffer_t& byte_code,
_In_reads_(instruction_count) ebpf_inst* instructions,
uint32_t instruction_count,
std::vector<uint64_t>& helper_addresses,
uint32_t& unwind_index)
{
@ -34,8 +36,7 @@ _build_helper_id_to_address_map(
std::map<uint32_t, uint32_t> helper_id_mapping;
unwind_index = MAXUINT32;
ebpf_inst* instructions = reinterpret_cast<ebpf_inst*>(byte_code.data());
for (size_t index = 0; index < byte_code.size() / sizeof(ebpf_inst); index++) {
for (size_t index = 0; index < instruction_count; index++) {
ebpf_inst& instruction = instructions[index];
if (instruction.opcode != INST_OP_CALL) {
continue;
@ -84,7 +85,7 @@ _build_helper_id_to_address_map(
}
// Replace old helper_ids in range [1, MAXUINT32] with new helper ids in range [0,63]
for (index = 0; index < byte_code.size() / sizeof(ebpf_inst); index++) {
for (index = 0; index < instruction_count; index++) {
ebpf_inst& instruction = instructions[index];
if (instruction.opcode != INST_OP_CALL) {
continue;
@ -123,20 +124,19 @@ _resolve_ec_function(ebpf_ec_function_t function, uint64_t* address)
// Replace map fds with map addresses.
static ebpf_result_t
_resolve_maps_in_byte_code(ebpf_handle_t program_handle, ebpf_code_buffer_t& byte_code)
_resolve_maps_in_byte_code(
ebpf_handle_t program_handle, _In_reads_(instruction_count) ebpf_inst* instructions, uint32_t instruction_count)
{
// Create parallel vectors indexed by # of occurrence in the instructions.
std::vector<size_t> instruction_offsets; // 0-based instruction number.
std::vector<fd_t> map_fds; // map_fd used in the bytecode.
ebpf_inst* instructions = reinterpret_cast<ebpf_inst*>(byte_code.data());
ebpf_inst* instruction_end = reinterpret_cast<ebpf_inst*>(byte_code.data() + byte_code.size());
for (size_t index = 0; index < byte_code.size() / sizeof(ebpf_inst); index++) {
for (size_t index = 0; index < instruction_count; index++) {
ebpf_inst& first_instruction = instructions[index];
if (first_instruction.opcode != INST_OP_LDDW_IMM) {
continue;
}
if (&instructions[index + 1] >= instruction_end) {
if (index + 1 >= instruction_count) {
return EBPF_INVALID_ARGUMENT;
}
index++;
@ -231,16 +231,16 @@ _query_and_cache_map_descriptors(
ebpf_result_t
ebpf_verify_and_load_program(
const GUID* program_type,
_In_ const GUID* program_type,
ebpf_handle_t program_handle,
ebpf_execution_context_t execution_context,
ebpf_execution_type_t execution_type,
uint32_t handle_map_count,
original_fd_handle_map_t* handle_map,
uint32_t byte_code_size,
uint8_t* byte_code,
const char** error_message,
uint32_t* error_message_size) noexcept
_In_reads_(handle_map_count) original_fd_handle_map_t* handle_map,
uint32_t instruction_count,
_In_reads_(instruction_count) ebpf_inst* instructions,
_Outptr_result_maybenull_z_ const char** error_message,
_Out_ uint32_t* error_message_size) noexcept
{
ebpf_result_t result = EBPF_SUCCESS;
int error = 0;
@ -274,19 +274,12 @@ ebpf_verify_and_load_program(
}
// Verify the program.
result = verify_byte_code(program_type, byte_code, byte_code_size, error_message, error_message_size);
result = verify_byte_code(program_type, instructions, instruction_count, error_message, error_message_size);
if (result != EBPF_SUCCESS) {
goto Exit;
}
if (byte_code_size > MAX_CODE_SIZE_IN_BYTES) {
result = EBPF_PROGRAM_TOO_LARGE;
goto Exit;
}
ebpf_code_buffer_t byte_code_buffer(byte_code, byte_code + byte_code_size);
result = _resolve_maps_in_byte_code(program_handle, byte_code_buffer);
result = _resolve_maps_in_byte_code(program_handle, instructions, instruction_count);
if (result != EBPF_SUCCESS) {
goto Exit;
}
@ -296,15 +289,18 @@ ebpf_verify_and_load_program(
goto Exit;
}
std::vector<uint64_t> helper_id_adddress;
std::vector<uint64_t> helper_id_address;
uint32_t unwind_index;
result = _build_helper_id_to_address_map(program_handle, byte_code_buffer, helper_id_adddress, unwind_index);
result = _build_helper_id_to_address_map(
program_handle, instructions, instruction_count, helper_id_address, unwind_index);
if (result != EBPF_SUCCESS)
goto Exit;
if (execution_type == EBPF_EXECUTION_JIT) {
ebpf_code_buffer_t machine_code(MAX_NATIVE_CODE_SIZE_IN_BYTES);
uint8_t* byte_code_data = (uint8_t*)instructions;
size_t byte_code_size = instruction_count * sizeof(*instructions);
ebpf_code_buffer_t machine_code(MAX_CODE_SIZE_IN_BYTES);
if (execution_type == EBPF_EXECUTION_JIT) {
size_t machine_code_size = machine_code.size();
// JIT code.
@ -314,8 +310,8 @@ ebpf_verify_and_load_program(
goto Exit;
}
for (uint32_t helper_id = 0; helper_id < helper_id_adddress.size(); helper_id++) {
if (ubpf_register(vm, helper_id, nullptr, reinterpret_cast<void*>(helper_id_adddress[helper_id])) < 0) {
for (uint32_t helper_id = 0; helper_id < helper_id_address.size(); helper_id++) {
if (ubpf_register(vm, helper_id, nullptr, reinterpret_cast<void*>(helper_id_address[helper_id])) < 0) {
result = EBPF_JIT_COMPILATION_FAILED;
goto Exit;
}
@ -328,10 +324,7 @@ ebpf_verify_and_load_program(
vm, reinterpret_cast<int (*)(FILE * stream, const char* format, ...)>(log_function_address));
if (ubpf_load(
vm,
byte_code_buffer.data(),
static_cast<uint32_t>(byte_code_buffer.size()),
const_cast<char**>(error_message)) < 0) {
vm, byte_code_data, static_cast<uint32_t>(byte_code_size), const_cast<char**>(error_message)) < 0) {
result = EBPF_JIT_COMPILATION_FAILED;
goto Exit;
}
@ -341,24 +334,22 @@ ebpf_verify_and_load_program(
goto Exit;
}
machine_code.resize(machine_code_size);
byte_code_buffer = machine_code;
byte_code_data = machine_code.data();
byte_code_size = machine_code.size();
if (*error_message != nullptr) {
*error_message_size = (uint32_t)strlen(*error_message);
}
}
request_buffer.resize(offsetof(ebpf_operation_load_code_request_t, code) + byte_code_buffer.size());
request_buffer.resize(offsetof(ebpf_operation_load_code_request_t, code) + byte_code_size);
request = reinterpret_cast<ebpf_operation_load_code_request_t*>(request_buffer.data());
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_LOAD_CODE;
request->header.length = static_cast<uint16_t>(request_buffer.size());
request->program_handle = program_handle;
request->code_type = execution_type == EBPF_EXECUTION_JIT ? EBPF_CODE_JIT : EBPF_CODE_EBPF;
std::copy(
byte_code_buffer.begin(),
byte_code_buffer.end(),
request_buffer.begin() + offsetof(ebpf_operation_load_code_request_t, code));
memcpy(request->code, byte_code_data, byte_code_size);
error = invoke_ioctl(request_buffer);

Просмотреть файл

@ -12,16 +12,16 @@
ebpf_result_t
ebpf_verify_and_load_program(
const GUID* program_type,
_In_ const GUID* program_type,
ebpf_handle_t program_handle,
ebpf_execution_context_t execution_context,
ebpf_execution_type_t execution_type,
uint32_t handle_map_count,
original_fd_handle_map_t* handle_map,
uint32_t byte_code_size,
uint8_t* byte_code,
const char** error_message,
uint32_t* error_message_size) noexcept;
_In_reads_(handle_map_count) original_fd_handle_map_t* handle_map,
uint32_t instruction_count,
_In_reads_(instruction_count) ebpf_inst* instructions,
_Outptr_result_maybenull_z_ const char** error_message,
_Out_ uint32_t* error_message_size) noexcept;
uint32_t
ebpf_service_initialize() noexcept;

Просмотреть файл

@ -44,14 +44,13 @@ _analyze(raw_program& raw_prog, const char** error_message, uint32_t* error_mess
ebpf_result_t
verify_byte_code(
const GUID* program_type,
const uint8_t* byte_code,
size_t byte_code_size,
const char** error_message,
uint32_t* error_message_size)
_In_reads_(instruction_count) const ebpf_inst* instruction_array,
uint32_t instruction_count,
_Outptr_result_maybenull_z_ const char** error_message,
_Out_ uint32_t* error_message_size)
{
const ebpf_platform_t* platform = &g_ebpf_platform_windows_service;
std::vector<ebpf_inst> instructions{
(ebpf_inst*)byte_code, (ebpf_inst*)byte_code + byte_code_size / sizeof(ebpf_inst)};
std::vector<ebpf_inst> instructions{instruction_array, instruction_array + instruction_count};
program_info info{platform};
std::string section;
std::string file;

Просмотреть файл

@ -8,8 +8,8 @@
ebpf_result_t
verify_byte_code(
const GUID* program_type,
const uint8_t* byte_code,
size_t byte_code_size,
const char** error_message,
uint32_t* error_message_size);
_In_ const GUID* program_type,
_In_reads_(instruction_count) const ebpf_inst* instructions,
uint32_t instruction_count,
_Outptr_result_maybenull_z_ const char** error_message,
_Out_ uint32_t* error_message_size);

Просмотреть файл

@ -204,8 +204,8 @@ ebpf_rpc_load_program(ebpf_program_load_info* info, const char** logs, uint32_t*
info->execution_type,
info->map_count,
info->handle_map,
info->byte_code_size,
info->byte_code,
info->instruction_count,
reinterpret_cast<ebpf_inst*>(info->instructions),
const_cast<const char**>(logs),
logs_size);

Просмотреть файл

@ -30,6 +30,16 @@ import "wtypes.idl";
file_handle_t handle;
} original_fd_handle_map_t;
// We can't use struct ebpf_inst since MIDL doesn't support
// bitfields, so define a structure here that doesn't use bitfields.
typedef struct _ebpf_instruction
{
uint8_t opcode;
uint8_t dst_src; //< Registers.
int16_t offset;
int32_t imm; //< Immediate constant
} ebpf_instruction_t;
typedef struct _ebpf_program_load_info
{
// Object name.
@ -44,8 +54,8 @@ import "wtypes.idl";
ebpf_execution_context_t execution_context;
uint32_t map_count;
[size_is(map_count)] original_fd_handle_map_t* handle_map;
uint32_t byte_code_size;
[ size_is(byte_code_size), ref ] uint8_t* byte_code;
uint32_t instruction_count;
[ size_is(instruction_count), ref ] ebpf_instruction_t* instructions;
} ebpf_program_load_info;
ebpf_result_t verify_and_load_program(

Просмотреть файл

@ -342,7 +342,7 @@ ebpf_program_load(
if (error < 0) {
if (log_buffer) {
size_t log_buffer_size;
*log_buffer = bpf_program__log_buf(program, &log_buffer_size);
*log_buffer = _strdup(bpf_program__log_buf(program, &log_buffer_size));
}
bpf_object__close(new_object);
return error;
@ -373,6 +373,7 @@ droppacket_test(ebpf_execution_type_t execution_type)
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
fd_t dropped_packet_map_fd = bpf_object__find_map_fd_by_name(object, "dropped_packet_map");
@ -463,6 +464,7 @@ divide_by_zero_test_um(ebpf_execution_type_t execution_type)
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -555,6 +557,7 @@ bindmonitor_test(ebpf_execution_type_t execution_type)
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
fd_t limit_map_fd = bpf_object__find_map_fd_by_name(object, "limits_map");
@ -635,6 +638,7 @@ bindmonitor_tailcall_test(ebpf_execution_type_t execution_type)
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
fd_t limit_map_fd = bpf_object__find_map_fd_by_name(object, "limits_map");
@ -756,6 +760,7 @@ bindmonitor_ring_buffer_test(ebpf_execution_type_t execution_type)
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -835,6 +840,7 @@ map_test(ebpf_execution_type_t execution_type)
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -946,6 +952,7 @@ _cgroup_load_test(
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -1069,6 +1076,7 @@ TEST_CASE("map_pinning_test", "[end_to_end]")
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -1128,6 +1136,7 @@ TEST_CASE("enumerate_and_query_programs", "[end_to_end]")
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -1141,6 +1150,7 @@ TEST_CASE("enumerate_and_query_programs", "[end_to_end]")
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -1212,6 +1222,7 @@ TEST_CASE("implicit_detach", "[end_to_end]")
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -1256,6 +1267,7 @@ TEST_CASE("implicit_detach_2", "[end_to_end]")
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -1304,6 +1316,7 @@ TEST_CASE("explicit_detach", "[end_to_end]")
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -1350,6 +1363,7 @@ TEST_CASE("implicit_explicit_detach", "[end_to_end]")
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(result == 0);
@ -2137,6 +2151,7 @@ TEST_CASE("load_native_program_negative3", "[end-to-end]")
"droppacket_um.dll", BPF_PROG_TYPE_UNSPEC, EBPF_EXECUTION_NATIVE, &object, &program_fd, &error_message);
if (error_message) {
printf("ebpf_program_load failed with %s\n", error_message);
free((void*)error_message);
}
REQUIRE(error == 0);