Merged PR 4256572: Update ebpf to use minimally changed ubpf
Update ebpf to use minimally changed ubpf 1) Revert change in ubpf to support dynamic map and helper resolution -> pre-resolve all maps and helpers. 2) Remove jitter code from kernel ubpf lib
This commit is contained in:
Родитель
b431246e5d
Коммит
b35a157c6b
|
@ -1 +1 @@
|
|||
Subproject commit c51ac5c3bc5273ec4b10d9db945326b35d44ec25
|
||||
Subproject commit 6c313139f7c722673f4fec4e62fe4d9567baec6c
|
|
@ -170,43 +170,12 @@ get_map_descriptor_internal(int map_fd)
|
|||
return get_map_cache_entry(map_fd).ebpf_map_descriptor;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
map_resolver(void* context, uint64_t fd)
|
||||
{
|
||||
_ebpf_operation_resolve_map_request request{
|
||||
sizeof(request), ebpf_operation_id_t::EBPF_OPERATION_RESOLVE_MAP, get_map_cache_entry(fd).handle};
|
||||
|
||||
_ebpf_operation_resolve_map_reply reply;
|
||||
|
||||
invoke_ioctl(context, request, reply);
|
||||
|
||||
if (reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_RESOLVE_MAP) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return reply.address[0];
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
helper_resolver(void* context, uint32_t helper)
|
||||
{
|
||||
_ebpf_operation_resolve_helper_request request{
|
||||
sizeof(request), ebpf_operation_id_t::EBPF_OPERATION_RESOLVE_HELPER, helper};
|
||||
|
||||
_ebpf_operation_resolve_map_reply reply;
|
||||
|
||||
invoke_ioctl(context, request, reply);
|
||||
|
||||
if (reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_RESOLVE_HELPER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return reply.address[0];
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
resolve_maps_in_byte_code(std::vector<uint8_t>& byte_code)
|
||||
{
|
||||
std::vector<size_t> instruction_offsets;
|
||||
std::vector<uint64_t> map_handles;
|
||||
|
||||
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++) {
|
||||
|
@ -225,22 +194,89 @@ resolve_maps_in_byte_code(std::vector<uint8_t>& byte_code)
|
|||
continue;
|
||||
}
|
||||
|
||||
uint64_t imm =
|
||||
static_cast<uint64_t>(first_instruction.imm) | (static_cast<uint64_t>(second_instruction.imm) << 32);
|
||||
instruction_offsets.push_back(index - 1);
|
||||
map_handles.push_back(imm);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> request_buffer(
|
||||
offsetof(ebpf_operation_resolve_map_request_t, map_handle) + sizeof(uint64_t) * map_handles.size());
|
||||
|
||||
std::vector<uint8_t> reply_buffer(
|
||||
offsetof(ebpf_operation_resolve_map_reply_t, address) + sizeof(uint64_t) * map_handles.size());
|
||||
|
||||
auto request = reinterpret_cast<ebpf_operation_resolve_map_request_t*>(request_buffer.data());
|
||||
auto reply = reinterpret_cast<ebpf_operation_resolve_map_reply_t*>(reply_buffer.data());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_RESOLVE_MAP;
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
|
||||
for (size_t index = 0; index < map_handles.size(); index++) {
|
||||
request->map_handle[index] = map_handles[index];
|
||||
}
|
||||
|
||||
uint32_t result = invoke_ioctl(device_handle, request_buffer, reply_buffer);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < map_handles.size(); index++) {
|
||||
ebpf_inst& first_instruction = instructions[instruction_offsets[index]];
|
||||
ebpf_inst& second_instruction = instructions[instruction_offsets[index] + 1];
|
||||
|
||||
// Clear LD_MAP flag
|
||||
first_instruction.src = 0;
|
||||
|
||||
// Resolve FD -> map address.
|
||||
uint64_t imm =
|
||||
static_cast<uint64_t>(first_instruction.imm) | (static_cast<uint64_t>(second_instruction.imm) << 32);
|
||||
uint64_t new_imm = map_resolver(device_handle, imm);
|
||||
if (new_imm == 0) {
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
// Replace handle with address
|
||||
uint64_t new_imm = reply->address[index];
|
||||
first_instruction.imm = static_cast<uint32_t>(new_imm);
|
||||
second_instruction.imm = static_cast<uint32_t>(new_imm >> 32);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
build_helper_id_to_address_map(std::vector<uint8_t>& byte_code, std::map<uint32_t, uint64_t>& helper_id_to_adddress)
|
||||
{
|
||||
ebpf_inst* instructions = reinterpret_cast<ebpf_inst*>(byte_code.data());
|
||||
for (size_t index = 0; index < byte_code.size() / sizeof(ebpf_inst); index++) {
|
||||
ebpf_inst& instruction = instructions[index];
|
||||
if (instruction.opcode != INST_OP_CALL) {
|
||||
continue;
|
||||
}
|
||||
helper_id_to_adddress[instruction.imm] = 0;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> request_buffer(
|
||||
offsetof(ebpf_operation_resolve_helper_request_t, helper_id) + sizeof(uint32_t) * helper_id_to_adddress.size());
|
||||
|
||||
std::vector<uint8_t> reply_buffer(
|
||||
offsetof(ebpf_operation_resolve_helper_reply_t, address) + sizeof(uint64_t) * helper_id_to_adddress.size());
|
||||
|
||||
auto request = reinterpret_cast<ebpf_operation_resolve_helper_request_t*>(request_buffer.data());
|
||||
auto reply = reinterpret_cast<ebpf_operation_resolve_helper_reply_t*>(reply_buffer.data());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_RESOLVE_HELPER;
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
|
||||
size_t index = 0;
|
||||
for (const auto& helper : helper_id_to_adddress) {
|
||||
request->helper_id[index++] = helper.first;
|
||||
}
|
||||
|
||||
uint32_t result = invoke_ioctl(device_handle, request_buffer, reply_buffer);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
for (auto& helper : helper_id_to_adddress) {
|
||||
helper.second = reply->address[index++];
|
||||
}
|
||||
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ebpf_api_load_program(
|
||||
const char* file_name,
|
||||
|
@ -306,6 +342,12 @@ ebpf_api_load_program(
|
|||
std::copy(section_name, section_name + section_name_bytes.size(), section_name_bytes.begin());
|
||||
|
||||
if (execution_type == EBPF_EXECUTION_JIT) {
|
||||
std::map<uint32_t, uint64_t> helper_id_to_adddress;
|
||||
result = build_helper_id_to_address_map(byte_code, helper_id_to_adddress);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> machine_code(MAX_CODE_SIZE);
|
||||
size_t machine_code_size = machine_code.size();
|
||||
|
||||
|
@ -315,8 +357,10 @@ ebpf_api_load_program(
|
|||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (ubpf_register_helper_resolver(vm, device_handle, helper_resolver) < 0) {
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
for (const auto& helper : helper_id_to_adddress) {
|
||||
if (ubpf_register(vm, helper.first, nullptr, reinterpret_cast<void*>(helper.second)) < 0) {
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
if (ubpf_load(
|
||||
|
@ -642,5 +686,6 @@ ebpf_api_program_query_information(
|
|||
void
|
||||
ebpf_api_delete_map(ebpf_handle_t handle)
|
||||
{
|
||||
CloseHandle(handle);
|
||||
UNREFERENCED_PARAMETER(handle);
|
||||
// TODO: Call close handle once the switch to using OB handles
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <exception>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
|
|
|
@ -362,6 +362,20 @@ ebpf_core_protocol_unload_code(_In_ const struct _ebpf_operation_unload_code_req
|
|||
return _ebpf_core_delete_code_entry(request->handle);
|
||||
}
|
||||
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_register_helpers(struct ubpf_vm* vm)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
for (index = 0; index < RTL_COUNT_OF(_ebpf_program_helpers); index++) {
|
||||
if (_ebpf_program_helpers[index] == NULL)
|
||||
continue;
|
||||
|
||||
if (ubpf_register(vm, index, NULL, (void*)_ebpf_program_helpers[index]) < 0)
|
||||
return EBPF_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_load_code(
|
||||
_In_ const ebpf_operation_load_code_request_t* request,
|
||||
|
@ -447,7 +461,11 @@ ebpf_core_protocol_load_code(
|
|||
// failing.
|
||||
toggle_bounds_check(code_entry->code_or_vm.vm, false);
|
||||
|
||||
ubpf_register_helper_resolver(code_entry->code_or_vm.vm, code_entry, ebpf_core_interpreter_helper_resolver);
|
||||
retval = ebpf_core_register_helpers(code_entry->code_or_vm.vm);
|
||||
if (retval != EBPF_ERROR_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (ubpf_load(code_entry->code_or_vm.vm, code, (uint32_t)code_length, &error_message) != 0) {
|
||||
ebpf_free(error_message);
|
||||
retval = EBPF_ERROR_INVALID_PARAMETER;
|
||||
|
@ -474,12 +492,24 @@ ebpf_core_protocol_resolve_helper(
|
|||
_Inout_ struct _ebpf_operation_resolve_helper_reply* reply,
|
||||
uint16_t reply_length)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(reply_length);
|
||||
size_t count_of_helpers =
|
||||
(request->header.length - RTL_OFFSET_OF(ebpf_operation_resolve_helper_request_t, helper_id)) /
|
||||
sizeof(request->helper_id[0]);
|
||||
size_t required_reply_length =
|
||||
RTL_OFFSET_OF(ebpf_operation_resolve_helper_reply_t, address) + count_of_helpers * sizeof(reply->address[0]);
|
||||
size_t helper_index;
|
||||
|
||||
if (request->helper_id[0] >= RTL_COUNT_OF(_ebpf_program_helpers)) {
|
||||
if (reply_length < required_reply_length) {
|
||||
return EBPF_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
reply->address[0] = (uint64_t)_ebpf_program_helpers[request->helper_id[0]];
|
||||
|
||||
for (helper_index = 0; helper_index < count_of_helpers; helper_index++) {
|
||||
if (request->helper_id[helper_index] >= RTL_COUNT_OF(_ebpf_program_helpers)) {
|
||||
return EBPF_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
reply->address[helper_index] = (uint64_t)_ebpf_program_helpers[request->helper_id[helper_index]];
|
||||
}
|
||||
reply->header.length = (uint16_t)required_reply_length;
|
||||
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -490,16 +520,26 @@ ebpf_core_protocol_resolve_map(
|
|||
_Inout_ struct _ebpf_operation_resolve_map_reply* reply,
|
||||
uint16_t reply_length)
|
||||
{
|
||||
size_t count_of_maps = (request->header.length - RTL_OFFSET_OF(ebpf_operation_resolve_map_request_t, map_handle)) /
|
||||
sizeof(request->map_handle[0]);
|
||||
size_t required_reply_length =
|
||||
RTL_OFFSET_OF(ebpf_operation_resolve_map_reply_t, address) + count_of_maps * sizeof(reply->address[0]);
|
||||
size_t map_index;
|
||||
ebpf_core_map_t* map;
|
||||
UNREFERENCED_PARAMETER(reply_length);
|
||||
|
||||
map = _ebpf_core_find_map_entry(request->map_handle[0]);
|
||||
if (map) {
|
||||
reply->address[0] = (uint64_t)map;
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
} else {
|
||||
return EBPF_ERROR_INVALID_HANDLE;
|
||||
if (reply_length < required_reply_length) {
|
||||
return EBPF_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
for (map_index = 0; map_index < count_of_maps; map_index++) {
|
||||
map = _ebpf_core_find_map_entry(request->map_handle[map_index]);
|
||||
if (!map) {
|
||||
return EBPF_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
reply->address[map_index] = (uint64_t)map;
|
||||
}
|
||||
reply->header.length = (uint16_t)required_reply_length;
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
|
|
|
@ -18,10 +18,8 @@
|
|||
<ClInclude Include="..\..\..\..\..\external\ubpf\vm\ebpf.h" />
|
||||
<ClInclude Include="..\..\..\..\..\external\ubpf\vm\platform.h" />
|
||||
<ClInclude Include="..\..\..\..\..\external\ubpf\vm\ubpf_int.h" />
|
||||
<ClInclude Include="..\..\..\..\..\external\ubpf\vm\ubpf_jit_x86_64.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\..\external\ubpf\vm\ubpf_jit_x86_64.c" />
|
||||
<ClCompile Include="..\..\..\..\..\external\ubpf\vm\ubpf_vm.c" />
|
||||
<ClCompile Include="platform.c" />
|
||||
</ItemGroup>
|
||||
|
@ -68,7 +66,7 @@
|
|||
<ClCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\external\ubpf\vm;$(SolutionDir)\external\ubpf\vm\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\external\ubpf\vm;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\src\ebpf\libs\ubpf\kernel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
|
@ -76,7 +74,7 @@
|
|||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\external\ubpf\vm;$(SolutionDir)\external\ubpf\vm\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\external\ubpf\vm;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\src\ebpf\libs\ubpf\kernel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
|
|
|
@ -25,17 +25,11 @@
|
|||
<ClInclude Include="..\..\..\..\..\external\ubpf\vm\ubpf_int.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\..\external\ubpf\vm\ubpf_jit_x86_64.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\..\external\ubpf\vm\platform.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\..\external\ubpf\vm\ubpf_jit_x86_64.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\..\external\ubpf\vm\ubpf_vm.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -8,16 +8,10 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
void*
|
||||
ubpf_alloc(size_t size, size_t count)
|
||||
{
|
||||
return calloc(size, count);
|
||||
}
|
||||
ubpf_alloc(size_t size, size_t count);
|
||||
|
||||
void
|
||||
ubpf_free(void* memory)
|
||||
{
|
||||
free(memory);
|
||||
}
|
||||
ubpf_free(void* memory);
|
||||
|
||||
int
|
||||
vasprintf(char** target, const char* format, va_list argptr)
|
||||
|
|
|
@ -123,6 +123,7 @@
|
|||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
Загрузка…
Ссылка в новой задаче