Update driver to return ebpf_program_data_t to verifier (#163)

* Update driver to return ebpf_program_data_t to verifier

Signed-off-by: Alan Jowett <alanjo@microsoft.com>

* Fix typo in comment

Co-authored-by: Dave Thaler <dthaler@microsoft.com>
This commit is contained in:
Alan Jowett 2021-05-11 10:53:12 -06:00 коммит произвёл GitHub
Родитель fba10c87b3
Коммит bf6cb270ac
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
13 изменённых файлов: 525 добавлений и 76 удалений

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

@ -85,6 +85,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EbpfCore", "ebpfcore\EbpfCore.vcxproj", "{97E52ABB-2F1E-4AD2-AEFD-6EB7FDC0A41D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetEbpfExt", "netebpfext\netebpfext.vcxproj", "{55499E36-37D4-4F86-B694-9F2990315758}"
ProjectSection(ProjectDependencies) = postProject
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68} = {FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "service", "service", "{4B0B9AFE-78D9-48AF-9968-88D3BB83770F}"
EndProject
@ -94,6 +97,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "execution_context_unit_test
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "platform_unit_test", "libs\platform\unit\platform_unit_test.vcxproj", "{829ADF66-544A-44DC-82B0-998EEADFE39D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encode_program_information", "tools\encode_program_information\encode_program_information.vcxproj", "{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@ -770,6 +775,34 @@ Global
{829ADF66-544A-44DC-82B0-998EEADFE39D}.RelWithDebInfo|x64.Build.0 = Release|x64
{829ADF66-544A-44DC-82B0-998EEADFE39D}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
{829ADF66-544A-44DC-82B0-998EEADFE39D}.RelWithDebInfo|x86.Build.0 = Release|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Debug|ARM.ActiveCfg = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Debug|ARM64.ActiveCfg = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Debug|x64.ActiveCfg = Debug|x64
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Debug|x64.Build.0 = Debug|x64
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Debug|x86.ActiveCfg = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Debug|x86.Build.0 = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.MinSizeRel|ARM.ActiveCfg = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.MinSizeRel|ARM.Build.0 = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.MinSizeRel|ARM64.ActiveCfg = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.MinSizeRel|ARM64.Build.0 = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.MinSizeRel|x64.ActiveCfg = Debug|x64
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.MinSizeRel|x64.Build.0 = Debug|x64
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.MinSizeRel|x86.ActiveCfg = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.MinSizeRel|x86.Build.0 = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Release|ARM.ActiveCfg = Release|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Release|ARM64.ActiveCfg = Release|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Release|x64.ActiveCfg = Release|x64
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Release|x64.Build.0 = Release|x64
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Release|x86.ActiveCfg = Release|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.Release|x86.Build.0 = Release|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.RelWithDebInfo|ARM.ActiveCfg = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.RelWithDebInfo|ARM.Build.0 = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.RelWithDebInfo|ARM64.Build.0 = Debug|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.RelWithDebInfo|x64.Build.0 = Release|x64
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68}.RelWithDebInfo|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -798,6 +831,7 @@ Global
{BA065B6A-38F8-4197-8F66-87C84AFAD513} = {4B0B9AFE-78D9-48AF-9968-88D3BB83770F}
{8D7421F1-B2DC-4BEF-955C-D69B317E6268} = {492C9B22-9237-4996-9E33-CA14D3533616}
{829ADF66-544A-44DC-82B0-998EEADFE39D} = {492C9B22-9237-4996-9E33-CA14D3533616}
{FA9BB88D-8259-40C1-9422-BDEDF9E9CE68} = {B09749EC-3D14-414B-BA9B-CD20E218DC84}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3D5F862D-74C6-4357-9F95-0B152E33B7B8}

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

@ -131,6 +131,9 @@
<ProjectReference Include="..\libs\api\api.vcxproj">
<Project>{c8bf60c3-40a9-43ad-891a-8aa34f1c3a68}</Project>
</ProjectReference>
<ProjectReference Include="..\libs\platform\user\platform_user.vcxproj">
<Project>{c26cb6a9-158c-4a9e-a243-755ddd98e5fe}</Project>
</ProjectReference>
<ProjectReference Include="..\libs\ubpf\user\ubpf_user.vcxproj">
<Project>{245f0ec7-1ebc-4d68-8b1f-f758ea9196ae}</Project>
</ProjectReference>

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

