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:
Родитель
709ee13c12
Коммит
ee166b5717
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче