Add epoch logic to handle run down of map entries. (#43)
* Add epoch logic to handle run down of map entries. Integrate with execution context to invoke epoch_enter/epoch_exit on entry/exit of execution context. Resolve: #24 Signed-off-by: Alan Jowett <alanjo@microsoft.com> Co-authored-by: Dave Thaler <dthaler@microsoft.com>
This commit is contained in:
Родитель
b115fce38d
Коммит
a57bfb30d4
|
@ -91,6 +91,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "maps_user", "src\ebpf\libs\
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "maps_kernel", "src\ebpf\libs\maps\kernel\maps_kernel.vcxproj", "{08B41A2E-3AA3-49C4-A525-D45B902D9DB0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "epoch_user", "src\ebpf\libs\epoch\user\epoch_user.vcxproj", "{A7E21439-B561-43F0-9DDD-237425F42BCD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "epoch_kernel", "src\ebpf\libs\epoch\kernel\epoch_kernel.vcxproj", "{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
|
@ -735,6 +739,82 @@ Global
|
|||
{08B41A2E-3AA3-49C4-A525-D45B902D9DB0}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
|
||||
{08B41A2E-3AA3-49C4-A525-D45B902D9DB0}.RelWithDebInfo|x86.Build.0 = Release|Win32
|
||||
{08B41A2E-3AA3-49C4-A525-D45B902D9DB0}.RelWithDebInfo|x86.Deploy.0 = Release|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Debug|ARM64.ActiveCfg = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Debug|x64.Build.0 = Debug|x64
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.MinSizeRel|ARM.ActiveCfg = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.MinSizeRel|ARM.Build.0 = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.MinSizeRel|ARM64.ActiveCfg = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.MinSizeRel|ARM64.Build.0 = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.MinSizeRel|x64.ActiveCfg = Debug|x64
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.MinSizeRel|x64.Build.0 = Debug|x64
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.MinSizeRel|x86.ActiveCfg = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.MinSizeRel|x86.Build.0 = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Release|ARM64.ActiveCfg = Release|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Release|x64.ActiveCfg = Release|x64
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Release|x64.Build.0 = Release|x64
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.Release|x86.Build.0 = Release|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.RelWithDebInfo|ARM.ActiveCfg = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.RelWithDebInfo|ARM.Build.0 = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.RelWithDebInfo|ARM64.Build.0 = Debug|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD}.RelWithDebInfo|x86.Build.0 = Release|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|x64.Build.0 = Debug|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Debug|x86.Deploy.0 = Debug|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|ARM.ActiveCfg = Debug|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|ARM.Build.0 = Debug|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|ARM.Deploy.0 = Debug|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|ARM64.ActiveCfg = Debug|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|ARM64.Build.0 = Debug|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|ARM64.Deploy.0 = Debug|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|x64.ActiveCfg = Debug|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|x64.Build.0 = Debug|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|x64.Deploy.0 = Debug|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|x86.ActiveCfg = Debug|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|x86.Build.0 = Debug|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.MinSizeRel|x86.Deploy.0 = Debug|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|ARM.Build.0 = Release|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|x64.ActiveCfg = Release|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|x64.Build.0 = Release|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|x64.Deploy.0 = Release|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|x86.Build.0 = Release|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.Release|x86.Deploy.0 = Release|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|ARM.ActiveCfg = Release|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|ARM.Build.0 = Release|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|ARM.Deploy.0 = Release|ARM
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|ARM64.ActiveCfg = Release|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|ARM64.Build.0 = Release|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|ARM64.Deploy.0 = Release|ARM64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|x64.Deploy.0 = Release|x64
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|x86.Build.0 = Release|Win32
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}.RelWithDebInfo|x86.Deploy.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -761,6 +841,8 @@ Global
|
|||
{FC3F9998-4085-4767-8386-5453F07C3AAD} = {7C2E30D9-E07F-4913-BD8A-345B38F18A81}
|
||||
{EBC4B40C-2319-4F7E-9531-8232EF8B87F4} = {69CDB6A1-434D-4BC9-9BFF-D12DF7EDBB6B}
|
||||
{08B41A2E-3AA3-49C4-A525-D45B902D9DB0} = {7C2E30D9-E07F-4913-BD8A-345B38F18A81}
|
||||
{A7E21439-B561-43F0-9DDD-237425F42BCD} = {69CDB6A1-434D-4BC9-9BFF-D12DF7EDBB6B}
|
||||
{FB2680FB-13CF-400C-8A5D-042C0AC20A3F} = {7C2E30D9-E07F-4913-BD8A-345B38F18A81}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3D5F862D-74C6-4357-9F95-0B152E33B7B8}
|
||||
|
|
|
@ -24,6 +24,6 @@ EXPORTS
|
|||
ebpf_api_pin_map
|
||||
ebpf_api_unpin_map
|
||||
ebpf_api_get_next_map
|
||||
ebpf_api_lookup_map
|
||||
ebpf_api_get_pinned_map
|
||||
ebpf_api_get_next_program
|
||||
ebpf_api_program_query_information
|
||||
|
|
|
@ -37,7 +37,7 @@ extern "C"
|
|||
* @brief Load an eBFP program into the kernel execution context.
|
||||
* @param[in] file An ELF file containing one or more eBPF programs.
|
||||
* @param[in] section_name Name of the section in the ELF file to load.
|
||||
* @param[in] execution_type How this program should be run in the exeuction
|
||||
* @param[in] execution_type How this program should be run in the execution
|
||||
* context.
|
||||
* @param[out] handle Handle to eBPF program.
|
||||
* @param[out] error_message Error message describing what failed.
|
||||
|
@ -214,13 +214,13 @@ extern "C"
|
|||
* @brief Convert an eBPF program to human readable byte code.
|
||||
* @param[in] file Name of ELF file containing eBPF program.
|
||||
* @param[in] section The name of the section to query.
|
||||
* @param[out] dissassembly On success points text version of the program.
|
||||
* @param[out] disassembly On success points text version of the program.
|
||||
* @param[out] error_message On failure points to a text description of
|
||||
* the error.
|
||||
*/
|
||||
uint32_t
|
||||
ebpf_api_elf_disassemble_section(
|
||||
const char* file, const char* section, const char** dissassembly, const char** error_message);
|
||||
const char* file, const char* section, const char** disassembly, const char** error_message);
|
||||
|
||||
/**
|
||||
* @brief Convert an eBPF program to human readable byte code.
|
||||
|
@ -259,8 +259,8 @@ extern "C"
|
|||
ebpf_api_pin_map(ebpf_handle_t handle, const uint8_t* name, uint32_t name_length);
|
||||
|
||||
/**
|
||||
* @brief Desasociate a name with a map handle.
|
||||
* @param[in] name Name to deassociate.
|
||||
* @brief Dissociate a name with a map handle.
|
||||
* @param[in] name Name to dissociate.
|
||||
*/
|
||||
uint32_t
|
||||
ebpf_api_unpin_map(const uint8_t* name, uint32_t name_length);
|
||||
|
@ -270,7 +270,7 @@ extern "C"
|
|||
* @param[in] name Name to find.
|
||||
*/
|
||||
uint32_t
|
||||
ebpf_api_lookup_map(const uint8_t* name, uint32_t name_length, ebpf_handle_t* handle);
|
||||
ebpf_api_get_pinned_map(const uint8_t* name, uint32_t name_length, ebpf_handle_t* handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -16,27 +16,24 @@ extern "C"
|
|||
|
||||
typedef uint32_t(__stdcall* ebpf_hook_function)(uint8_t*);
|
||||
ebpf_error_code_t
|
||||
ebpf_core_initialize();
|
||||
ebpf_core_initiate();
|
||||
|
||||
void
|
||||
ebpf_core_terminate();
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_invoke_hook(_In_ ebpf_program_type_t hook_point, _Inout_ void* context, _Inout_ uint32_t* result);
|
||||
ebpf_core_invoke_hook(ebpf_program_type_t hook_point, _Inout_ void* context, _Inout_ uint32_t* result);
|
||||
|
||||
typedef struct _ebpf_protocol_handler
|
||||
{
|
||||
union
|
||||
{
|
||||
ebpf_error_code_t (*protocol_handler_no_reply)(_In_ const void* input_buffer);
|
||||
ebpf_error_code_t (*protocol_handler_with_reply)(
|
||||
_In_ const void* input_buffer, void* output_buffer, uint16_t output_buffer_length);
|
||||
} dispatch;
|
||||
size_t minimum_request_size;
|
||||
size_t minimum_reply_size;
|
||||
} const ebpf_protocol_handler_t;
|
||||
ebpf_error_code_t
|
||||
ebpf_core_invoke_protocol_handler(
|
||||
ebpf_operation_id_t operation_id,
|
||||
_In_ const void* input_buffer,
|
||||
_Out_writes_bytes_(output_buffer_length) void* output_buffer,
|
||||
uint16_t output_buffer_length);
|
||||
|
||||
extern ebpf_protocol_handler_t EbpfProtocolHandlers[EBPF_OPERATION_LOOKUP_MAP_PINNING + 1];
|
||||
ebpf_error_code_t
|
||||
ebpf_core_get_protocol_handler_properties(
|
||||
ebpf_operation_id_t operation_id, _Out_ size_t* minimum_request_size, _Out_ size_t* minimum_reply_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ebpf_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_epoch_initiate();
|
||||
|
||||
void
|
||||
ebpf_epoch_terminate();
|
||||
|
||||
/**
|
||||
* @brief Called prior to touching memory with lifetime under epoch control.
|
||||
* @retval EBPF_ERROR_OUT_OF_RESOURCES Unable to allocate per-thread
|
||||
* tracking state.
|
||||
*/
|
||||
ebpf_error_code_t
|
||||
ebpf_epoch_enter();
|
||||
|
||||
/**
|
||||
* @brief Called after touching memory with lifetime under epoch control.
|
||||
*/
|
||||
void
|
||||
ebpf_epoch_exit();
|
||||
|
||||
/**
|
||||
* @brief Allocate memory under epoch control.
|
||||
* @param[in] size Size of memory to allocate
|
||||
* @param[in] type Allocate memory as executable vs non-executable
|
||||
* @returns Pointer to memory block allocated, or null on failure.
|
||||
*/
|
||||
void*
|
||||
ebpf_epoch_allocate(size_t size, ebpf_memory_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Free memory under epoch control.
|
||||
* @param[in] memory Allocation to be freed once epoch ends.
|
||||
*/
|
||||
void
|
||||
ebpf_epoch_free(void* memory);
|
||||
|
||||
/**
|
||||
* @Brief Release any memory that is associated with expired epochs.
|
||||
*/
|
||||
void
|
||||
ebpf_epoch_flush();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -26,8 +26,11 @@ extern "C"
|
|||
EBPF_CODE_INTEGRITY_HYPER_VISOR_KERNEL_MODE = 1
|
||||
} ebpf_code_integrity_state_t;
|
||||
|
||||
typedef struct _epbf_non_preemptable_work_item epbf_non_preepmtable_work_item_t;
|
||||
typedef struct _ebpf_timer_work_item ebpf_timer_work_item_t;
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_platform_initialize();
|
||||
ebpf_platform_initiate();
|
||||
|
||||
void
|
||||
ebpf_platform_terminate();
|
||||
|
@ -59,10 +62,56 @@ extern "C"
|
|||
void
|
||||
ebpf_lock_unlock(ebpf_lock_t* lock, ebpf_lock_state_t* state);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_get_cpu_count(uint32_t* cpu_count);
|
||||
|
||||
bool
|
||||
ebpf_is_preemptable();
|
||||
|
||||
uint32_t
|
||||
ebpf_get_current_cpu();
|
||||
|
||||
uint64_t
|
||||
ebpf_get_current_thread_id();
|
||||
|
||||
bool
|
||||
ebpf_is_non_preepmtable_work_item_supported();
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_allocate_non_preemptable_work_item(
|
||||
epbf_non_preepmtable_work_item_t** work_item,
|
||||
uint32_t cpu_id,
|
||||
void (*work_item_routine)(void* work_item_context, void* parameter_1),
|
||||
void* work_item_context);
|
||||
|
||||
void
|
||||
ebpf_free_non_preemptable_work_item(epbf_non_preepmtable_work_item_t* work_item);
|
||||
|
||||
bool
|
||||
ebpf_queue_non_preemptable_work_item(epbf_non_preepmtable_work_item_t* work_item, void* parameter_1);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_allocate_timer_work_item(
|
||||
ebpf_timer_work_item_t** work_item,
|
||||
void (*work_item_routine)(void* work_item_context),
|
||||
void* work_item_context);
|
||||
|
||||
void
|
||||
ebpf_schedule_timer_work_item(ebpf_timer_work_item_t* work_item, uint32_t elaped_microseconds);
|
||||
|
||||
void
|
||||
ebpf_free_timer_work_item(ebpf_timer_work_item_t* work_item);
|
||||
|
||||
typedef struct _ebpf_hash_table ebpf_hash_table_t;
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_hash_table_create(ebpf_hash_table_t** hash_table, size_t key_size, size_t value_size);
|
||||
ebpf_hash_table_create(
|
||||
ebpf_hash_table_t** hash_table,
|
||||
void* (*allocate)(size_t size, ebpf_memory_type_t type),
|
||||
void (*free)(void* memory),
|
||||
size_t key_size,
|
||||
size_t value_size);
|
||||
|
||||
void
|
||||
ebpf_hash_table_destroy(ebpf_hash_table_t* hash_table);
|
||||
ebpf_error_code_t
|
||||
|
@ -75,10 +124,19 @@ extern "C"
|
|||
ebpf_hash_table_next_key(ebpf_hash_table_t* hash_table, const uint8_t* previous_key, uint8_t* next_key);
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_increment(volatile int32_t* addend);
|
||||
ebpf_interlocked_increment_int32(volatile int32_t* addend);
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_decrement(volatile int32_t* addend);
|
||||
ebpf_interlocked_decrement_int32(volatile int32_t* addend);
|
||||
|
||||
int64_t
|
||||
ebpf_interlocked_increment_int64(volatile int64_t* addend);
|
||||
|
||||
int64_t
|
||||
ebpf_interlocked_decrement_int64(volatile int64_t* addend);
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_compare_exchange_int32(volatile int32_t* destination, int32_t exchange, int32_t comperand);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
typedef enum _ebpf_operation_id
|
||||
{
|
||||
EBPF_OPERATION_EVIDENCE,
|
||||
EBPF_OPERATION_RESOLVE_HELPER,
|
||||
EBPF_OPERATION_RESOLVE_MAP,
|
||||
EBPF_OPERATION_LOAD_CODE,
|
||||
|
@ -24,7 +23,7 @@ typedef enum _ebpf_operation_id
|
|||
EBPF_OPERATION_QUERY_MAP_DEFINITION,
|
||||
EBPF_OPERATION_QUERY_PROGRAM_INFORMATION,
|
||||
EBPF_OPERATION_UPDATE_MAP_PINNING,
|
||||
EBPF_OPERATION_LOOKUP_MAP_PINNING,
|
||||
EBPF_OPERATION_GET_MAP_PINNING,
|
||||
} ebpf_operation_id_t;
|
||||
|
||||
typedef enum _ebpf_code_type
|
||||
|
@ -39,18 +38,6 @@ typedef struct _ebpf_operation_header
|
|||
ebpf_operation_id_t id;
|
||||
} ebpf_operation_header_t;
|
||||
|
||||
typedef struct _ebpf_operation_eidence_request
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint8_t EBPF_OPERATION_EVIDENCE[1];
|
||||
} ebpf_operation_eidence_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_evidence_reply
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint32_t status;
|
||||
} ebpf_operation_evidence_reply_t;
|
||||
|
||||
typedef struct _ebpf_operation_resolve_helper_request
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
|
@ -215,14 +202,14 @@ typedef struct _ebpf_operation_update_map_pinning_request
|
|||
uint8_t name[1];
|
||||
} ebpf_operation_update_map_pinning_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_lookup_map_pinning_request
|
||||
typedef struct _ebpf_operation_get_map_pinning_request
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint8_t name[1];
|
||||
} ebpf_operation_lookup_map_pinning_request_t;
|
||||
} ebpf_operation_get_map_pinning_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_lookup_map_pinning_reply
|
||||
typedef struct _ebpf_operation_get_map_pinning_reply
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t handle;
|
||||
} ebpf_operation_lookup_map_pinning_reply_t;
|
||||
} ebpf_operation_get_map_pinning_reply_t;
|
||||
|
|
|
@ -443,13 +443,13 @@ ebpf_api_unpin_map(const uint8_t* name, uint32_t name_length)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
ebpf_api_lookup_map(const uint8_t* name, uint32_t name_length, ebpf_handle_t* handle)
|
||||
ebpf_api_get_pinned_map(const uint8_t* name, uint32_t name_length, ebpf_handle_t* handle)
|
||||
{
|
||||
std::vector<uint8_t> request_buffer(offsetof(ebpf_operation_lookup_map_pinning_request_t, name) + name_length);
|
||||
auto request = reinterpret_cast<ebpf_operation_lookup_map_pinning_request_t*>(request_buffer.data());
|
||||
ebpf_operation_lookup_map_pinning_reply_t reply;
|
||||
std::vector<uint8_t> request_buffer(offsetof(ebpf_operation_get_map_pinning_request_t, name) + name_length);
|
||||
auto request = reinterpret_cast<ebpf_operation_get_map_pinning_request_t*>(request_buffer.data());
|
||||
ebpf_operation_get_map_pinning_reply_t reply;
|
||||
|
||||
request->header.id = EBPF_OPERATION_LOOKUP_MAP_PINNING;
|
||||
request->header.id = EBPF_OPERATION_GET_MAP_PINNING;
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
std::copy(name, name + name_length, request->name);
|
||||
auto result = invoke_ioctl(device_handle, request_buffer, reply);
|
||||
|
@ -457,7 +457,7 @@ ebpf_api_lookup_map(const uint8_t* name, uint32_t name_length, ebpf_handle_t* ha
|
|||
return result;
|
||||
}
|
||||
|
||||
if (reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_LOOKUP_MAP_PINNING) {
|
||||
if (reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_GET_MAP_PINNING) {
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include "ebpf_epoch.h"
|
||||
|
||||
// Brief summary of how epoch tracking works.
|
||||
// Each free operation increments the epoch and the freed memory is stamped with
|
||||
// that epoch.
|
||||
//
|
||||
// Each block of code that accesses epoch freed memory wraps access in calls to
|
||||
// ebpf_epoch_enter/ebpf_epoch_exit.
|
||||
//
|
||||
// Epoch tracking is handled differently for pre-emptable vs non-pre-emptable
|
||||
// invocations.
|
||||
//
|
||||
// Non-pre-emptable invocations are:
|
||||
// 1) Tracked by the CPU they are running on as they don't switch CPUs.
|
||||
// 2) Accessed without synchronization.
|
||||
// 3) Set to the current epoch on entry.
|
||||
//
|
||||
// Pre-emptable invocations are:
|
||||
// 1) Tracked by thread ID.
|
||||
// 2) Accessed under a lock.
|
||||
// 3) Set to the current epoch on entry.
|
||||
// 4) Set to epoch 0 on exit.
|
||||
//
|
||||
// Memory can be freed only if there is no code using that epoch.
|
||||
// The CPU epoch table and thread table are scanned to find the lowest epoch in use.
|
||||
// The release epoch is then lowest epoch - 1 (if not 0).
|
||||
//
|
||||
// Note:
|
||||
// CPU table entries aren't cleared on exit as we can't rely on
|
||||
// memory ordering.
|
||||
// I.e., the thread doing the cleanup may have a stale view of the CPU table.
|
||||
// As long as the entries in the CPU table increase, this gives correct behavior.
|
||||
//
|
||||
|
||||
#define EBPF_EPOCH_FLUSH_DELAY_IN_MICROSECONDS 1000
|
||||
|
||||
// TODO: This lock may become a contention point.
|
||||
// Investigate partitioning the table.
|
||||
static ebpf_lock_t _ebpf_epoch_thread_table_lock = {0};
|
||||
|
||||
// Table to track what epoch each thread is on.
|
||||
static ebpf_hash_table_t* _ebpf_epoch_thread_table = NULL;
|
||||
|
||||
// Table to track what epoch each CPU is on.
|
||||
typedef struct _ebpf_epoch_cpu_entry
|
||||
{
|
||||
int64_t epoch;
|
||||
epbf_non_preepmtable_work_item_t* non_preemtable_work_item;
|
||||
} ebpf_epoch_cpu_entry_t;
|
||||
|
||||
static ebpf_epoch_cpu_entry_t* _ebpf_epoch_cpu_table = NULL;
|
||||
static uint32_t _ebpf_epoch_cpu_table_size = 0;
|
||||
|
||||
static volatile int64_t _ebpf_current_epoch = 1;
|
||||
|
||||
static ebpf_timer_work_item_t* _ebpf_flush_timer = NULL;
|
||||
static volatile int32_t _ebpf_flush_timer_set = 0;
|
||||
|
||||
typedef struct _ebpf_epoch_allocation_header
|
||||
{
|
||||
struct _ebpf_epoch_allocation_header* next;
|
||||
int64_t freed_epoch;
|
||||
} ebpf_epoch_allocation_header_t;
|
||||
|
||||
static ebpf_lock_t _ebpf_epoch_free_list_lock = {0};
|
||||
static ebpf_epoch_allocation_header_t _ebpf_epoch_free_list = {0};
|
||||
|
||||
// Release memory that was freed during this epoch or a prior epoch.
|
||||
static void
|
||||
ebpf_epoch_release_free_list(int64_t released_epoch);
|
||||
|
||||
// Get the highest epoch that is no longer in use.
|
||||
static ebpf_error_code_t
|
||||
ebpf_epoch_get_release_epoch(int64_t* released_epoch);
|
||||
|
||||
static void
|
||||
_ebpf_epoch_update_cpu_entry(void* context, void* parameter_1);
|
||||
|
||||
static void
|
||||
_ebpf_flush_worker(void* context);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_epoch_initiate()
|
||||
{
|
||||
ebpf_error_code_t return_value;
|
||||
uint32_t cpu_id;
|
||||
|
||||
_ebpf_current_epoch = 1;
|
||||
|
||||
ebpf_lock_create(&_ebpf_epoch_thread_table_lock);
|
||||
ebpf_lock_create(&_ebpf_epoch_free_list_lock);
|
||||
|
||||
if (ebpf_is_non_preepmtable_work_item_supported()) {
|
||||
return_value = ebpf_get_cpu_count(&_ebpf_epoch_cpu_table_size);
|
||||
if (return_value != EBPF_ERROR_SUCCESS) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
_ebpf_epoch_cpu_table =
|
||||
ebpf_allocate(_ebpf_epoch_cpu_table_size * sizeof(ebpf_epoch_cpu_entry_t), EBPF_MEMORY_NO_EXECUTE);
|
||||
if (!_ebpf_epoch_cpu_table) {
|
||||
return_value = EBPF_ERROR_OUT_OF_RESOURCES;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
memset(_ebpf_epoch_cpu_table, 0, _ebpf_epoch_cpu_table_size * sizeof(ebpf_epoch_cpu_entry_t));
|
||||
|
||||
for (cpu_id = 0; cpu_id < _ebpf_epoch_cpu_table_size; cpu_id++) {
|
||||
_ebpf_epoch_cpu_table[cpu_id].epoch = 0;
|
||||
return_value = ebpf_allocate_non_preemptable_work_item(
|
||||
&_ebpf_epoch_cpu_table[cpu_id].non_preemtable_work_item,
|
||||
cpu_id,
|
||||
_ebpf_epoch_update_cpu_entry,
|
||||
&_ebpf_epoch_cpu_table[cpu_id]);
|
||||
|
||||
if (return_value != EBPF_ERROR_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (return_value != EBPF_ERROR_SUCCESS) {
|
||||
for (cpu_id = 0; cpu_id < _ebpf_epoch_cpu_table_size; cpu_id++) {
|
||||
ebpf_free_non_preemptable_work_item(_ebpf_epoch_cpu_table[cpu_id].non_preemtable_work_item);
|
||||
}
|
||||
}
|
||||
if (return_value != EBPF_ERROR_SUCCESS)
|
||||
goto Error;
|
||||
}
|
||||
|
||||
return_value =
|
||||
ebpf_hash_table_create(&_ebpf_epoch_thread_table, ebpf_allocate, ebpf_free, sizeof(uint64_t), sizeof(int64_t));
|
||||
if (return_value != EBPF_ERROR_SUCCESS) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
return_value = ebpf_allocate_timer_work_item(&_ebpf_flush_timer, _ebpf_flush_worker, NULL);
|
||||
if (return_value != EBPF_ERROR_SUCCESS) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
return return_value;
|
||||
|
||||
Error:
|
||||
ebpf_epoch_terminate();
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_epoch_terminate()
|
||||
{
|
||||
ebpf_free_timer_work_item(_ebpf_flush_timer);
|
||||
ebpf_hash_table_destroy(_ebpf_epoch_thread_table);
|
||||
ebpf_free(_ebpf_epoch_cpu_table);
|
||||
ebpf_lock_destroy(&_ebpf_epoch_thread_table_lock);
|
||||
ebpf_epoch_release_free_list(INT64_MAX);
|
||||
ebpf_lock_destroy(&_ebpf_epoch_free_list_lock);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_epoch_enter()
|
||||
{
|
||||
if (!ebpf_is_non_preepmtable_work_item_supported() || ebpf_is_preemptable()) {
|
||||
ebpf_error_code_t return_value;
|
||||
ebpf_lock_state_t lock_state;
|
||||
uint64_t current_thread_id = ebpf_get_current_thread_id();
|
||||
int64_t current_epoch = _ebpf_current_epoch;
|
||||
ebpf_lock_lock(&_ebpf_epoch_thread_table_lock, &lock_state);
|
||||
return_value = ebpf_hash_table_update(
|
||||
_ebpf_epoch_thread_table, (const uint8_t*)¤t_thread_id, (const uint8_t*)¤t_epoch);
|
||||
ebpf_lock_unlock(&_ebpf_epoch_thread_table_lock, &lock_state);
|
||||
return return_value;
|
||||
} else {
|
||||
uint32_t current_cpu = ebpf_get_current_cpu();
|
||||
if (current_cpu >= _ebpf_epoch_cpu_table_size) {
|
||||
return EBPF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_ebpf_epoch_cpu_table[current_cpu].epoch = _ebpf_current_epoch;
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_epoch_exit()
|
||||
{
|
||||
if (ebpf_is_preemptable()) {
|
||||
ebpf_lock_state_t lock_state;
|
||||
uint64_t current_thread_id = ebpf_get_current_thread_id();
|
||||
int64_t current_epoch = 0;
|
||||
ebpf_lock_lock(&_ebpf_epoch_thread_table_lock, &lock_state);
|
||||
ebpf_hash_table_update(
|
||||
_ebpf_epoch_thread_table, (const uint8_t*)¤t_thread_id, (const uint8_t*)¤t_epoch);
|
||||
ebpf_lock_unlock(&_ebpf_epoch_thread_table_lock, &lock_state);
|
||||
} else {
|
||||
uint32_t current_cpu = ebpf_get_current_cpu();
|
||||
if (current_cpu >= _ebpf_epoch_cpu_table_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
_ebpf_epoch_cpu_table[current_cpu].epoch = _ebpf_current_epoch;
|
||||
}
|
||||
|
||||
if (_ebpf_epoch_free_list.next != NULL &&
|
||||
(ebpf_interlocked_compare_exchange_int32(&_ebpf_flush_timer_set, 0, 1) != 0)) {
|
||||
ebpf_schedule_timer_work_item(_ebpf_flush_timer, EBPF_EPOCH_FLUSH_DELAY_IN_MICROSECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_epoch_flush()
|
||||
{
|
||||
ebpf_error_code_t return_value;
|
||||
int64_t released_epoch;
|
||||
uint32_t cpu_id;
|
||||
|
||||
if (ebpf_is_non_preepmtable_work_item_supported()) {
|
||||
// Schedule a non-preemptable work item to bring the CPU up to the current
|
||||
// epoch.
|
||||
// Note: May not affect the current flush.
|
||||
for (cpu_id = 0; cpu_id < _ebpf_epoch_cpu_table_size; cpu_id++) {
|
||||
if (!_ebpf_epoch_cpu_table[cpu_id].non_preemtable_work_item)
|
||||
break;
|
||||
|
||||
// Don't synchronize CPUs that have never participated.
|
||||
if (_ebpf_epoch_cpu_table[cpu_id].epoch == 0)
|
||||
continue;
|
||||
|
||||
// Note: Either the per-cpu epoch or the global epoch could be out of date.
|
||||
// That is acceptable as it may schedule an extra work item.
|
||||
if (_ebpf_epoch_cpu_table[cpu_id].epoch != _ebpf_current_epoch)
|
||||
ebpf_queue_non_preemptable_work_item(_ebpf_epoch_cpu_table[cpu_id].non_preemtable_work_item, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return_value = ebpf_epoch_get_release_epoch(&released_epoch);
|
||||
if (return_value == EBPF_ERROR_SUCCESS) {
|
||||
ebpf_epoch_release_free_list(released_epoch);
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
ebpf_epoch_allocate(size_t size, ebpf_memory_type_t type)
|
||||
{
|
||||
ebpf_epoch_allocation_header_t* header;
|
||||
size += sizeof(ebpf_epoch_allocation_header_t);
|
||||
header = (ebpf_epoch_allocation_header_t*)ebpf_allocate(size, type);
|
||||
if (header)
|
||||
header++;
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_epoch_free(void* memory)
|
||||
{
|
||||
ebpf_epoch_allocation_header_t* header = (ebpf_epoch_allocation_header_t*)memory;
|
||||
ebpf_lock_state_t lock_state;
|
||||
header--;
|
||||
|
||||
header->freed_epoch = ebpf_interlocked_increment_int64(&_ebpf_current_epoch) - 1;
|
||||
|
||||
ebpf_lock_lock(&_ebpf_epoch_free_list_lock, &lock_state);
|
||||
header->next = _ebpf_epoch_free_list.next;
|
||||
_ebpf_epoch_free_list.next = header;
|
||||
ebpf_lock_unlock(&_ebpf_epoch_free_list_lock, &lock_state);
|
||||
}
|
||||
|
||||
static void
|
||||
ebpf_epoch_release_free_list(int64_t released_epoch)
|
||||
{
|
||||
ebpf_lock_state_t lock_state;
|
||||
ebpf_epoch_allocation_header_t* header;
|
||||
ebpf_epoch_allocation_header_t* previous_header;
|
||||
|
||||
ebpf_lock_lock(&_ebpf_epoch_free_list_lock, &lock_state);
|
||||
header = _ebpf_epoch_free_list.next;
|
||||
previous_header = &_ebpf_epoch_free_list;
|
||||
while (header) {
|
||||
if (header->freed_epoch <= released_epoch) {
|
||||
previous_header->next = header->next;
|
||||
ebpf_free(header);
|
||||
header = previous_header->next;
|
||||
} else {
|
||||
previous_header = header;
|
||||
header = header->next;
|
||||
}
|
||||
}
|
||||
ebpf_lock_unlock(&_ebpf_epoch_free_list_lock, &lock_state);
|
||||
}
|
||||
|
||||
static ebpf_error_code_t
|
||||
ebpf_epoch_get_release_epoch(int64_t* release_epoch)
|
||||
{
|
||||
int64_t lowest_epoch = INT64_MAX;
|
||||
int64_t* thread_epoch;
|
||||
uint32_t cpu_id;
|
||||
uint64_t thread_id = 0;
|
||||
ebpf_lock_state_t lock_state;
|
||||
ebpf_error_code_t return_value;
|
||||
|
||||
if (ebpf_is_non_preepmtable_work_item_supported()) {
|
||||
for (cpu_id = 0; cpu_id < _ebpf_epoch_cpu_table_size; cpu_id++) {
|
||||
if ((_ebpf_epoch_cpu_table[cpu_id].epoch != 0) && _ebpf_epoch_cpu_table[cpu_id].epoch < lowest_epoch)
|
||||
lowest_epoch = _ebpf_epoch_cpu_table[cpu_id].epoch;
|
||||
}
|
||||
}
|
||||
|
||||
ebpf_lock_lock(&_ebpf_epoch_thread_table_lock, &lock_state);
|
||||
return_value = ebpf_hash_table_next_key(_ebpf_epoch_thread_table, NULL, (uint8_t*)&thread_id);
|
||||
if (return_value == EBPF_ERROR_SUCCESS)
|
||||
for (;;) {
|
||||
return_value =
|
||||
ebpf_hash_table_lookup(_ebpf_epoch_thread_table, (uint8_t*)&thread_id, (uint8_t**)&thread_epoch);
|
||||
if (return_value != EBPF_ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
if (*thread_epoch != 0 && *thread_epoch < lowest_epoch)
|
||||
lowest_epoch = *thread_epoch;
|
||||
|
||||
return_value =
|
||||
ebpf_hash_table_next_key(_ebpf_epoch_thread_table, (uint8_t*)&thread_id, (uint8_t*)&thread_id);
|
||||
if (return_value != EBPF_ERROR_SUCCESS)
|
||||
break;
|
||||
}
|
||||
ebpf_lock_unlock(&_ebpf_epoch_thread_table_lock, &lock_state);
|
||||
|
||||
if (return_value != EBPF_ERROR_NO_MORE_KEYS) {
|
||||
return return_value;
|
||||
}
|
||||
|
||||
*release_epoch = lowest_epoch - 1;
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_ebpf_epoch_update_cpu_entry(void* context, void* parameter_1)
|
||||
{
|
||||
ebpf_epoch_cpu_entry_t* cpu_entry = (ebpf_epoch_cpu_entry_t*)context;
|
||||
UNREFERENCED_PARAMETER(parameter_1);
|
||||
|
||||
cpu_entry->epoch = _ebpf_current_epoch;
|
||||
}
|
||||
|
||||
static void
|
||||
_ebpf_flush_worker(void* context)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(context);
|
||||
|
||||
if (ebpf_interlocked_compare_exchange_int32(&_ebpf_flush_timer_set, 1, 0) != 1) {
|
||||
return;
|
||||
}
|
||||
ebpf_epoch_flush();
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" 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>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\ebpf_epoch.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\include\ebpf_epoch.h" />
|
||||
<ClInclude Include="..\..\..\include\ebpf_platform.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{FB2680FB-13CF-400C-8A5D-042C0AC20A3F}</ProjectGuid>
|
||||
<TemplateGuid>{0a049372-4c4d-4ea0-a64e-dc6ad88ceca1}</TemplateGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||
<RootNamespace>epoch_kernel</RootNamespace>
|
||||
<DriverType>KMDF</DriverType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<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>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<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>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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)\src\ebpf\include;$(SolutionDir)\src\ebpf\include\kernel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<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)\src\ebpf\include;$(SolutionDir)\src\ebpf\include\kernel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<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>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<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>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<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>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<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>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,34 @@
|
|||
<?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;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;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="..\ebpf_epoch.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\include\ebpf_epoch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\include\ebpf_platform.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,168 @@
|
|||
<?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>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\include\ebpf_epoch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\ebpf_epoch.c" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{a7e21439-b561-43f0-9ddd-237425f42bcd}</ProjectGuid>
|
||||
<RootNamespace>epochuser</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</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;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\src\ebpf\include;$(SolutionDir)\src\ebpf\include\user</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\src\ebpf\include;$(SolutionDir)\src\ebpf\include\user</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,31 @@
|
|||
<?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>
|
||||
<ClInclude Include="..\..\..\include\ebpf_epoch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\ebpf_epoch.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "ebpf_core.h"
|
||||
|
||||
#include "ebpf_epoch.h"
|
||||
#include "ebpf_maps.h"
|
||||
#include "ubpf.h"
|
||||
|
||||
|
@ -262,20 +263,37 @@ _ebpf_core_delete_code_entry(uint64_t handle)
|
|||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_initialize()
|
||||
ebpf_core_initiate()
|
||||
{
|
||||
ebpf_error_code_t return_value;
|
||||
return_value = ebpf_platform_initialize();
|
||||
if (return_value != EBPF_ERROR_SUCCESS) {
|
||||
return return_value;
|
||||
}
|
||||
bool platform_initialized = false;
|
||||
bool epoch_initialize = false;
|
||||
|
||||
return_value = ebpf_platform_initiate();
|
||||
if (return_value != EBPF_ERROR_SUCCESS)
|
||||
goto Done;
|
||||
platform_initialized = true;
|
||||
|
||||
return_value = ebpf_epoch_initiate();
|
||||
if (return_value != EBPF_ERROR_SUCCESS)
|
||||
goto Done;
|
||||
epoch_initialize = true;
|
||||
|
||||
ebpf_lock_create(&_ebpf_core_code_entry_table_lock);
|
||||
ebpf_lock_create(&_ebpf_core_map_entry_table_lock);
|
||||
ebpf_lock_create(&_ebpf_core_hook_table_lock);
|
||||
ebpf_lock_create(&_ebpf_core_pinning_table_lock);
|
||||
|
||||
return ebpf_query_code_integrity_state(&_ebpf_core_code_integrity_state);
|
||||
return_value = ebpf_query_code_integrity_state(&_ebpf_core_code_integrity_state);
|
||||
|
||||
Done:
|
||||
if (return_value != EBPF_ERROR_SUCCESS) {
|
||||
if (epoch_initialize)
|
||||
ebpf_epoch_terminate();
|
||||
if (platform_initialized)
|
||||
ebpf_platform_terminate();
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -298,6 +316,10 @@ ebpf_core_terminate()
|
|||
for (index = 0; index < EBPF_COUNT_OF(_ebpf_core_pinning_table); index++)
|
||||
ebpf_free(_ebpf_core_pinning_table[index]);
|
||||
ebpf_lock_unlock(&_ebpf_core_pinning_table_lock, &state);
|
||||
|
||||
ebpf_epoch_terminate();
|
||||
|
||||
ebpf_platform_terminate();
|
||||
}
|
||||
|
||||
static ebpf_error_code_t
|
||||
|
@ -449,7 +471,7 @@ ebpf_core_protocol_load_code(
|
|||
goto Done;
|
||||
}
|
||||
|
||||
// BUG - ubpf implements bounds checking to detect interpreted code accesing
|
||||
// BUG - ubpf implements bounds checking to detect interpreted code accessing
|
||||
// memory out of bounds. Currently this is flagging valid access checks and
|
||||
// failing.
|
||||
toggle_bounds_check(code_entry->code_or_vm.vm, false);
|
||||
|
@ -536,27 +558,31 @@ ebpf_core_protocol_resolve_map(
|
|||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_invoke_hook(_In_ ebpf_program_type_t hook_point, _Inout_ void* context, _Inout_ uint32_t* result)
|
||||
ebpf_core_invoke_hook(ebpf_program_type_t hook_point, _Inout_ void* context, _Inout_ uint32_t* result)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
ebpf_core_code_entry_t* code = NULL;
|
||||
ebpf_hook_function function_pointer;
|
||||
char* error_message = NULL;
|
||||
|
||||
retval = ebpf_epoch_enter();
|
||||
if (retval != EBPF_ERROR_SUCCESS)
|
||||
return retval;
|
||||
|
||||
code = _ebpf_core_get_hook_entry(hook_point);
|
||||
if (code) {
|
||||
if (code->code_type == EBPF_CODE_NATIVE) {
|
||||
function_pointer = (ebpf_hook_function)(code->code_or_vm.code);
|
||||
*result = (function_pointer)(context);
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
} else {
|
||||
*result = (uint32_t)(ubpf_exec(code->code_or_vm.vm, context, 1024, &error_message));
|
||||
if (error_message) {
|
||||
ebpf_free(error_message);
|
||||
}
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
// Nothing to do if no hook is registered.
|
||||
|
||||
ebpf_epoch_exit();
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -742,7 +768,7 @@ ebpf_core_protocol_get_next_map(
|
|||
uint64_t next_handle = request->previous_handle;
|
||||
UNREFERENCED_PARAMETER(reply_length);
|
||||
|
||||
// Start search from begining
|
||||
// Start search from beginning
|
||||
if (next_handle == UINT64_MAX) {
|
||||
next_handle = 1;
|
||||
} else {
|
||||
|
@ -776,7 +802,7 @@ ebpf_core_protocol_get_next_program(
|
|||
uint64_t next_handle = request->previous_handle;
|
||||
UNREFERENCED_PARAMETER(reply_length);
|
||||
|
||||
// Start search from begining
|
||||
// Start search from beginning
|
||||
if (next_handle == UINT64_MAX) {
|
||||
next_handle = 1;
|
||||
} else {
|
||||
|
@ -895,14 +921,14 @@ Done:
|
|||
}
|
||||
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_lookup_map_pinning(
|
||||
_In_ const struct _ebpf_operation_lookup_map_pinning_request* request,
|
||||
_Inout_ struct _ebpf_operation_lookup_map_pinning_reply* reply,
|
||||
ebpf_core_protocol_get_pinned_map(
|
||||
_In_ const struct _ebpf_operation_get_map_pinning_request* request,
|
||||
_Inout_ struct _ebpf_operation_get_map_pinning_reply* reply,
|
||||
uint16_t reply_length)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
const uint8_t* name = request->name;
|
||||
size_t name_length = request->header.length - EBPF_OFFSET_OF(ebpf_operation_lookup_map_pinning_request_t, name);
|
||||
size_t name_length = request->header.length - EBPF_OFFSET_OF(ebpf_operation_get_map_pinning_request_t, name);
|
||||
UNREFERENCED_PARAMETER(reply_length);
|
||||
|
||||
if (name_length == 0) {
|
||||
|
@ -950,8 +976,21 @@ ebpf_core_interpreter_helper_resolver(void* context, uint32_t helper_id)
|
|||
return (uint64_t)_ebpf_program_helpers[helper_id];
|
||||
}
|
||||
|
||||
ebpf_protocol_handler_t EbpfProtocolHandlers[EBPF_OPERATION_LOOKUP_MAP_PINNING + 1] = {
|
||||
{NULL, sizeof(struct _ebpf_operation_eidence_request)}, // EBPF_OPERATION_EVIDENCE
|
||||
typedef struct _ebpf_protocol_handler
|
||||
{
|
||||
union
|
||||
{
|
||||
ebpf_error_code_t (*protocol_handler_no_reply)(_In_ const void* input_buffer);
|
||||
ebpf_error_code_t (*protocol_handler_with_reply)(
|
||||
_In_ const void* input_buffer,
|
||||
_Out_writes_bytes_(output_buffer_length) void* output_buffer,
|
||||
uint16_t output_buffer_length);
|
||||
} dispatch;
|
||||
size_t minimum_request_size;
|
||||
size_t minimum_reply_size;
|
||||
} const ebpf_protocol_handler_t;
|
||||
|
||||
static ebpf_protocol_handler_t _ebpf_protocol_handlers[EBPF_OPERATION_GET_MAP_PINNING + 1] = {
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_resolve_helper,
|
||||
sizeof(struct _ebpf_operation_resolve_helper_request),
|
||||
sizeof(struct _ebpf_operation_resolve_helper_reply)},
|
||||
|
@ -988,7 +1027,52 @@ ebpf_protocol_handler_t EbpfProtocolHandlers[EBPF_OPERATION_LOOKUP_MAP_PINNING +
|
|||
sizeof(struct _ebpf_operation_query_program_information_request),
|
||||
sizeof(struct _ebpf_operation_query_program_information_reply)},
|
||||
{ebpf_core_protocol_update_map_pinning, sizeof(struct _ebpf_operation_update_map_pinning_request), 0},
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_lookup_map_pinning,
|
||||
sizeof(struct _ebpf_operation_lookup_map_pinning_request),
|
||||
sizeof(struct _ebpf_operation_lookup_map_pinning_reply)},
|
||||
};
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_get_pinned_map,
|
||||
sizeof(struct _ebpf_operation_get_map_pinning_request),
|
||||
sizeof(struct _ebpf_operation_get_map_pinning_reply)},
|
||||
};
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_get_protocol_handler_properties(
|
||||
ebpf_operation_id_t operation_id, _Out_ size_t* minimum_request_size, _Out_ size_t* minimum_reply_size)
|
||||
{
|
||||
*minimum_request_size = 0;
|
||||
*minimum_reply_size = 0;
|
||||
|
||||
if (operation_id > EBPF_OPERATION_GET_MAP_PINNING || operation_id < EBPF_OPERATION_RESOLVE_HELPER)
|
||||
return EBPF_ERROR_NOT_SUPPORTED;
|
||||
|
||||
if (!_ebpf_protocol_handlers[operation_id].dispatch.protocol_handler_no_reply)
|
||||
return EBPF_ERROR_NOT_SUPPORTED;
|
||||
|
||||
*minimum_request_size = _ebpf_protocol_handlers[operation_id].minimum_request_size;
|
||||
*minimum_reply_size = _ebpf_protocol_handlers[operation_id].minimum_reply_size;
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_invoke_protocol_handler(
|
||||
ebpf_operation_id_t operation_id,
|
||||
_In_ const void* input_buffer,
|
||||
_Out_writes_bytes_(output_buffer_length) void* output_buffer,
|
||||
uint16_t output_buffer_length)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
|
||||
if (operation_id > EBPF_OPERATION_GET_MAP_PINNING || operation_id < EBPF_OPERATION_RESOLVE_HELPER) {
|
||||
return EBPF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
retval = ebpf_epoch_enter();
|
||||
if (retval != EBPF_ERROR_SUCCESS)
|
||||
return retval;
|
||||
|
||||
if (output_buffer == NULL)
|
||||
retval = _ebpf_protocol_handlers[operation_id].dispatch.protocol_handler_no_reply(input_buffer);
|
||||
else
|
||||
retval = _ebpf_protocol_handlers[operation_id].dispatch.protocol_handler_with_reply(
|
||||
input_buffer, output_buffer, output_buffer_length);
|
||||
|
||||
ebpf_epoch_exit();
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include "ebpf_maps.h"
|
||||
#include "ebpf_epoch.h"
|
||||
|
||||
typedef struct _ebpf_core_map
|
||||
{
|
||||
|
@ -52,13 +53,13 @@ ebpf_map_create(const ebpf_map_definition_t* ebpf_map_definition, ebpf_map_t** e
|
|||
void
|
||||
ebpf_map_acquire_reference(ebpf_map_t* map)
|
||||
{
|
||||
ebpf_interlocked_increment(&map->reference_count);
|
||||
ebpf_interlocked_increment_int32(&map->reference_count);
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_map_release_reference(ebpf_map_t* map)
|
||||
{
|
||||
uint32_t new_ref_count = ebpf_interlocked_decrement(&map->reference_count);
|
||||
uint32_t new_ref_count = ebpf_interlocked_decrement_int32(&map->reference_count);
|
||||
if (new_ref_count == 0)
|
||||
ebpf_map_function_tables[map->ebpf_map_definition.type].delete_map(map);
|
||||
}
|
||||
|
@ -197,7 +198,11 @@ ebpf_create_hash_map(_In_ const ebpf_map_definition_t* map_definition)
|
|||
map->data = NULL;
|
||||
|
||||
retval = ebpf_hash_table_create(
|
||||
(ebpf_hash_table_t**)&map->data, map->ebpf_map_definition.key_size, map->ebpf_map_definition.value_size);
|
||||
(ebpf_hash_table_t**)&map->data,
|
||||
ebpf_epoch_allocate,
|
||||
ebpf_epoch_free,
|
||||
map->ebpf_map_definition.key_size,
|
||||
map->ebpf_map_definition.value_size);
|
||||
if (retval != EBPF_ERROR_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ struct _ebpf_hash_table
|
|||
struct _RTL_AVL_TABLE avl_table;
|
||||
size_t key_size;
|
||||
size_t value_size;
|
||||
void* (*allocate)(size_t size, ebpf_memory_type_t type);
|
||||
void (*free)(void* memory);
|
||||
};
|
||||
|
||||
// NOTE:
|
||||
|
@ -31,21 +33,26 @@ ebpf_hash_map_compare(struct _RTL_AVL_TABLE* avl_table, void* first_struct, void
|
|||
}
|
||||
|
||||
static void*
|
||||
ebpf_hash_map_allocate(struct _RTL_AVL_TABLE* table, unsigned long byte_size)
|
||||
ebpf_hash_map_allocate(struct _RTL_AVL_TABLE* avl_table, unsigned long byte_size)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(table);
|
||||
return ebpf_allocate(byte_size, EBPF_MEMORY_NO_EXECUTE);
|
||||
ebpf_hash_table_t* table = (ebpf_hash_table_t*)avl_table;
|
||||
return table->allocate(byte_size, EBPF_MEMORY_NO_EXECUTE);
|
||||
}
|
||||
|
||||
static void
|
||||
ebpf_hash_map_free(struct _RTL_AVL_TABLE* table, void* buffer)
|
||||
ebpf_hash_map_free(struct _RTL_AVL_TABLE* avl_table, void* buffer)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(table);
|
||||
ebpf_free(buffer);
|
||||
ebpf_hash_table_t* table = (ebpf_hash_table_t*)avl_table;
|
||||
table->free(buffer);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_hash_table_create(ebpf_hash_table_t** hash_table, size_t key_size, size_t value_size)
|
||||
ebpf_hash_table_create(
|
||||
ebpf_hash_table_t** hash_table,
|
||||
void* (*allocate)(size_t size, ebpf_memory_type_t type),
|
||||
void (*free)(void* memory),
|
||||
size_t key_size,
|
||||
size_t value_size)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
ebpf_hash_table_t* table = NULL;
|
||||
|
@ -62,6 +69,8 @@ ebpf_hash_table_create(ebpf_hash_table_t** hash_table, size_t key_size, size_t v
|
|||
|
||||
table->key_size = key_size;
|
||||
table->value_size = value_size;
|
||||
table->allocate = allocate;
|
||||
table->free = free;
|
||||
|
||||
*hash_table = table;
|
||||
retval = EBPF_ERROR_SUCCESS;
|
||||
|
@ -165,7 +174,7 @@ ebpf_hash_table_next_key(ebpf_hash_table_t* hash_table, const uint8_t* previous_
|
|||
if (!entry) {
|
||||
// Entry deleted.
|
||||
|
||||
// Start at the begining of the table.
|
||||
// Start at the beginning of the table.
|
||||
entry = RtlEnumerateGenericTableAvl(table, TRUE);
|
||||
if (entry == NULL) {
|
||||
return EBPF_ERROR_NO_MORE_KEYS;
|
||||
|
|
|
@ -10,7 +10,7 @@ typedef enum _ebpf_pool_tag
|
|||
} ebpf_pool_tag_t;
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_platform_initialize()
|
||||
ebpf_platform_initiate()
|
||||
{
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -109,13 +109,174 @@ ebpf_lock_unlock(ebpf_lock_t* lock, ebpf_lock_state_t* state)
|
|||
}
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_increment(volatile int32_t* addend)
|
||||
ebpf_interlocked_increment_int32(volatile int32_t* addend)
|
||||
{
|
||||
return InterlockedIncrement((volatile LONG*)addend);
|
||||
return InterlockedIncrement((volatile long*)addend);
|
||||
}
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_decrement(volatile int32_t* addend)
|
||||
ebpf_interlocked_decrement_int32(volatile int32_t* addend)
|
||||
{
|
||||
return InterlockedDecrement((volatile LONG*)addend);
|
||||
}
|
||||
return InterlockedDecrement((volatile long*)addend);
|
||||
}
|
||||
|
||||
int64_t
|
||||
ebpf_interlocked_increment_int64(volatile int64_t* addend)
|
||||
{
|
||||
return InterlockedIncrement64(addend);
|
||||
}
|
||||
|
||||
int64_t
|
||||
ebpf_interlocked_decrement_int64(volatile int64_t* addend)
|
||||
{
|
||||
return InterlockedDecrement64(addend);
|
||||
}
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_compare_exchange_int32(volatile int32_t* destination, int32_t exchange, int32_t comperand)
|
||||
{
|
||||
return InterlockedCompareExchange((long volatile*)destination, exchange, comperand);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_get_cpu_count(uint32_t* cpu_count)
|
||||
{
|
||||
*cpu_count = KeQueryMaximumProcessorCount();
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
bool
|
||||
ebpf_is_preemptable()
|
||||
{
|
||||
KIRQL irql = KeGetCurrentIrql();
|
||||
return irql >= DISPATCH_LEVEL;
|
||||
}
|
||||
|
||||
bool
|
||||
ebpf_is_non_preepmtable_work_item_supported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ebpf_get_current_cpu()
|
||||
{
|
||||
return KeGetCurrentProcessorNumber();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ebpf_get_current_thread_id()
|
||||
{
|
||||
return (uint64_t)KeGetCurrentThread();
|
||||
}
|
||||
|
||||
typedef struct _epbf_non_preemptable_work_item
|
||||
{
|
||||
KDPC deferred_procedure_call;
|
||||
void (*work_item_routine)(void* work_item_context, void* parameter_1);
|
||||
} epbf_non_preepmtable_work_item_t;
|
||||
|
||||
static void
|
||||
_ebpf_deferred_routine(
|
||||
KDPC* deferred_procedure_call, PVOID deferred_context, PVOID system_argument_1, PVOID system_argument_2)
|
||||
{
|
||||
epbf_non_preepmtable_work_item_t* deferred_routine_context =
|
||||
(epbf_non_preepmtable_work_item_t*)deferred_procedure_call;
|
||||
UNREFERENCED_PARAMETER(system_argument_2);
|
||||
deferred_routine_context->work_item_routine(deferred_context, system_argument_1);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_allocate_non_preemptable_work_item(
|
||||
epbf_non_preepmtable_work_item_t** work_item,
|
||||
uint32_t cpu_id,
|
||||
void (*work_item_routine)(void* work_item_context, void* parameter_1),
|
||||
void* work_item_context)
|
||||
{
|
||||
*work_item = ebpf_allocate(sizeof(epbf_non_preepmtable_work_item_t), EBPF_MEMORY_NO_EXECUTE);
|
||||
if (*work_item == NULL) {
|
||||
return EBPF_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
(*work_item)->work_item_routine = work_item_routine;
|
||||
|
||||
KeInitializeDpc(&(*work_item)->deferred_procedure_call, _ebpf_deferred_routine, work_item_context);
|
||||
KeSetTargetProcessorDpc(&(*work_item)->deferred_procedure_call, (uint8_t)cpu_id);
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_free_non_preemptable_work_item(epbf_non_preepmtable_work_item_t* work_item)
|
||||
{
|
||||
if (!work_item)
|
||||
return;
|
||||
|
||||
KeRemoveQueueDpc(&work_item->deferred_procedure_call);
|
||||
ebpf_free(work_item);
|
||||
}
|
||||
|
||||
bool
|
||||
ebpf_queue_non_preemptable_work_item(epbf_non_preepmtable_work_item_t* work_item, void* parameter_1)
|
||||
{
|
||||
return KeInsertQueueDpc(&work_item->deferred_procedure_call, parameter_1, NULL);
|
||||
}
|
||||
|
||||
typedef struct _ebpf_timer_work_item
|
||||
{
|
||||
KTIMER timer;
|
||||
KDPC deferred_procedure_call;
|
||||
void (*work_item_routine)(void* work_item_context);
|
||||
void* work_item_context;
|
||||
} ebpf_timer_work_item_t;
|
||||
|
||||
static void
|
||||
_ebpf_timer_routine(
|
||||
KDPC* deferred_procedure_call, PVOID deferred_context, PVOID system_argument_1, PVOID system_argument_2)
|
||||
{
|
||||
ebpf_timer_work_item_t* timer_work_item = (ebpf_timer_work_item_t*)deferred_procedure_call;
|
||||
UNREFERENCED_PARAMETER(system_argument_1);
|
||||
UNREFERENCED_PARAMETER(system_argument_2);
|
||||
timer_work_item->work_item_routine(deferred_context);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_allocate_timer_work_item(
|
||||
ebpf_timer_work_item_t** timer_work_item,
|
||||
void (*work_item_routine)(void* work_item_context),
|
||||
void* work_item_context)
|
||||
{
|
||||
*timer_work_item = ebpf_allocate(sizeof(ebpf_timer_work_item_t), EBPF_MEMORY_NO_EXECUTE);
|
||||
if (*timer_work_item == NULL)
|
||||
return EBPF_ERROR_OUT_OF_RESOURCES;
|
||||
|
||||
(*timer_work_item)->work_item_routine = work_item_routine;
|
||||
(*timer_work_item)->work_item_context = work_item_context;
|
||||
|
||||
KeInitializeTimer(&(*timer_work_item)->timer);
|
||||
KeInitializeDpc(&(*timer_work_item)->deferred_procedure_call, _ebpf_timer_routine, work_item_context);
|
||||
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
#define MICROSECONDS_PER_TICK 10
|
||||
#define MICROSECONDS_PER_MILLISECOND 1000
|
||||
|
||||
void
|
||||
ebpf_schedule_timer_work_item(ebpf_timer_work_item_t* work_item, uint32_t elaped_microseconds)
|
||||
{
|
||||
LARGE_INTEGER due_time;
|
||||
due_time.QuadPart = -((int64_t)elaped_microseconds * MICROSECONDS_PER_TICK);
|
||||
|
||||
KeSetTimer(&work_item->timer, due_time, &work_item->deferred_procedure_call);
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_free_timer_work_item(ebpf_timer_work_item_t* work_item)
|
||||
{
|
||||
if (!work_item)
|
||||
return;
|
||||
|
||||
KeCancelTimer(&work_item->timer);
|
||||
KeRemoveQueueDpc(&work_item->deferred_procedure_call);
|
||||
ebpf_free(work_item);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,11 @@
|
|||
|
||||
std::set<uint64_t> _executable_segments;
|
||||
|
||||
// Global variables used to override behavior for testing.
|
||||
// Permit the test to simulate both Hyper-V Code Integrity.
|
||||
bool _ebpf_platform_code_integrity_enabled = false;
|
||||
// Permit the test to simulate non-preemptable execution.
|
||||
bool _ebpf_platform_is_preemptable = true;
|
||||
|
||||
void (*RtlInitializeGenericTableAvl)(
|
||||
_Out_ PRTL_AVL_TABLE Table,
|
||||
|
@ -46,7 +50,7 @@ resolve_function(HMODULE module_handle, fn& function, const char* function_name)
|
|||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_platform_initialize()
|
||||
ebpf_platform_initiate()
|
||||
{
|
||||
HMODULE ntdll_module = nullptr;
|
||||
|
||||
|
@ -167,13 +171,161 @@ ebpf_lock_unlock(ebpf_lock_t* lock, ebpf_lock_state_t* state)
|
|||
}
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_increment(volatile int32_t* addend)
|
||||
ebpf_interlocked_increment_int32(volatile int32_t* addend)
|
||||
{
|
||||
return InterlockedIncrement((volatile LONG*)addend);
|
||||
return InterlockedIncrement((volatile long*)addend);
|
||||
}
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_decrement(volatile int32_t* addend)
|
||||
ebpf_interlocked_decrement_int32(volatile int32_t* addend)
|
||||
{
|
||||
return InterlockedDecrement((volatile LONG*)addend);
|
||||
}
|
||||
return InterlockedDecrement((volatile long*)addend);
|
||||
}
|
||||
|
||||
int64_t
|
||||
ebpf_interlocked_increment_int64(volatile int64_t* addend)
|
||||
{
|
||||
return InterlockedIncrement64(addend);
|
||||
}
|
||||
|
||||
int64_t
|
||||
ebpf_interlocked_decrement_int64(volatile int64_t* addend)
|
||||
{
|
||||
return InterlockedDecrement64(addend);
|
||||
}
|
||||
|
||||
int32_t
|
||||
ebpf_interlocked_compare_exchange_int32(volatile int32_t* destination, int32_t exchange, int32_t comperand)
|
||||
{
|
||||
return InterlockedCompareExchange((long volatile*)destination, exchange, comperand);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_get_cpu_count(uint32_t* cpu_count)
|
||||
{
|
||||
SYSTEM_INFO system_information;
|
||||
GetNativeSystemInfo(&system_information);
|
||||
*cpu_count = system_information.dwNumberOfProcessors;
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
bool
|
||||
ebpf_is_preemptable()
|
||||
{
|
||||
return _ebpf_platform_is_preemptable;
|
||||
}
|
||||
|
||||
bool
|
||||
ebpf_is_non_preepmtable_work_item_supported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ebpf_get_current_cpu()
|
||||
{
|
||||
return GetCurrentProcessorNumber();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ebpf_get_current_thread_id()
|
||||
{
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_allocate_non_preemptable_work_item(
|
||||
epbf_non_preepmtable_work_item_t** work_item,
|
||||
uint32_t cpu_id,
|
||||
void (*work_item_routine)(void* work_item_context, void* parameter_1),
|
||||
void* work_item_context)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(work_item);
|
||||
UNREFERENCED_PARAMETER(cpu_id);
|
||||
UNREFERENCED_PARAMETER(work_item_routine);
|
||||
UNREFERENCED_PARAMETER(work_item_context);
|
||||
return EBPF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_free_non_preemptable_work_item(epbf_non_preepmtable_work_item_t* work_item)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(work_item);
|
||||
}
|
||||
|
||||
bool
|
||||
ebpf_queue_non_preemptable_work_item(epbf_non_preepmtable_work_item_t* work_item, void* parameter_1)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(work_item);
|
||||
UNREFERENCED_PARAMETER(parameter_1);
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef struct _ebpf_timer_work_item
|
||||
{
|
||||
TP_TIMER* threadpool_timer;
|
||||
void (*work_item_routine)(void* work_item_context);
|
||||
void* work_item_context;
|
||||
} ebpf_timer_work_item_t;
|
||||
|
||||
void
|
||||
_ebpf_timer_callback(_Inout_ TP_CALLBACK_INSTANCE* instance, _Inout_opt_ void* Context, _Inout_ TP_TIMER* Timer)
|
||||
{
|
||||
ebpf_timer_work_item_t* timer_work_item = reinterpret_cast<ebpf_timer_work_item_t*>(Context);
|
||||
UNREFERENCED_PARAMETER(instance);
|
||||
UNREFERENCED_PARAMETER(Timer);
|
||||
|
||||
timer_work_item->work_item_routine(timer_work_item->work_item_context);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_allocate_timer_work_item(
|
||||
ebpf_timer_work_item_t** work_item, void (*work_item_routine)(void* work_item_context), void* work_item_context)
|
||||
{
|
||||
*work_item = (ebpf_timer_work_item_t*)ebpf_allocate(sizeof(ebpf_timer_work_item_t), EBPF_MEMORY_NO_EXECUTE);
|
||||
|
||||
if (*work_item == NULL)
|
||||
goto Error;
|
||||
|
||||
(*work_item)->threadpool_timer = CreateThreadpoolTimer(_ebpf_timer_callback, *work_item, NULL);
|
||||
if ((*work_item)->threadpool_timer == NULL)
|
||||
goto Error;
|
||||
|
||||
(*work_item)->work_item_routine = work_item_routine;
|
||||
(*work_item)->work_item_context = work_item_context;
|
||||
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
|
||||
Error:
|
||||
if (*work_item != NULL) {
|
||||
if ((*work_item)->threadpool_timer != NULL)
|
||||
CloseThreadpoolTimer((*work_item)->threadpool_timer);
|
||||
|
||||
ebpf_free(*work_item);
|
||||
}
|
||||
return EBPF_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
#define MICROSECONDS_PER_TICK 10
|
||||
#define MICROSECONDS_PER_MILLISECOND 1000
|
||||
|
||||
void
|
||||
ebpf_schedule_timer_work_item(ebpf_timer_work_item_t* work_item, uint32_t elaped_microseconds)
|
||||
{
|
||||
int64_t due_time;
|
||||
due_time = -static_cast<int64_t>(elaped_microseconds) * MICROSECONDS_PER_TICK;
|
||||
|
||||
SetThreadpoolTimer(
|
||||
work_item->threadpool_timer,
|
||||
reinterpret_cast<FILETIME*>(&due_time),
|
||||
0,
|
||||
elaped_microseconds / MICROSECONDS_PER_MILLISECOND);
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_free_timer_work_item(ebpf_timer_work_item_t* work_item)
|
||||
{
|
||||
WaitForThreadpoolTimerCallbacks(work_item->threadpool_timer, true);
|
||||
CloseThreadpoolTimer(work_item->threadpool_timer);
|
||||
ebpf_free(work_item);
|
||||
}
|
||||
|
|
|
@ -135,6 +135,9 @@
|
|||
<ClInclude Include="ebpf_l2_hook.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libs\epoch\kernel\epoch_kernel.vcxproj">
|
||||
<Project>{fb2680fb-13cf-400c-8a5d-042c0ac20a3f}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\libs\execution_context\kernel\execution_context_kernel.vcxproj">
|
||||
<Project>{26e7ed0b-c128-4d7c-a90e-c246def40ad3}</Project>
|
||||
</ProjectReference>
|
||||
|
|
|
@ -196,7 +196,7 @@ EbpfCoreInitDriverObjects(
|
|||
goto Exit;
|
||||
}
|
||||
|
||||
status = ebpf_error_code_to_ntstatus(ebpf_core_initialize());
|
||||
status = ebpf_error_code_to_ntstatus(ebpf_core_initiate());
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
@ -262,6 +262,8 @@ EbpfCoreEvtIoDeviceControl(
|
|||
}
|
||||
|
||||
if (input_buffer != NULL) {
|
||||
size_t minimum_request_size = 0;
|
||||
size_t minimum_reply_size = 0;
|
||||
|
||||
status = ebpf_hook_register_callouts(_wdm_device_object);
|
||||
// non fatal for now while testing
|
||||
|
@ -272,23 +274,13 @@ EbpfCoreEvtIoDeviceControl(
|
|||
goto Done;
|
||||
}
|
||||
|
||||
if (user_request->id >= sizeof(EbpfProtocolHandlers) / sizeof(EbpfProtocolHandlers[0])) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
status = ebpf_error_code_to_ntstatus(ebpf_core_get_protocol_handler_properties(
|
||||
user_request->id, &minimum_request_size, &minimum_reply_size));
|
||||
if (status != STATUS_SUCCESS)
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (user_request->length < EbpfProtocolHandlers[user_request->id].minimum_request_size) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (!EbpfProtocolHandlers[user_request->id].dispatch.protocol_handler_no_reply) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// Be aware: Input and output buffer point to the same memory.
|
||||
if (EbpfProtocolHandlers[user_request->id].minimum_reply_size > 0) {
|
||||
if (minimum_reply_size > 0) {
|
||||
// Retrieve output buffer associated with the request object
|
||||
status = WdfRequestRetrieveOutputBuffer(
|
||||
request, output_buffer_length, &output_buffer, &actual_output_length);
|
||||
|
@ -302,21 +294,15 @@ EbpfCoreEvtIoDeviceControl(
|
|||
goto Done;
|
||||
}
|
||||
|
||||
if (actual_output_length < EbpfProtocolHandlers[user_request->id].minimum_reply_size) {
|
||||
if (actual_output_length < minimum_reply_size) {
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
goto Done;
|
||||
}
|
||||
user_reply = output_buffer;
|
||||
}
|
||||
|
||||
if (EbpfProtocolHandlers[user_request->id].minimum_reply_size == 0) {
|
||||
status = ebpf_error_code_to_ntstatus(
|
||||
EbpfProtocolHandlers[user_request->id].dispatch.protocol_handler_no_reply(user_request));
|
||||
} else {
|
||||
status = ebpf_error_code_to_ntstatus(
|
||||
EbpfProtocolHandlers[user_request->id].dispatch.protocol_handler_with_reply(
|
||||
user_request, user_reply, (uint16_t)actual_output_length));
|
||||
}
|
||||
status = ebpf_error_code_to_ntstatus(ebpf_core_invoke_protocol_handler(
|
||||
user_request->id, user_request, user_reply, (uint16_t)actual_output_length));
|
||||
|
||||
// Fill out the rest of the out buffer after processing the input
|
||||
// buffer.
|
||||
|
@ -362,7 +348,7 @@ DriverEntry(_In_ DRIVER_OBJECT* driver_object, _In_ UNICODE_STRING* registry_pat
|
|||
|
||||
ebpf_hook_register_callouts(_wdm_device_object);
|
||||
// ignore status. at boot, registration can fail.
|
||||
// we will try to re-register during prog load.
|
||||
// we will try to re-register during program load.
|
||||
|
||||
Exit:
|
||||
|
||||
|
|
|
@ -4,10 +4,16 @@
|
|||
*/
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch2\catch.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <WinSock2.h>
|
||||
|
||||
#include "catch2\catch.hpp"
|
||||
#include "ebpf_api.h"
|
||||
#include "ebpf_core.h"
|
||||
#include "ebpf_epoch.h"
|
||||
#include "ebpf_protocol.h"
|
||||
#include "mock.h"
|
||||
#include "tlv.h"
|
||||
|
@ -19,7 +25,6 @@ namespace ebpf {
|
|||
}; // namespace ebpf
|
||||
|
||||
#include "unwind_helper.h"
|
||||
#include <WinSock2.h>
|
||||
|
||||
ebpf_handle_t
|
||||
GlueCreateFileW(
|
||||
|
@ -70,33 +75,42 @@ GlueDeviceIoControl(
|
|||
ebpf_operation_header_t* user_reply = nullptr;
|
||||
*lpBytesReturned = 0;
|
||||
auto request_id = user_request->id;
|
||||
if (request_id >= _countof(EbpfProtocolHandlers)) {
|
||||
size_t minimum_request_size = 0;
|
||||
size_t minimum_reply_size = 0;
|
||||
|
||||
retval = ebpf_core_get_protocol_handler_properties(request_id, &minimum_request_size, &minimum_reply_size);
|
||||
if (retval != EBPF_ERROR_SUCCESS)
|
||||
goto Fail;
|
||||
|
||||
if (user_request->length < minimum_request_size) {
|
||||
retval = EBPF_ERROR_INVALID_PARAMETER;
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if (user_request->length < EbpfProtocolHandlers[request_id].minimum_request_size) {
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if (EbpfProtocolHandlers[request_id].minimum_reply_size > 0) {
|
||||
if (minimum_reply_size > 0) {
|
||||
user_reply = reinterpret_cast<decltype(user_reply)>(lpOutBuffer);
|
||||
if (!user_reply) {
|
||||
retval = EBPF_ERROR_INVALID_PARAMETER;
|
||||
goto Fail;
|
||||
}
|
||||
if (nOutBufferSize < EbpfProtocolHandlers[request_id].minimum_reply_size) {
|
||||
if (nOutBufferSize < minimum_reply_size) {
|
||||
retval = EBPF_ERROR_INVALID_PARAMETER;
|
||||
goto Fail;
|
||||
}
|
||||
user_reply->length = static_cast<uint16_t>(nOutBufferSize);
|
||||
user_reply->id = user_request->id;
|
||||
*lpBytesReturned = user_reply->length;
|
||||
}
|
||||
if (EbpfProtocolHandlers[request_id].minimum_reply_size == 0) {
|
||||
retval = EbpfProtocolHandlers[request_id].dispatch.protocol_handler_no_reply(user_request);
|
||||
} else {
|
||||
retval = EbpfProtocolHandlers[request_id].dispatch.protocol_handler_with_reply(
|
||||
user_request, user_reply, static_cast<uint16_t>(nOutBufferSize));
|
||||
}
|
||||
|
||||
retval =
|
||||
ebpf_core_invoke_protocol_handler(request_id, user_request, user_reply, static_cast<uint16_t>(nOutBufferSize));
|
||||
|
||||
if (retval != EBPF_ERROR_SUCCESS)
|
||||
goto Fail;
|
||||
|
||||
return TRUE;
|
||||
|
||||
Fail:
|
||||
if (retval != EBPF_ERROR_SUCCESS) {
|
||||
switch (retval) {
|
||||
case EBPF_ERROR_OUT_OF_RESOURCES:
|
||||
|
@ -115,13 +129,8 @@ GlueDeviceIoControl(
|
|||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
break;
|
||||
}
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
Fail:
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -162,7 +171,7 @@ TEST_CASE("droppacket-jit", "[droppacket_jit]")
|
|||
ebpf_core_terminate();
|
||||
});
|
||||
|
||||
REQUIRE(ebpf_core_initialize() == EBPF_ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_core_initiate() == EBPF_ERROR_SUCCESS);
|
||||
ec_initialized = true;
|
||||
|
||||
REQUIRE(ebpf_api_initiate() == ERROR_SUCCESS);
|
||||
|
@ -238,7 +247,7 @@ TEST_CASE("droppacket-interpret", "[droppacket_interpret]")
|
|||
});
|
||||
uint32_t result = 0;
|
||||
|
||||
REQUIRE(ebpf_core_initialize() == EBPF_ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_core_initiate() == EBPF_ERROR_SUCCESS);
|
||||
ec_initialized = true;
|
||||
|
||||
REQUIRE(ebpf_api_initiate() == ERROR_SUCCESS);
|
||||
|
@ -308,7 +317,7 @@ TEST_CASE("enum section", "[enum sections]")
|
|||
ebpf_core_terminate();
|
||||
});
|
||||
|
||||
REQUIRE(ebpf_core_initialize() == EBPF_ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_core_initiate() == EBPF_ERROR_SUCCESS);
|
||||
ec_initialized = true;
|
||||
REQUIRE(ebpf_api_initiate() == ERROR_SUCCESS);
|
||||
api_initialized = true;
|
||||
|
@ -355,7 +364,7 @@ TEST_CASE("verify section", "[verify section]")
|
|||
ebpf_core_terminate();
|
||||
});
|
||||
|
||||
REQUIRE(ebpf_core_initialize() == EBPF_ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_core_initiate() == EBPF_ERROR_SUCCESS);
|
||||
api_initialized = true;
|
||||
REQUIRE(ebpf_api_initiate() == ERROR_SUCCESS);
|
||||
ec_initialized = true;
|
||||
|
@ -437,7 +446,7 @@ TEST_CASE("bindmonitor-interpret", "[bindmonitor_interpret]")
|
|||
ebpf_core_terminate();
|
||||
});
|
||||
|
||||
REQUIRE(ebpf_core_initialize() == EBPF_ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_core_initiate() == EBPF_ERROR_SUCCESS);
|
||||
ec_initialized = true;
|
||||
|
||||
REQUIRE(ebpf_api_initiate() == ERROR_SUCCESS);
|
||||
|
@ -470,13 +479,13 @@ TEST_CASE("bindmonitor-interpret", "[bindmonitor_interpret]")
|
|||
|
||||
ebpf_handle_t test_handle;
|
||||
REQUIRE(
|
||||
ebpf_api_lookup_map(
|
||||
ebpf_api_get_pinned_map(
|
||||
reinterpret_cast<const uint8_t*>(process_maps_name.c_str()),
|
||||
static_cast<uint32_t>(process_maps_name.size()),
|
||||
&test_handle) == ERROR_SUCCESS);
|
||||
REQUIRE(test_handle == map_handles[0]);
|
||||
REQUIRE(
|
||||
ebpf_api_lookup_map(
|
||||
ebpf_api_get_pinned_map(
|
||||
reinterpret_cast<const uint8_t*>(limit_maps_name.c_str()),
|
||||
static_cast<uint32_t>(limit_maps_name.size()),
|
||||
&test_handle) == ERROR_SUCCESS);
|
||||
|
@ -491,12 +500,12 @@ TEST_CASE("bindmonitor-interpret", "[bindmonitor_interpret]")
|
|||
reinterpret_cast<const uint8_t*>(limit_maps_name.c_str()), static_cast<uint32_t>(limit_maps_name.size())) ==
|
||||
ERROR_SUCCESS);
|
||||
REQUIRE(
|
||||
ebpf_api_lookup_map(
|
||||
ebpf_api_get_pinned_map(
|
||||
reinterpret_cast<const uint8_t*>(process_maps_name.c_str()),
|
||||
static_cast<uint32_t>(process_maps_name.size()),
|
||||
&test_handle) == ERROR_NOT_FOUND);
|
||||
REQUIRE(
|
||||
ebpf_api_lookup_map(
|
||||
ebpf_api_get_pinned_map(
|
||||
reinterpret_cast<const uint8_t*>(limit_maps_name.c_str()),
|
||||
static_cast<uint32_t>(limit_maps_name.size()),
|
||||
&test_handle) == ERROR_NOT_FOUND);
|
||||
|
@ -583,7 +592,7 @@ TEST_CASE("enumerate_and_query_programs", "[enumerate_and_query_programs]")
|
|||
ebpf_api_free_string(section_name);
|
||||
});
|
||||
|
||||
REQUIRE(ebpf_core_initialize() == EBPF_ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_core_initiate() == EBPF_ERROR_SUCCESS);
|
||||
ec_initialized = true;
|
||||
|
||||
REQUIRE(ebpf_api_initiate() == ERROR_SUCCESS);
|
||||
|
@ -634,3 +643,48 @@ TEST_CASE("enumerate_and_query_programs", "[enumerate_and_query_programs]")
|
|||
REQUIRE(ebpf_api_get_next_program(program_handle, &program_handle) == ERROR_SUCCESS);
|
||||
REQUIRE(program_handle == INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
TEST_CASE("epoch_test_single_epoch", "[epoch_test_single_epoch]")
|
||||
{
|
||||
bool ep_initialized = false;
|
||||
_unwind_helper on_exit([&] {
|
||||
if (ep_initialized)
|
||||
ebpf_epoch_terminate();
|
||||
});
|
||||
|
||||
REQUIRE(ebpf_epoch_initiate() == EBPF_ERROR_SUCCESS);
|
||||
ep_initialized = true;
|
||||
|
||||
REQUIRE(ebpf_epoch_enter() == EBPF_ERROR_SUCCESS);
|
||||
void* memory = ebpf_epoch_allocate(10, EBPF_MEMORY_NO_EXECUTE);
|
||||
ebpf_epoch_free(memory);
|
||||
ebpf_epoch_exit();
|
||||
ebpf_epoch_flush();
|
||||
}
|
||||
|
||||
TEST_CASE("epoch_test_two_threads", "[epoch_test_two_threads]")
|
||||
{
|
||||
bool ep_initialized = false;
|
||||
_unwind_helper on_exit([&] {
|
||||
if (ep_initialized)
|
||||
ebpf_epoch_terminate();
|
||||
});
|
||||
|
||||
REQUIRE(ebpf_epoch_initiate() == EBPF_ERROR_SUCCESS);
|
||||
ep_initialized = true;
|
||||
|
||||
auto epoch = []() {
|
||||
ebpf_epoch_enter();
|
||||
void* memory = ebpf_epoch_allocate(10, EBPF_MEMORY_NO_EXECUTE);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
ebpf_epoch_free(memory);
|
||||
ebpf_epoch_exit();
|
||||
ebpf_epoch_flush();
|
||||
};
|
||||
|
||||
std::thread thread_1(epoch);
|
||||
std::thread thread_2(epoch);
|
||||
thread_1.join();
|
||||
thread_2.join();
|
||||
}
|
|
@ -112,6 +112,9 @@
|
|||
<ProjectReference Include="..\..\ebpf\libs\api\api.vcxproj">
|
||||
<Project>{c8bf60c3-40a9-43ad-891a-8aa34f1c3a68}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\ebpf\libs\epoch\user\epoch_user.vcxproj">
|
||||
<Project>{a7e21439-b561-43f0-9ddd-237425f42bcd}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\ebpf\libs\execution_context\user\execution_context_user.vcxproj">
|
||||
<Project>{18127b0d-8381-4afe-9a3a-cf53241992d3}</Project>
|
||||
</ProjectReference>
|
||||
|
|
|
@ -10,69 +10,71 @@
|
|||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
WSAData data;
|
||||
int
|
||||
main(int argc, const char** argv)
|
||||
{
|
||||
WSAData data;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s target_ip\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s target_ip\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (WSAStartup(2, &data) != 0) {
|
||||
printf("WSAStartup failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (WSAStartup(2, &data) != 0) {
|
||||
printf("WSAStartup failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned short us = 0x1234;
|
||||
us = us >> 8 | us << 8;
|
||||
printf("%.2X\n", us);
|
||||
Sleep(10000);
|
||||
unsigned short us = 0x1234;
|
||||
us = us >> 8 | us << 8;
|
||||
printf("%.2X\n", us);
|
||||
Sleep(10000);
|
||||
|
||||
auto socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nullptr, 0, 0);
|
||||
if (socket == INVALID_SOCKET) {
|
||||
printf("WSASocket failed\n");
|
||||
return 1;
|
||||
}
|
||||
ADDRINFOA *addrinfo = nullptr;
|
||||
auto socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nullptr, 0, 0);
|
||||
if (socket == INVALID_SOCKET) {
|
||||
printf("WSASocket failed\n");
|
||||
return 1;
|
||||
}
|
||||
ADDRINFOA* addrinfo = nullptr;
|
||||
|
||||
if (getaddrinfo(argv[1], "53", nullptr, &addrinfo) != 0) {
|
||||
printf("getaddrinfo failed \n");
|
||||
return 1;
|
||||
}
|
||||
if (getaddrinfo(argv[1], "53", nullptr, &addrinfo) != 0) {
|
||||
printf("getaddrinfo failed \n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (connect(socket, addrinfo->ai_addr,
|
||||
static_cast<int>(addrinfo->ai_addrlen)) != 0) {
|
||||
printf("connect failed \n");
|
||||
return 1;
|
||||
}
|
||||
if (connect(socket, addrinfo->ai_addr, static_cast<int>(addrinfo->ai_addrlen)) != 0) {
|
||||
printf("connect failed \n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<WSABUF> buffers(1024);
|
||||
char a = 'A';
|
||||
for (auto &b : buffers) {
|
||||
b.buf = &a;
|
||||
b.len = 0;
|
||||
}
|
||||
DWORD bytes_sent;
|
||||
std::vector<WSABUF> buffers(1024);
|
||||
char a = 'A';
|
||||
for (auto& b : buffers) {
|
||||
b.buf = &a;
|
||||
b.len = 0;
|
||||
}
|
||||
DWORD bytes_sent;
|
||||
|
||||
volatile long packet_sent = 0;
|
||||
std::vector<std::thread> threads(4);
|
||||
volatile long packet_sent = 0;
|
||||
std::vector<std::thread> threads(4);
|
||||
|
||||
for (auto &t : threads) {
|
||||
t = std::thread([&] {
|
||||
for (;;) {
|
||||
if (WSASend(socket, buffers.data(), static_cast<DWORD>(buffers.size()),
|
||||
&bytes_sent, 0, nullptr, nullptr) != 0) {
|
||||
printf("WSASend failed\n");
|
||||
return 1;
|
||||
}
|
||||
InterlockedAdd(&packet_sent, static_cast<LONG>(buffers.size()));
|
||||
}
|
||||
});
|
||||
}
|
||||
for (auto& t : threads) {
|
||||
t = std::thread([&] {
|
||||
for (;;) {
|
||||
if (WSASend(
|
||||
socket, buffers.data(), static_cast<DWORD>(buffers.size()), &bytes_sent, 0, nullptr, nullptr) !=
|
||||
0) {
|
||||
printf("WSASend failed\n");
|
||||
return 1;
|
||||
}
|
||||
InterlockedAdd(&packet_sent, static_cast<long>(buffers.size()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
long old = packet_sent;
|
||||
Sleep(1000);
|
||||
printf("%d\n", packet_sent - old);
|
||||
}
|
||||
for (;;) {
|
||||
long old = packet_sent;
|
||||
Sleep(1000);
|
||||
printf("%d\n", packet_sent - old);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ stats(int argc, char** argv)
|
|||
uint64_t pid;
|
||||
process_entry_t process_entry;
|
||||
|
||||
result = ebpf_api_lookup_map(process_map, sizeof(process_map), &map);
|
||||
result = ebpf_api_get_pinned_map(process_map, sizeof(process_map), &map);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to look up eBPF map: %d\n", result);
|
||||
return 1;
|
||||
|
@ -111,7 +111,7 @@ limit(int argc, char** argv)
|
|||
uint32_t result;
|
||||
uint32_t key = 0;
|
||||
|
||||
result = ebpf_api_lookup_map(limits_map, sizeof(limits_map), &map);
|
||||
result = ebpf_api_get_pinned_map(limits_map, sizeof(limits_map), &map);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to look up eBPF map: %d\n", result);
|
||||
return 1;
|
||||
|
|
Загрузка…
Ссылка в новой задаче