@ -398,6 +398,7 @@ ebpf_api_load_program(
struct ubpf_vm* vm = nullptr;
uint64_t log_function_address;
ebpf_extension_data_t* program_information_data = NULL;
ebpf_program_information_t* program_information = NULL;
_unwind_helper unwind([&] {
if (vm) {
ubpf_destroy(vm);
@ -405,6 +406,7 @@ ebpf_api_load_program(
for (auto& map : _map_file_descriptors) {
ebpf_api_close_handle(reinterpret_cast<ebpf_handle_t>(map.handle));
}
ebpf_free(program_information);
free(program_information_data);
});
@ -422,12 +424,20 @@ ebpf_api_load_program(
return result;
}
// TODO (issue #67): Pass the resulting program information to the verifier.
result = _get_program_information_data(program_handle, &program_information_data);
if (result != ERROR_SUCCESS) {
return result;
}
// TODO (issue #67): Pass the resulting program information to the verifier.
result = ebpf_program_information_decode(
&program_information,
program_information_data->data,
program_information_data->size - EBPF_OFFSET_OF(ebpf_extension_data_t, data));
if (result != ERROR_SUCCESS) {
return result;
}
// Verify code.
if (verify_byte_code(file_name, section_name, byte_code.data(), byte_code_size, error_message) != 0) {
return ERROR_INVALID_PARAMETER;
@ -686,7 +696,8 @@ ebpf_api_get_next_map(ebpf_handle_t previous_handle, ebpf_handle_t* next_handle)
uint32_t
ebpf_api_get_next_program(ebpf_handle_t previous_handle, ebpf_handle_t* next_handle)
{
_ebpf_operation_get_next_program_request request{sizeof(request),
_ebpf_operation_get_next_program_request request{
sizeof(request),
ebpf_operation_id_t::EBPF_OPERATION_GET_NEXT_PROGRAM,
reinterpret_cast<uint64_t>(previous_handle)};

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

@ -128,13 +128,11 @@ TEST_CASE("program")
map.reset(local_map);
}
ebpf_program_type_t program_type;
ebpf_guid_create(&program_type);
const ebpf_utf8_string_t program_name{(uint8_t*)("foo"), 3};
const ebpf_utf8_string_t section_name{(uint8_t*)("bar"), 3};
program_information_provider_t program_information_provider(program_type);
program_information_provider_t program_information_provider(EBPF_PROGRAM_TYPE_BIND);
const ebpf_program_parameters_t program_parameters{program_type, program_name, section_name};
const ebpf_program_parameters_t program_parameters{EBPF_PROGRAM_TYPE_BIND, program_name, section_name};
ebpf_program_parameters_t returned_program_parameters{};
const ebpf_extension_data_t* program_information_data;

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

@ -30,24 +30,41 @@ ebpf_error_code_t
ebpf_program_information_decode(
ebpf_program_information_t** program_information, const uint8_t* buffer, unsigned long buffer_size)
{
ebpf_error_code_t return_value;
handle_t handle = NULL;
ebpf_program_information_pointer_t local_program_information = NULL;
uint8_t* local_buffer = NULL;
RPC_STATUS status = MesDecodeBufferHandleCreate((char*)buffer, buffer_size, &handle);
if (status != RPC_S_OK)
return EBPF_ERROR_OUT_OF_RESOURCES;
local_buffer = ebpf_allocate(buffer_size, EBPF_MEMORY_NO_EXECUTE);
if (!local_buffer) {
return_value = EBPF_ERROR_OUT_OF_RESOURCES;
goto Done;
}
memcpy(local_buffer, buffer, buffer_size);
RPC_STATUS status = MesDecodeBufferHandleCreate((char*)local_buffer, buffer_size, &handle);
if (status != RPC_S_OK) {
return_value = EBPF_ERROR_OUT_OF_RESOURCES;
goto Done;
}
RpcTryExcept { ebpf_program_information_pointer_t_Decode(handle, &local_program_information); }
RpcExcept(RpcExceptionFilter(RpcExceptionCode())) { status = RpcExceptionCode(); }
RpcEndExcept;
if (handle)
MesHandleFree(handle);
if (status != RPC_S_OK)
return EBPF_ERROR_INVALID_PARAMETER;
if (status != RPC_S_OK) {
return_value = EBPF_ERROR_INVALID_PARAMETER;
goto Done;
}
*program_information = local_program_information;
Done:
if (handle)
MesHandleFree(handle);
ebpf_free(local_buffer);
return EBPF_ERROR_SUCCESS;
}

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

@ -32,11 +32,17 @@ Environment:
#include <guiddef.h>
#include <netiodef.h>
#include <ntddk.h>
// ebpf_bind_program_data.h and ebpf_xdp_program_data.h are generated
// headers. encode_program_information generates them from the structs
// in ebpf_nethooks.h. This workaround exists due to the inability
// to call RPC serialization services from kernel mode. Once we switch
// to a different serializer, we can get rid of this workaround.
#include "ebpf_bind_program_data.h"
#include "ebpf_nethooks.h"
#include "ebpf_platform.h"
#include "ebpf_program_types.h"
#include "ebpf_windows.h"
#include "ebpf_xdp_program_data.h"
typedef struct _net_ebpf_ext_hook_provider_registration
{
@ -696,39 +702,26 @@ static ebpf_error_code_t
_net_ebpf_ext_program_information_encode_xdp()
{
ebpf_error_code_t return_value;
uint8_t* buffer = NULL;
unsigned long buffer_size = 0;
ebpf_context_descriptor_t xdp_context_descriptor = {
sizeof(xdp_md_t),
EBPF_OFFSET_OF(xdp_md_t, data),
EBPF_OFFSET_OF(xdp_md_t, data_end),
EBPF_OFFSET_OF(xdp_md_t, data_meta)};
ebpf_program_type_descriptor_t xdp_program_type = {"xdp", &xdp_context_descriptor};
ebpf_program_information_t xdp_program_information = {xdp_program_type, 0, NULL};
#if defined(MSRPC_LIB)
return_value = ebpf_program_information_encode(&xdp_program_information, &buffer, &buffer_size);
if (return_value != EBPF_ERROR_SUCCESS)
goto Done;
#else
UNREFERENCED_PARAMETER(xdp_program_information);
#endif
const uint8_t* buffer = _ebpf_encoded_xdp_program_information_data;
unsigned long buffer_size = sizeof(_ebpf_encoded_xdp_program_information_data);
_ebpf_xdp_program_information_provider_data = (ebpf_extension_data_t*)ebpf_allocate(
sizeof(EBPF_OFFSET_OF(ebpf_extension_data_t, data) + buffer_size), EBPF_MEMORY_NO_EXECUTE);
EBPF_OFFSET_OF(ebpf_extension_data_t, data) + buffer_size, EBPF_MEMORY_NO_EXECUTE);
if (_ebpf_xdp_program_information_provider_data == NULL) {
return_value = EBPF_ERROR_OUT_OF_RESOURCES;
goto Done;
}
_ebpf_xdp_program_information_provider_data->size =
(uint16_t)(EBPF_OFFSET_OF(ebpf_extension_data_t, data) + buffer_size);
_ebpf_xdp_program_information_provider_data->version = 0;
memcpy(_ebpf_xdp_program_information_provider_data->data, buffer, buffer_size);
return_value = EBPF_ERROR_SUCCESS;
Done:
ebpf_free(buffer);
return return_value;
}
@ -736,36 +729,25 @@ static ebpf_error_code_t
_net_ebpf_ext_program_information_encode_bind()
{
ebpf_error_code_t return_value;
uint8_t* buffer = NULL;
unsigned long buffer_size = 0;
ebpf_context_descriptor_t bind_context_descriptor = {
sizeof(bind_md_t), EBPF_OFFSET_OF(bind_md_t, app_id_start), EBPF_OFFSET_OF(bind_md_t, app_id_end), -1};
ebpf_program_type_descriptor_t bind_program_type = {"bind", &bind_context_descriptor};
ebpf_program_information_t bind_program_information = {bind_program_type, 0, NULL};
#if defined(MSRPC_LIB)
return_value = ebpf_program_information_encode(&bind_program_information, &buffer, &buffer_size);
if (return_value != EBPF_ERROR_SUCCESS)
goto Done;
#else
UNREFERENCED_PARAMETER(bind_program_information);
#endif
const uint8_t* buffer = _ebpf_encoded_bind_program_information_data;
unsigned long buffer_size = sizeof(_ebpf_encoded_bind_program_information_data);
_ebpf_bind_program_information_provider_data = (ebpf_extension_data_t*)ebpf_allocate(
sizeof(EBPF_OFFSET_OF(ebpf_extension_data_t, data) + buffer_size), EBPF_MEMORY_NO_EXECUTE);
EBPF_OFFSET_OF(ebpf_extension_data_t, data) + buffer_size, EBPF_MEMORY_NO_EXECUTE);
if (_ebpf_bind_program_information_provider_data == NULL) {
return_value = EBPF_ERROR_OUT_OF_RESOURCES;
goto Done;
}
_ebpf_bind_program_information_provider_data->size =
(uint16_t)(EBPF_OFFSET_OF(ebpf_extension_data_t, data) + buffer_size);
_ebpf_bind_program_information_provider_data->version = 0;
memcpy(_ebpf_bind_program_information_provider_data->data, buffer, buffer_size);
return_value = EBPF_ERROR_SUCCESS;
Done:
ebpf_free(buffer);
return return_value;
}

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

@ -87,7 +87,7 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);BINARY_COMPATIBLE=0;NT;UNICODE;_UNICODE;NDIS60;POOL_NX_OPTIN_AUTO</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\kernel</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\kernel;$(OutputPath)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);BINARY_COMPATIBLE=0;NT;UNICODE;_UNICODE;NDIS60;POOL_NX_OPTIN_AUTO</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
@ -106,7 +106,7 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);BINARY_COMPATIBLE=0;NT;UNICODE;_UNICODE;NDIS60;POOL_NX_OPTIN_AUTO</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\kernel</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\kernel;$(OutputPath)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);BINARY_COMPATIBLE=0;NT;UNICODE;_UNICODE;NDIS60;POOL_NX_OPTIN_AUTO</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>

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

@ -12,7 +12,9 @@
#include "catch2\catch.hpp"
#include "ebpf_api.h"
#include "ebpf_bind_program_data.h"
#include "ebpf_core.h"
#include "ebpf_xdp_program_data.h"
#include "helpers.h"
#include "mock.h"
#include "tlv.h"
@ -202,7 +204,7 @@ TEST_CASE("droppacket-jit", "[droppacket_jit]")
ERROR_SUCCESS);
// Test that we drop the packet and increment the map
ebpf::xdp_md_t ctx{packet.data(), packet.data() + packet.size()};
xdp_md_t ctx{packet.data(), packet.data() + packet.size()};
REQUIRE(hook.fire(&ctx, &result) == EBPF_ERROR_SUCCESS);
REQUIRE(result == 2);
@ -220,7 +222,7 @@ TEST_CASE("droppacket-jit", "[droppacket_jit]")
REQUIRE(value == 0);
packet = prepare_udp_packet(10);
ebpf::xdp_md_t ctx2{packet.data(), packet.data() + packet.size()};
xdp_md_t ctx2{packet.data(), packet.data() + packet.size()};
REQUIRE(hook.fire(&ctx2, &result) == EBPF_ERROR_SUCCESS);
REQUIRE(result == 1);
@ -285,7 +287,7 @@ TEST_CASE("droppacket-interpret", "[droppacket_interpret]")
ERROR_SUCCESS);
// Test that we drop the packet and increment the map
ebpf::xdp_md_t ctx{packet.data(), packet.data() + packet.size()};
xdp_md_t ctx{packet.data(), packet.data() + packet.size()};
REQUIRE(hook.fire(&ctx, &result) == EBPF_ERROR_SUCCESS);
REQUIRE(result == 2);
@ -302,7 +304,7 @@ TEST_CASE("droppacket-interpret", "[droppacket_interpret]")
REQUIRE(value == 0);
packet = prepare_udp_packet(10);
ebpf::xdp_md_t ctx2{packet.data(), packet.data() + packet.size()};
xdp_md_t ctx2{packet.data(), packet.data() + packet.size()};
REQUIRE(hook.fire(&ctx2, &result) == EBPF_ERROR_SUCCESS);
REQUIRE(result == 1);
@ -360,7 +362,7 @@ TEST_CASE("divide_by_zero_jit", "[divide_by_zero_jit]")
auto packet = prepare_udp_packet(0);
// Test that we drop the packet and increment the map
ebpf::xdp_md_t ctx{packet.data(), packet.data() + packet.size()};
xdp_md_t ctx{packet.data(), packet.data() + packet.size()};
REQUIRE(hook.fire(&ctx, &result) == EBPF_ERROR_SUCCESS);
REQUIRE(result == -1);
@ -456,18 +458,18 @@ get_bind_count_for_pid(ebpf_handle_t handle, uint64_t pid)
return entry.count;
}
ebpf::bind_action_t
bind_action_t
emulate_bind(single_instance_hook_t& hook, uint64_t pid, const char* appid)
{
uint32_t result;
std::string app_id = appid;
ebpf::bind_md_t ctx{0};
bind_md_t ctx{0};
ctx.app_id_start = (uint8_t*)app_id.c_str();
ctx.app_id_end = (uint8_t*)(app_id.c_str()) + app_id.size();
ctx.process_id = pid;
ctx.operation = ebpf::BIND_OPERATION_BIND;
ctx.operation = BIND_OPERATION_BIND;
REQUIRE(hook.fire(&ctx, &result) == EBPF_ERROR_SUCCESS);
return static_cast<ebpf::bind_action_t>(result);
return static_cast<bind_action_t>(result);
}
void
@ -475,9 +477,9 @@ emulate_unbind(single_instance_hook_t& hook, uint64_t pid, const char* appid)
{
uint32_t result;
std::string app_id = appid;
ebpf::bind_md_t ctx{0};
bind_md_t ctx{0};
ctx.process_id = pid;
ctx.operation = ebpf::BIND_OPERATION_UNBIND;
ctx.operation = BIND_OPERATION_UNBIND;
REQUIRE(hook.fire(&ctx, &result) == EBPF_ERROR_SUCCESS);
}
@ -590,15 +592,15 @@ TEST_CASE("bindmonitor-interpret", "[bindmonitor_interpret]")
set_bind_limit(map_handles[1], 2);
// Bind first port - success
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_1") == ebpf::BIND_PERMIT);
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_1") == BIND_PERMIT);
REQUIRE(get_bind_count_for_pid(map_handles[0], fake_pid) == 1);
// Bind second port - success
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_1") == ebpf::BIND_PERMIT);
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_1") == BIND_PERMIT);
REQUIRE(get_bind_count_for_pid(map_handles[0], fake_pid) == 2);
// Bind third port - blocked
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_1") == ebpf::BIND_DENY);
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_1") == BIND_DENY);
REQUIRE(get_bind_count_for_pid(map_handles[0], fake_pid) == 2);
// Unbind second port
@ -610,11 +612,11 @@ TEST_CASE("bindmonitor-interpret", "[bindmonitor_interpret]")
REQUIRE(get_bind_count_for_pid(map_handles[0], fake_pid) == 0);
// Bind from two apps to test enumeration
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_1") == ebpf::BIND_PERMIT);
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_1") == BIND_PERMIT);
REQUIRE(get_bind_count_for_pid(map_handles[0], fake_pid) == 1);
fake_pid = 54321;
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_2") == ebpf::BIND_PERMIT);
REQUIRE(emulate_bind(hook, fake_pid, "fake_app_2") == BIND_PERMIT);
REQUIRE(get_bind_count_for_pid(map_handles[0], fake_pid) == 1);
uint64_t pid;

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

@ -80,7 +80,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\api;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@ -98,7 +98,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\api;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>

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

@ -5,7 +5,20 @@
#pragma once
#include "ebpf_api.h"
#include "ebpf_link.h"
#include "ebpf_nethooks.h"
#include "ebpf_platform.h"
#include "ebpf_program_types.h"
typedef struct _ebpf_free_memory
{
void
operator()(uint8_t* memory)
{
ebpf_free(memory);
}
} ebpf_free_memory_t;
typedef std::unique_ptr<uint8_t, ebpf_free_memory_t> ebpf_memory_t;
typedef class _single_instance_hook
{
@ -91,15 +104,99 @@ typedef class _program_information_provider
public:
_program_information_provider(ebpf_program_type_t program_type) : program_type(program_type)
{
if (program_type == EBPF_PROGRAM_TYPE_XDP)
encode_xdp();
else if (program_type == EBPF_PROGRAM_TYPE_BIND)
encode_bind();
REQUIRE(
ebpf_provider_load(&provider, &program_type, nullptr, &provider_data, nullptr, nullptr, nullptr, nullptr) ==
EBPF_ERROR_SUCCESS);
ebpf_provider_load(
&provider,
&program_type,
nullptr,
reinterpret_cast<ebpf_extension_data_t*>(provider_data.data()),
nullptr,
nullptr,
nullptr,
nullptr) == EBPF_ERROR_SUCCESS);
}
~_program_information_provider() { ebpf_provider_unload(provider); }
private:
void
encode_bind()
{
ebpf_helper_function_prototype_t helper_functions[] = {
{1,
"ebpf_map_lookup_element",
EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL,
{EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}},
{2,
"ebpf_map_update_element",
EBPF_RETURN_TYPE_INTEGER,
{EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE}},
{3,
"ebpf_map_delete_element",
EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL,
{EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}},
};
ebpf_context_descriptor_t context_descriptor{
sizeof(bind_md_t), EBPF_OFFSET_OF(bind_md_t, app_id_start), EBPF_OFFSET_OF(bind_md_t, app_id_end), -1};
ebpf_program_type_descriptor_t program_type_descriptor{"bind", &context_descriptor};
ebpf_program_information_t program_information{
program_type_descriptor, _countof(helper_functions), helper_functions};
uint8_t* buffer;
unsigned long buffer_size;
REQUIRE(ebpf_program_information_encode(&program_information, &buffer, &buffer_size) == EBPF_ERROR_SUCCESS);
// Capture the buffer so that it's freed on scope exit.
ebpf_memory_t memory(buffer);
provider_data.resize(EBPF_OFFSET_OF(ebpf_extension_data_t, data) + buffer_size);
ebpf_extension_data_t* extension_data = reinterpret_cast<ebpf_extension_data_t*>(provider_data.data());
extension_data->size = static_cast<uint16_t>(provider_data.size());
extension_data->version = 0;
memcpy(extension_data->data, buffer, buffer_size);
}
void
encode_xdp()
{
ebpf_helper_function_prototype_t helper_functions[] = {
{1,
"ebpf_map_lookup_element",
EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL,
{EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}},
{2,
"ebpf_map_update_element",
EBPF_RETURN_TYPE_INTEGER,
{EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE}},
{3,
"ebpf_map_delete_element",
EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL,
{EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}},
};
ebpf_context_descriptor_t context_descriptor{
sizeof(xdp_md_t),
EBPF_OFFSET_OF(xdp_md_t, data),
EBPF_OFFSET_OF(xdp_md_t, data_end),
EBPF_OFFSET_OF(xdp_md_t, data_meta)};
ebpf_program_type_descriptor_t program_type_descriptor{"xdp", &context_descriptor};
ebpf_program_information_t program_information{
program_type_descriptor, _countof(helper_functions), helper_functions};
uint8_t* buffer;
unsigned long buffer_size;
REQUIRE(ebpf_program_information_encode(&program_information, &buffer, &buffer_size) == EBPF_ERROR_SUCCESS);
// Capture the buffer so that it's freed on scope exit.
ebpf_memory_t memory(buffer);
provider_data.resize(EBPF_OFFSET_OF(ebpf_extension_data_t, data) + buffer_size);
ebpf_extension_data_t* extension_data = reinterpret_cast<ebpf_extension_data_t*>(provider_data.data());
extension_data->size = static_cast<uint16_t>(provider_data.size());
extension_data->version = 0;
memcpy(extension_data->data, buffer, buffer_size);
}
ebpf_program_type_t program_type;
ebpf_extension_data_t provider_data = {0, 0};
std::vector<uint8_t> provider_data;
ebpf_extension_provider_t* provider;
} program_information_provider_t;

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

@ -0,0 +1,99 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
#include <stdio.h>
#include "ebpf_nethooks.h"
#include "ebpf_platform.h"
#include "ebpf_program_types.h"
#include "ebpf_windows.h"
static ebpf_error_code_t
_emit_program_information_file(
const char* file_name, const char* symbol_name, uint8_t* buffer, unsigned long buffer_size)
{
unsigned long index;
FILE* output;
if (fopen_s(&output, file_name, "w") != 0)
return EBPF_ERROR_OUT_OF_RESOURCES;
fprintf(output, "#pragma once\n");
fprintf(output, "#include <stdint.h>\n");
fprintf(output, "static const uint8_t %s[] = {", symbol_name);
for (index = 0; index < buffer_size; index++) {
if (index % 16 == 0)
fprintf(output, "\n");
fprintf(output, "0x%.2X, ", buffer[index]);
}
fprintf(output, "};");
fflush(output);
fclose(output);
return EBPF_ERROR_SUCCESS;
}
static ebpf_error_code_t
_encode_bind()
{
ebpf_error_code_t return_value;
uint8_t* buffer = NULL;
unsigned long buffer_size = 0;
ebpf_context_descriptor_t bind_context_descriptor = {
sizeof(bind_md_t), EBPF_OFFSET_OF(bind_md_t, app_id_start), EBPF_OFFSET_OF(bind_md_t, app_id_end), -1};
ebpf_program_type_descriptor_t bind_program_type = {"bind", &bind_context_descriptor};
ebpf_program_information_t bind_program_information = {bind_program_type, 0, NULL};
return_value = ebpf_program_information_encode(&bind_program_information, &buffer, &buffer_size);
if (return_value != EBPF_ERROR_SUCCESS)
goto Done;
return_value = _emit_program_information_file(
"ebpf_bind_program_data.h", "_ebpf_encoded_bind_program_information_data", buffer, buffer_size);
if (return_value != EBPF_ERROR_SUCCESS)
goto Done;
return_value = EBPF_ERROR_SUCCESS;
Done:
ebpf_free(buffer);
return return_value;
}
static ebpf_error_code_t
_encode_xdp()
{
ebpf_error_code_t return_value;
uint8_t* buffer = NULL;
unsigned long buffer_size = 0;
ebpf_context_descriptor_t xdp_context_descriptor = {
sizeof(xdp_md_t),
EBPF_OFFSET_OF(xdp_md_t, data),
EBPF_OFFSET_OF(xdp_md_t, data_end),
EBPF_OFFSET_OF(xdp_md_t, data_meta)};
ebpf_program_type_descriptor_t xdp_program_type = {"xdp", &xdp_context_descriptor};
ebpf_program_information_t xdp_program_information = {xdp_program_type, 0, NULL};
return_value = ebpf_program_information_encode(&xdp_program_information, &buffer, &buffer_size);
if (return_value != EBPF_ERROR_SUCCESS)
goto Done;
return_value = _emit_program_information_file(
"ebpf_xdp_program_data.h", "_ebpf_encoded_xdp_program_information_data", buffer, buffer_size);
if (return_value != EBPF_ERROR_SUCCESS)
goto Done;
return_value = EBPF_ERROR_SUCCESS;
Done:
ebpf_free(buffer);
return return_value;
}
int
main()
{
if (_encode_xdp() != EBPF_ERROR_SUCCESS || _encode_bind() != EBPF_ERROR_SUCCESS)
return 1;
return 0;
}

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

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: MIT
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{fa9bb88d-8259-40c1-9422-bdedf9e9ce68}</ProjectGuid>
<RootNamespace>encodeprograminformation</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<CustomBuildAfterTargets>Link</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>Link</CustomBuildAfterTargets>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\api</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<CustomBuildStep>
<Command>cd /d $(OutputPath)
$(OutputPath)\encode_program_information.exe</Command>
</CustomBuildStep>
<CustomBuildStep>
<Message>Encoding Program Information</Message>
</CustomBuildStep>
<CustomBuildStep>
<Outputs>$(OutputPath)ebpf_bind_program_data.h;$(OutputPath)ebpf_xdp_program_data.h;%(Outputs)</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\api</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<CustomBuildStep>
<Command>cd /d $(OutputPath)
$(OutputPath)\encode_program_information.exe</Command>
</CustomBuildStep>
<CustomBuildStep>
<Message>Encoding Program Information</Message>
</CustomBuildStep>
<CustomBuildStep>
<Outputs>$(OutputPath)ebpf_bind_program_data.h;$(OutputPath)ebpf_xdp_program_data.h;%(Outputs)</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="encode_program_information.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libs\platform\user\platform_user.vcxproj">
<Project>{c26cb6a9-158c-4a9e-a243-755ddd98e5fe}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

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

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: MIT
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="encode_program_information.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>