diff --git a/include/ebpf_extension.h b/include/ebpf_extension.h index 760feb18ff..2c57893973 100644 --- a/include/ebpf_extension.h +++ b/include/ebpf_extension.h @@ -87,13 +87,13 @@ typedef struct _ebpf_extension_program_dispatch_table typedef struct _ebpf_extension_data { - uint16_t version; - size_t size; + ebpf_extension_header_t header; const void* data; } ebpf_extension_data_t; typedef struct _ebpf_attach_provider_data { + ebpf_extension_header_t header; ebpf_program_type_t supported_program_type; bpf_attach_type_t bpf_attach_type; enum bpf_link_type link_type; @@ -118,9 +118,4 @@ typedef struct _ebpf_execution_context_state const void* next_program; uint32_t count; } tail_call_state; -} ebpf_execution_context_state_t; - -#define EBPF_ATTACH_CLIENT_DATA_VERSION 0 -#define EBPF_ATTACH_PROVIDER_DATA_VERSION 1 -#define EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION 0 -#define EBPF_MAX_GENERAL_HELPER_FUNCTION 0xFFFF +} ebpf_execution_context_state_t; \ No newline at end of file diff --git a/include/ebpf_program_attach_type_guids.h b/include/ebpf_program_attach_type_guids.h index b0cd7fa2be..a36a397fee 100644 --- a/include/ebpf_program_attach_type_guids.h +++ b/include/ebpf_program_attach_type_guids.h @@ -21,69 +21,98 @@ extern "C" __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_XDP = { 0x85e0d8ef, 0x579e, 0x4931, {0xb0, 0x72, 0x8e, 0xe2, 0x26, 0xbb, 0x2e, 0x9d}}; +#define EBPF_ATTACH_TYPE_BIND_GUID \ + { \ + 0xb9707e04, 0x8127, 0x4c72, { 0x83, 0x3e, 0x05, 0xb1, 0xfb, 0x43, 0x94, 0x96 } \ + } /** @brief Attach type for handling socket bind() requests. * * Program type: \ref EBPF_PROGRAM_TYPE_BIND */ - __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_BIND = { - 0xb9707e04, 0x8127, 0x4c72, {0x83, 0x3e, 0x05, 0xb1, 0xfb, 0x43, 0x94, 0x96}}; + __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_BIND = EBPF_ATTACH_TYPE_BIND_GUID; +#define EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT_GUID \ + { \ + 0xa82e37b1, 0xaee7, 0x11ec, { 0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee } \ + } /** @brief The programs attached to the INET4_CONNECT hook will be invoked for * connect() calls on TCP or UDP sockets or when a UDP socket sends a packet to * a unique remote address/port tuple. * * Program type: \ref EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR */ - __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT = { - 0xa82e37b1, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}}; + __declspec(selectany) + ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT = EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT_GUID; +#define EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT_GUID \ + { \ + 0xa82e37b2, 0xaee7, 0x11ec, { 0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee } \ + } /** @brief The programs attached to the INET6_CONNECT hook will be invoked for * connect() calls on TCP or UDP sockets or when a UDP socket sends a packet to * a unique remote address/port tuple. * * Program type: \ref EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR */ - __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT = { - 0xa82e37b2, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}}; + __declspec(selectany) + ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT = EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT_GUID; +#define EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT_GUID \ + { \ + 0xa82e37b3, 0xaee7, 0x11ec, { 0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee } \ + } /** @brief The programs attached to the INET4_RECV_ACCEPT hook will get invoked for * TCP accept() calls or for the first unicast UDP packet from a unique remote * address/port tuple. * * Program type: \ref EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR */ - __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT = { - 0xa82e37b3, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}}; + __declspec(selectany) + ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT = EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT_GUID; +#define EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT_GUID \ + { \ + 0xa82e37b4, 0xaee7, 0x11ec, { 0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee } \ + } /** @brief The programs attached to the INET6_RECV_ACCEPT hook will get invoked for * TCP accept() calls or for the first unicast UDP packet from a unique remote * address/port tuple. * * Program type: \ref EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR */ - __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT = { - 0xa82e37b4, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}}; + __declspec(selectany) + ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT = EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT_GUID; +#define EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS_GUID \ + { \ + 0x837d02cd, 0x3251, 0x4632, { 0x8d, 0x94, 0x60, 0xd3, 0xb4, 0x57, 0x69, 0xf2 } \ + } /** @brief Attach type for handling socket event notifications. * * Program type: \ref EBPF_PROGRAM_TYPE_SOCK_OPS */ - __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS = { - 0x837d02cd, 0x3251, 0x4632, {0x8d, 0x94, 0x60, 0xd3, 0xb4, 0x57, 0x69, 0xf2}}; + __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS = EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS_GUID; + +#define EBPF_ATTACH_TYPE_SAMPLE_GUID \ + { \ + 0xf788ef4b, 0x207d, 0x4dc3, { 0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c } \ + } /** @brief Attach type implemented by eBPF Sample Extension driver, used for testing. * * Program type: \ref EBPF_PROGRAM_TYPE_SAMPLE */ - __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_SAMPLE = { - 0xf788ef4b, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}}; + __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_SAMPLE = EBPF_ATTACH_TYPE_SAMPLE_GUID; +#define EBPF_ATTACH_TYPE_XDP_TEST_GUID \ + { \ + 0x0dccc15d, 0xa5f9, 0x4dc1, { 0xac, 0x79, 0xfa, 0x25, 0xee, 0xf2, 0x15, 0xc3 } \ + } /** @brief Attach type for handling incoming packets as early as possible. * * Program type: \ref EBPF_PROGRAM_TYPE_XDP_TEST */ - __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_XDP_TEST = { - 0x0dccc15d, 0xa5f9, 0x4dc1, {0xac, 0x79, 0xfa, 0x25, 0xee, 0xf2, 0x15, 0xc3}}; + __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_XDP_TEST = EBPF_ATTACH_TYPE_XDP_TEST_GUID; // // Program Types. diff --git a/include/ebpf_program_types.h b/include/ebpf_program_types.h index b1aabfb925..744fc602ad 100644 --- a/include/ebpf_program_types.h +++ b/include/ebpf_program_types.h @@ -4,22 +4,15 @@ #include "ebpf_base.h" #include "ebpf_result.h" - -#include -#if !defined(NO_CRT) && !defined(_NO_CRT_STDIO_INLINE) -#include -#else -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef unsigned short wchar_t; -#endif +#include "ebpf_windows.h" #define EBPF_MAX_PROGRAM_DESCRIPTOR_NAME_LENGTH 256 #define EBPF_MAX_HELPER_FUNCTION_NAME_LENGTH 256 typedef struct _ebpf_program_type_descriptor { + ebpf_extension_header_t header; + // The following fields are available in version EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0 and later. const char* name; const ebpf_context_descriptor_t* context_descriptor; GUID program_type; @@ -29,6 +22,8 @@ typedef struct _ebpf_program_type_descriptor typedef struct _ebpf_helper_function_prototype { + ebpf_extension_header_t header; + // The following fields are available in version EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0 and later. uint32_t helper_id; const char* name; ebpf_return_type_t return_type; @@ -37,7 +32,8 @@ typedef struct _ebpf_helper_function_prototype typedef struct _ebpf_program_info { - ebpf_program_type_descriptor_t program_type_descriptor; + ebpf_extension_header_t header; + const ebpf_program_type_descriptor_t* program_type_descriptor; uint32_t count_of_program_type_specific_helpers; const ebpf_helper_function_prototype_t* program_type_specific_helper_prototype; uint32_t count_of_global_helpers; @@ -46,6 +42,7 @@ typedef struct _ebpf_program_info typedef struct _ebpf_helper_function_addresses { + ebpf_extension_header_t header; uint32_t helper_function_count; uint64_t* helper_function_address; } ebpf_helper_function_addresses_t; @@ -66,6 +63,7 @@ typedef void (*ebpf_program_context_destroy_t)( typedef struct _ebpf_program_data { + ebpf_extension_header_t header; const ebpf_program_info_t* program_info; ///< Pointer to program information. const ebpf_helper_function_addresses_t* program_type_specific_helper_function_addresses; ///< Pointer to program type specific helper function @@ -79,6 +77,7 @@ typedef struct _ebpf_program_data typedef struct _ebpf_program_section_info { + ebpf_extension_header_t header; const wchar_t* section_name; const GUID* program_type; const GUID* attach_type; diff --git a/include/ebpf_structs.h b/include/ebpf_structs.h index 926921d8ee..a4b24db833 100644 --- a/include/ebpf_structs.h +++ b/include/ebpf_structs.h @@ -10,16 +10,6 @@ #include "ebpf_windows.h" -#if !defined(NO_CRT) && !defined(_NO_CRT_STDIO_INLINE) -#include -#include -#else -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -#endif - #define MAX_TAIL_CALL_CNT 33 #define BPF_ENUM_TO_STRING(X) #X diff --git a/include/ebpf_windows.h b/include/ebpf_windows.h index c02e0c7a9b..27162404f5 100644 --- a/include/ebpf_windows.h +++ b/include/ebpf_windows.h @@ -5,16 +5,24 @@ #ifdef _MSC_VER #include #else +typedef uint8_t GUID[16]; +#endif + #if !defined(NO_CRT) && !defined(_NO_CRT_STDIO_INLINE) +#include +#include #include #else typedef unsigned char uint8_t; -#endif -typedef uint8_t GUID[16]; +typedef unsigned short uint16_t; +typedef unsigned short wchar_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +typedef unsigned long long size_t; #endif // This file contains eBPF definitions needed by eBPF programs as well as -// the verifier and execution context. +// the verifier, execution context and extension drivers. #define EBPF_ROOT_REGISTRY_PATH L"\\Registry\\Machine\\Software\\eBPF" #define EBPF_ROOT_RELATIVE_PATH L"Software\\eBPF" @@ -49,3 +57,30 @@ typedef enum _ebpf_helper_function EBPF_UPDATE_ELEMENT = 2, ///< Update map element. EBPF_DELETE_ELEMENT = 3, ///< Delete a map element. } ebpf_helper_function_t; + +#define EBPF_MAX_GENERAL_HELPER_FUNCTION 0xFFFF + +// Version 0 of the eBPF extension data structures. +#define EBPF_ATTACH_CLIENT_DATA_VERSION_0 0 +#define EBPF_ATTACH_PROVIDER_DATA_VERSION_0 0 +#define EBPF_PROGRAM_INFORMATION_CLIENT_DATA_VERSION_0 0 +#define EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0 0 +#define EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0 0 +#define EBPF_PROGRAM_INFORMATION_VERSION_0 0 +#define EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0 0 +#define EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0 0 +#define EBPF_PROGRAM_DATA_VERSION_0 0 +#define EBPF_PROGRAM_SECTION_VERSION_0 0 + +/** + * @brief Header of an eBPF extension data structure. + * Every eBPF extension data structure must start with this header. + * New fields can be added to the end eBPF extension data structure + * without breaking backward compatibility. The version field must be + * updated only if the new data structure is not backward compatible. + */ +typedef struct _ebpf_extension_header +{ + uint16_t version; ///< Version of the extension data structure. + size_t size; ///< Size of the extension data structure. +} ebpf_extension_header_t; diff --git a/libs/api_common/store_helper_internal.cpp b/libs/api_common/store_helper_internal.cpp index d5478c3c6a..e568f53f96 100644 --- a/libs/api_common/store_helper_internal.cpp +++ b/libs/api_common/store_helper_internal.cpp @@ -100,6 +100,7 @@ _load_program_data_information( uint32_t bpf_program_type; ebpf_program_type_t* program_type = nullptr; ebpf_program_info_t* program_information = nullptr; + ebpf_program_type_descriptor_t* program_type_descriptor = nullptr; uint32_t helper_count; wchar_t* helper_name = nullptr; @@ -174,16 +175,25 @@ _load_program_data_information( goto Exit; } - program_information->program_type_descriptor.name = cxplat_duplicate_string(program_type_name_string.c_str()); - if (program_information->program_type_descriptor.name == nullptr) { + program_information->program_type_descriptor = + (ebpf_program_type_descriptor_t*)ebpf_allocate(sizeof(ebpf_program_type_descriptor_t)); + if (program_information->program_type_descriptor == nullptr) { result = EBPF_NO_MEMORY; goto Exit; } - program_information->program_type_descriptor.context_descriptor = descriptor; + program_type_descriptor = + const_cast(program_information->program_type_descriptor); + + program_type_descriptor->name = cxplat_duplicate_string(program_type_name_string.c_str()); + if (program_type_descriptor->name == nullptr) { + result = EBPF_NO_MEMORY; + goto Exit; + } + program_type_descriptor->context_descriptor = descriptor; descriptor = nullptr; - program_information->program_type_descriptor.is_privileged = !!is_privileged; - program_information->program_type_descriptor.bpf_prog_type = bpf_program_type; - program_information->program_type_descriptor.program_type = *program_type; + program_type_descriptor->is_privileged = !!is_privileged; + program_type_descriptor->bpf_prog_type = bpf_program_type; + program_type_descriptor->program_type = *program_type; if (helper_count > 0) { // Read the helper functions prototypes. diff --git a/libs/api_common/windows_helpers.cpp b/libs/api_common/windows_helpers.cpp index 7c0d877f23..7a6db836c2 100644 --- a/libs/api_common/windows_helpers.cpp +++ b/libs/api_common/windows_helpers.cpp @@ -47,7 +47,10 @@ get_helper_prototype_windows(int32_t n) } EbpfHelperPrototype verifier_prototype = {0}; - verifier_prototype.context_descriptor = info->program_type_descriptor.context_descriptor; + if (info->program_type_descriptor == nullptr) { + throw std::runtime_error(std::string("program type descriptor not found.")); + } + verifier_prototype.context_descriptor = info->program_type_descriptor->context_descriptor; const ebpf_helper_function_prototype_t* raw_prototype = _get_helper_function_prototype(info, n); if (raw_prototype == nullptr) { diff --git a/libs/api_common/windows_platform_common.cpp b/libs/api_common/windows_platform_common.cpp index 9077b17931..67180c904b 100644 --- a/libs/api_common/windows_platform_common.cpp +++ b/libs/api_common/windows_platform_common.cpp @@ -23,7 +23,7 @@ #include #include -#define GET_PROGRAM_INFO_REPLY_BUFFER_SIZE 2048 +#define GET_PROGRAM_INFO_REPLY_BUFFER_SIZE 4096 static thread_local ebpf_handle_t _program_under_verification = ebpf_handle_invalid; @@ -137,7 +137,17 @@ _get_program_descriptor_from_info(_In_ const ebpf_program_info_t* info, _Outptr_ goto Exit; } - name = cxplat_duplicate_string(info->program_type_descriptor.name); + if (info->program_type_descriptor == nullptr) { + result = EBPF_INVALID_ARGUMENT; + goto Exit; + } + + if (info->program_type_descriptor->context_descriptor == nullptr) { + result = EBPF_INVALID_ARGUMENT; + goto Exit; + } + + name = cxplat_duplicate_string(info->program_type_descriptor->name); if (name == nullptr) { result = EBPF_NO_MEMORY; goto Exit; @@ -150,16 +160,16 @@ _get_program_descriptor_from_info(_In_ const ebpf_program_info_t* info, _Outptr_ } memcpy( (void*)type->context_descriptor, - info->program_type_descriptor.context_descriptor, + info->program_type_descriptor->context_descriptor, sizeof(ebpf_context_descriptor_t)); ebpf_program_type_t* program_type = (ebpf_program_type_t*)ebpf_allocate(sizeof(ebpf_program_type_t)); if (program_type == nullptr) { result = EBPF_NO_MEMORY; goto Exit; } - *program_type = info->program_type_descriptor.program_type; + *program_type = info->program_type_descriptor->program_type; type->platform_specific_data = (uint64_t)program_type; - type->is_privileged = info->program_type_descriptor.is_privileged; + type->is_privileged = info->program_type_descriptor->is_privileged; *descriptor = type; } catch (...) { @@ -285,7 +295,7 @@ get_ebpf_program_type(bpf_prog_type_t bpf_program_type) _load_ebpf_provider_data(); for (auto const& [key, value] : _windows_program_information) { - if (value.get()->program_type_descriptor.bpf_prog_type == (uint32_t)bpf_program_type) { + if (value.get()->program_type_descriptor->bpf_prog_type == (uint32_t)bpf_program_type) { return &key; } } @@ -314,7 +324,7 @@ get_bpf_program_type(_In_ const ebpf_program_type_t* ebpf_program_type) noexcept for (auto const& [key, value] : _windows_program_information) { if (IsEqualGUID(*ebpf_program_type, key)) { - return (bpf_prog_type_t)value.get()->program_type_descriptor.bpf_prog_type; + return (bpf_prog_type_t)value.get()->program_type_descriptor->bpf_prog_type; } } @@ -676,7 +686,7 @@ _load_all_program_data_information() for (uint32_t index = 0; index < program_info_count; index++) { ebpf_program_info_t* info = program_info[index]; program_info[index] = nullptr; - ebpf_program_type_t program_type = info->program_type_descriptor.program_type; + ebpf_program_type_t program_type = info->program_type_descriptor->program_type; _windows_program_information[program_type] = ebpf_program_info_ptr_t(info); EbpfProgramType* program_data = nullptr; diff --git a/libs/execution_context/ebpf_core.c b/libs/execution_context/ebpf_core.c index 5ee5de801d..c2de382fbb 100644 --- a/libs/execution_context/ebpf_core.c +++ b/libs/execution_context/ebpf_core.c @@ -78,7 +78,15 @@ _ebpf_core_is_current_admin(_In_ const void* ctx); #define EBPF_CORE_GLOBAL_HELPER_EXTENSION_VERSION 0 -static ebpf_program_info_t _ebpf_global_helper_program_info = {{"global_helper", NULL, {0}}, 0, NULL}; +static ebpf_program_type_descriptor_t _ebpf_global_helper_program_descriptor = { + EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, sizeof(ebpf_program_type_descriptor_t), "global_helper", NULL, {0}, 0, 0}; +static ebpf_program_info_t _ebpf_global_helper_program_info = { + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &_ebpf_global_helper_program_descriptor, + 0, + NULL, + 0, + NULL}; // Order of elements in this table must match the order of the elements in ebpf_core_helper_function_prototype. static const void* _ebpf_general_helpers[] = { @@ -110,14 +118,13 @@ static const void* _ebpf_general_helpers[] = { }; static const ebpf_helper_function_addresses_t _ebpf_global_helper_function_dispatch_table = { - EBPF_COUNT_OF(_ebpf_general_helpers), (uint64_t*)_ebpf_general_helpers}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(_ebpf_general_helpers), + (uint64_t*)_ebpf_general_helpers}; static const ebpf_program_data_t _ebpf_global_helper_function_program_data = { - &_ebpf_global_helper_program_info, &_ebpf_global_helper_function_dispatch_table}; - -static const ebpf_extension_data_t _ebpf_global_helper_function_extension_data = { - EBPF_CORE_GLOBAL_HELPER_EXTENSION_VERSION, - sizeof(_ebpf_global_helper_function_program_data), - &_ebpf_global_helper_function_program_data}; + {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, + &_ebpf_global_helper_program_info, + &_ebpf_global_helper_function_dispatch_table}; static NPI_PROVIDER_ATTACH_CLIENT_FN _ebpf_general_helper_function_provider_attach_client; static NPI_PROVIDER_DETACH_CLIENT_FN _ebpf_general_helper_function_provider_detach_client; @@ -129,12 +136,12 @@ static const NPI_PROVIDER_CHARACTERISTICS _ebpf_global_helper_function_provider_ _ebpf_general_helper_function_provider_detach_client, NULL, { - EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION, + EBPF_PROGRAM_DATA_VERSION_0, sizeof(NPI_REGISTRATION_INSTANCE), &EBPF_PROGRAM_INFO_EXTENSION_IID, &ebpf_general_helper_function_module_id, 0, - &_ebpf_global_helper_function_extension_data, + &_ebpf_global_helper_function_program_data, }, }; diff --git a/libs/execution_context/ebpf_general_helpers.c b/libs/execution_context/ebpf_general_helpers.c index de8c828bd0..53cb0dfe4b 100644 --- a/libs/execution_context/ebpf_general_helpers.c +++ b/libs/execution_context/ebpf_general_helpers.c @@ -11,34 +11,56 @@ #include "ebpf_structs.h" ebpf_helper_function_prototype_t ebpf_core_helper_function_prototype_array[] = { - {BPF_FUNC_map_lookup_elem, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_map_lookup_elem, "bpf_map_lookup_elem", EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}}, - {BPF_FUNC_map_update_elem, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_map_update_elem, "bpf_map_update_elem", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE, EBPF_ARGUMENT_TYPE_ANYTHING}}, - {BPF_FUNC_map_delete_elem, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_map_delete_elem, "bpf_map_delete_elem", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}}, - {BPF_FUNC_map_lookup_and_delete_elem, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_map_lookup_and_delete_elem, "bpf_map_lookup_and_delete_elem", EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}}, - {BPF_FUNC_tail_call, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_tail_call, "bpf_tail_call", EBPF_RETURN_TYPE_INTEGER_OR_NO_RETURN_IF_SUCCEED, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_OF_PROGRAMS, EBPF_ARGUMENT_TYPE_ANYTHING}}, - {BPF_FUNC_get_prandom_u32, "bpf_get_prandom_u32", EBPF_RETURN_TYPE_INTEGER, {0}}, - {BPF_FUNC_ktime_get_boot_ns, "bpf_ktime_get_boot_ns", EBPF_RETURN_TYPE_INTEGER, {0}}, - {BPF_FUNC_get_smp_processor_id, "bpf_get_smp_processor_id", EBPF_RETURN_TYPE_INTEGER, {0}}, - {BPF_FUNC_ktime_get_ns, "bpf_ktime_get_ns", EBPF_RETURN_TYPE_INTEGER, {0}}, - {BPF_FUNC_csum_diff, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_get_prandom_u32, + "bpf_get_prandom_u32", + EBPF_RETURN_TYPE_INTEGER, + {0}}, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_ktime_get_boot_ns, + "bpf_ktime_get_boot_ns", + EBPF_RETURN_TYPE_INTEGER, + {0}}, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_get_smp_processor_id, + "bpf_get_smp_processor_id", + EBPF_RETURN_TYPE_INTEGER, + {0}}, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_ktime_get_ns, + "bpf_ktime_get_ns", + EBPF_RETURN_TYPE_INTEGER, + {0}}, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_csum_diff, "bpf_csum_diff", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM_OR_NULL, @@ -46,29 +68,34 @@ ebpf_helper_function_prototype_t ebpf_core_helper_function_prototype_array[] = { EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM_OR_NULL, EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO, EBPF_ARGUMENT_TYPE_ANYTHING}}, - {BPF_FUNC_ringbuf_output, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_ringbuf_output, "bpf_ringbuf_output", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, EBPF_ARGUMENT_TYPE_CONST_SIZE, EBPF_ARGUMENT_TYPE_ANYTHING}}, - {BPF_FUNC_trace_printk2, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_trace_printk2, "bpf_trace_printk2", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, EBPF_ARGUMENT_TYPE_CONST_SIZE}}, - {BPF_FUNC_trace_printk3, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_trace_printk3, "bpf_trace_printk3", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, EBPF_ARGUMENT_TYPE_CONST_SIZE, EBPF_ARGUMENT_TYPE_ANYTHING}}, - {BPF_FUNC_trace_printk4, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_trace_printk4, "bpf_trace_printk4", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, EBPF_ARGUMENT_TYPE_CONST_SIZE, EBPF_ARGUMENT_TYPE_ANYTHING, EBPF_ARGUMENT_TYPE_ANYTHING}}, - {BPF_FUNC_trace_printk5, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_trace_printk5, "bpf_trace_printk5", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, @@ -76,24 +103,36 @@ ebpf_helper_function_prototype_t ebpf_core_helper_function_prototype_array[] = { EBPF_ARGUMENT_TYPE_ANYTHING, EBPF_ARGUMENT_TYPE_ANYTHING, EBPF_ARGUMENT_TYPE_ANYTHING}}, - {BPF_FUNC_map_push_elem, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_map_push_elem, "bpf_map_push_elem", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE, EBPF_ARGUMENT_TYPE_ANYTHING}}, - {BPF_FUNC_map_pop_elem, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_map_pop_elem, "bpf_map_pop_elem", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE}}, - {BPF_FUNC_map_peek_elem, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_map_peek_elem, "bpf_map_peek_elem", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE}}, - {BPF_FUNC_get_current_pid_tgid, "bpf_get_current_pid_tgid", EBPF_RETURN_TYPE_INTEGER, {0}}, - {BPF_FUNC_get_current_logon_id, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_get_current_pid_tgid, + "bpf_get_current_pid_tgid", + EBPF_RETURN_TYPE_INTEGER, + {0}}, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_get_current_logon_id, "bpf_get_current_logon_id", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX}}, - {BPF_FUNC_is_current_admin, "bpf_is_current_admin", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX}}, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_is_current_admin, + "bpf_is_current_admin", + EBPF_RETURN_TYPE_INTEGER, + {EBPF_ARGUMENT_TYPE_PTR_TO_CTX}}, }; #ifdef __cplusplus diff --git a/libs/execution_context/ebpf_link.c b/libs/execution_context/ebpf_link.c index 3dd78d5dcf..93ef65c452 100644 --- a/libs/execution_context/ebpf_link.c +++ b/libs/execution_context/ebpf_link.c @@ -32,6 +32,10 @@ typedef enum _ebpf_link_state EBPF_LINK_STATE_DETACHED, ///< Program is detached from a provider. } ebpf_link_state_t; +// Latest version of the eBPF extension attach/hook data structures. +#define EBPF_ATTACH_CLIENT_DATA_VERSION EBPF_ATTACH_CLIENT_DATA_VERSION_0 +#define EBPF_ATTACH_PROVIDER_DATA_VERSION EBPF_ATTACH_PROVIDER_DATA_VERSION_0 + typedef struct _ebpf_link { ebpf_core_object_t object; @@ -59,7 +63,7 @@ static const NPI_CLIENT_CHARACTERISTICS _ebpf_link_client_characteristics = { _ebpf_link_client_detach_provider, NULL, { - EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION, + EBPF_ATTACH_CLIENT_DATA_VERSION, sizeof(NPI_REGISTRATION_INSTANCE), &EBPF_HOOK_EXTENSION_IID, NULL, @@ -121,8 +125,8 @@ _ebpf_link_client_attach_provider( ebpf_link_t* link = (ebpf_link_t*)client_context; void* provider_binding_context; void* provider_dispatch; - const ebpf_extension_data_t* provider_data = - (const ebpf_extension_data_t*)provider_registration_instance->NpiSpecificCharacteristics; + const ebpf_attach_provider_data_t* attach_provider_data = + (const ebpf_attach_provider_data_t*)provider_registration_instance->NpiSpecificCharacteristics; bool lock_held = false; @@ -132,21 +136,19 @@ _ebpf_link_client_attach_provider( UNREFERENCED_PARAMETER(nmr_binding_handle); // Verify that that the provider is using the same version of the extension as the client. - if (provider_data->version > EBPF_ATTACH_PROVIDER_DATA_VERSION || - provider_data->size < sizeof(ebpf_extension_data_t)) { + if (attach_provider_data->header.version > EBPF_ATTACH_PROVIDER_DATA_VERSION_0 || + attach_provider_data->header.size < sizeof(ebpf_attach_provider_data_t)) { EBPF_LOG_MESSAGE_UINT64_UINT64( EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_LINK, "Attach provider data version is not compatible.", - provider_data->version, - provider_data->size); + attach_provider_data->header.version, + attach_provider_data->header.size); status = STATUS_INVALID_PARAMETER; goto Done; } - ebpf_attach_provider_data_t* attach_provider_data = (ebpf_attach_provider_data_t*)provider_data->data; - if (provider_registration_instance->ModuleId->Type != MIT_GUID) { EBPF_LOG_MESSAGE( EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_LINK, "Attach provider ModuleId type is not GUID."); @@ -252,7 +254,7 @@ ebpf_link_create( ebpf_lock_state_t state = ebpf_lock_lock(&local_link->lock); lock_held = true; - local_link->client_data.size = context_data_length; + local_link->client_data.header.size = context_data_length; if (context_data_length > 0) { local_link->client_data.data = ebpf_allocate_with_tag(context_data_length, EBPF_POOL_TAG_LINK); @@ -434,7 +436,7 @@ ebpf_link_detach_program(_Inout_ ebpf_link_t* link) ebpf_free((void*)link->client_data.data); link->client_data.data = NULL; - link->client_data.size = 0; + link->client_data.header.size = 0; link->program = NULL; Done: @@ -569,8 +571,8 @@ ebpf_link_get_info( // Copy any additional parameters. size_t size = sizeof(struct bpf_link_info) - FIELD_OFFSET(struct bpf_link_info, attach_data); - if ((link->client_data.size > 0) && (link->client_data.size <= size)) { - memcpy(&info->attach_data, link->client_data.data, link->client_data.size); + if ((link->client_data.header.size > 0) && (link->client_data.header.size <= size)) { + memcpy(&info->attach_data, link->client_data.data, link->client_data.header.size); } ebpf_lock_unlock((ebpf_lock_t*)&link->lock, state); diff --git a/libs/execution_context/ebpf_native.c b/libs/execution_context/ebpf_native.c index 35291779ba..9b913906ff 100644 --- a/libs/execution_context/ebpf_native.c +++ b/libs/execution_context/ebpf_native.c @@ -121,7 +121,7 @@ static const NPI_PROVIDER_CHARACTERISTICS _ebpf_native_provider_characteristics _ebpf_native_provider_detach_client_callback, NULL, { - EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION, + 0, sizeof(NPI_REGISTRATION_INSTANCE), &_ebpf_native_npi_id, &_ebpf_native_provider_module_id, diff --git a/libs/execution_context/ebpf_program.c b/libs/execution_context/ebpf_program.c index d7683eb4ac..fc2933f6b1 100644 --- a/libs/execution_context/ebpf_program.c +++ b/libs/execution_context/ebpf_program.c @@ -15,6 +15,7 @@ #include "ebpf_program.h" #include "ebpf_program_attach_type_guids.h" #include "ebpf_program_types.h" +#include "ebpf_shared_framework.h" #include "ebpf_state.h" #include "ebpf_tracelog.h" #include "ubpf.h" @@ -60,8 +61,8 @@ typedef struct _ebpf_program EX_RUNDOWN_REF program_information_rundown_reference; - const ebpf_extension_data_t* general_helper_provider_data; - const ebpf_extension_data_t* info_extension_provider_data; + const ebpf_program_data_t* general_helper_program_data; + const ebpf_program_data_t* extension_program_data; bpf_prog_type_t bpf_prog_type; @@ -104,7 +105,7 @@ static const NPI_CLIENT_CHARACTERISTICS _ebpf_program_general_program_informatio _ebpf_program_general_program_information_detach_provider, NULL, { - EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION, + EBPF_PROGRAM_INFORMATION_CLIENT_DATA_VERSION_0, sizeof(NPI_REGISTRATION_INSTANCE), &EBPF_PROGRAM_INFO_EXTENSION_IID, NULL, @@ -123,7 +124,7 @@ static const NPI_CLIENT_CHARACTERISTICS _ebpf_program_type_specific_program_info _ebpf_program_type_specific_program_information_detach_provider, NULL, { - EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION, + EBPF_PROGRAM_INFORMATION_CLIENT_DATA_VERSION_0, sizeof(NPI_REGISTRATION_INSTANCE), &EBPF_PROGRAM_INFO_EXTENSION_IID, NULL, @@ -182,61 +183,153 @@ _IRQL_requires_max_(PASSIVE_LEVEL) static ebpf_result_t _ebpf_program_compute_pr _In_ const uint32_t* actual_helper_ids, size_t count_of_actual_helper_ids, _In_ const ebpf_program_data_t* general_program_information_data, - _In_ const ebpf_program_data_t* type_specific_program_information_data, + _In_ const ebpf_program_data_t* extension_program_data, _In_ const cxplat_utf8_string_t* hash_algorithm, _Outptr_ uint8_t** hash, _Out_ size_t* hash_length); +static bool +_ebpf_program_match_provider_data_module_id(_In_ const PNPI_MODULEID npi_module_id, _In_ const GUID* expected_module_id) +{ + bool match = false; + // Verify the NPI module ID is a GUID. + if (npi_module_id->Type != MIT_GUID) { + EBPF_LOG_MESSAGE( + EBPF_TRACELOG_LEVEL_ERROR, + EBPF_TRACELOG_KEYWORD_PROGRAM, + "Program information provider module ID type mismatch."); + goto Done; + } + + // Check if the provider module ID matches the expected module ID. + if (memcmp(&npi_module_id->Guid, expected_module_id, sizeof(GUID)) != 0) { + // This is expected as the attach callback will be called for each provider of NPI + // EBPF_PROGRAM_INFO_EXTENSION_IID. + goto Done; + } + match = true; +Done: + return match; +} + +enum ebpf_program_info_provider_type +{ + EBPF_PROGRAM_INFO_PROVIDER_TYPE_EXTENSION, + EBPF_PROGRAM_INFO_PROVIDER_TYPE_GENERAL_HELPER +}; + +static bool +_ebpf_program_verify_provider_program_data( + _In_ enum ebpf_program_info_provider_type provider_type, + _In_ const PNPI_MODULEID npi_module_id, + _In_opt_ const ebpf_program_data_t* program_data) +{ + bool program_data_valid = false; + bool is_general_helper_program_data = (provider_type == EBPF_PROGRAM_INFO_PROVIDER_TYPE_GENERAL_HELPER); + + // Verify that the program data is present. + if (program_data == NULL) { + EBPF_LOG_MESSAGE( + EBPF_TRACELOG_LEVEL_ERROR, + EBPF_TRACELOG_KEYWORD_PROGRAM, + "The program information provider data is not present."); + goto Done; + } + + // Verify that that the program information version is supported. + if (program_data->header.version > EBPF_PROGRAM_DATA_VERSION_LATEST || + program_data->header.size < sizeof(ebpf_program_data_t)) { + EBPF_LOG_MESSAGE( + EBPF_TRACELOG_LEVEL_ERROR, + EBPF_TRACELOG_KEYWORD_PROGRAM, + "Program information provider version not supported."); + goto Done; + } + + if (program_data->header.size < EBPF_PROGRAM_DATA_MINIMUM_SIZE) { + EBPF_LOG_MESSAGE_GUID( + EBPF_TRACELOG_LEVEL_ERROR, + EBPF_TRACELOG_KEYWORD_PROGRAM, + "Program information provider data size too small.", + &npi_module_id->Guid); + goto Done; + } + + if (!is_general_helper_program_data) { + if (program_data->required_irql > HIGH_LEVEL) { + EBPF_LOG_MESSAGE_GUID( + EBPF_TRACELOG_LEVEL_ERROR, + EBPF_TRACELOG_KEYWORD_PROGRAM, + "An extension cannot have required_irql higher than HIGH_LEVEL", + &npi_module_id->Guid); + goto Done; + } + + if ((program_data->program_type_specific_helper_function_addresses) && + program_data->program_type_specific_helper_function_addresses->helper_function_count != + program_data->program_info->count_of_program_type_specific_helpers) { + EBPF_LOG_MESSAGE_GUID( + EBPF_TRACELOG_LEVEL_ERROR, + EBPF_TRACELOG_KEYWORD_PROGRAM, + "An extension cannot have a mismatch between the number of helper functions and the number of helper " + "function addresses", + &npi_module_id->Guid); + goto Done; + } + + if ((program_data->global_helper_function_addresses) && + (program_data->global_helper_function_addresses->helper_function_count != + program_data->program_info->count_of_global_helpers)) { + EBPF_LOG_MESSAGE_GUID( + EBPF_TRACELOG_LEVEL_ERROR, + EBPF_TRACELOG_KEYWORD_PROGRAM, + "An extension cannot have a mismatch between the number of helper functions and the number of helper " + "function addresses", + &npi_module_id->Guid); + goto Done; + } + } + program_data_valid = true; + +Done: + return program_data_valid; +} + static NTSTATUS _ebpf_program_general_program_information_attach_provider( _In_ HANDLE nmr_binding_handle, _In_ void* client_context, _In_ const NPI_REGISTRATION_INSTANCE* provider_registration_instance) { - const ebpf_extension_data_t* provider_data = - (const ebpf_extension_data_t*)provider_registration_instance->NpiSpecificCharacteristics; + const ebpf_program_data_t* program_data = + (const ebpf_program_data_t*)provider_registration_instance->NpiSpecificCharacteristics; ebpf_program_t* program = (ebpf_program_t*)client_context; NTSTATUS status; - void* provider_binding_context; void* provider_dispatch; - + ebpf_lock_state_t state = 0; bool lock_held = false; - ebpf_lock_state_t state = ebpf_lock_lock(&program->lock); - lock_held = true; - - // Verify that that the provider is using the same version of the extension as the client. - if (provider_data->version > EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION || - provider_data->size < sizeof(ebpf_program_data_t)) { + if (!_ebpf_program_match_provider_data_module_id( + provider_registration_instance->ModuleId, &ebpf_general_helper_function_module_id.Guid)) { EBPF_LOG_MESSAGE( EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_PROGRAM, - "Global program information provider version mismatch."); + "Program information provider module ID mismatch."); status = STATUS_INVALID_PARAMETER; goto Done; } - if (provider_registration_instance->ModuleId->Type != MIT_GUID) { - EBPF_LOG_MESSAGE( - EBPF_TRACELOG_LEVEL_ERROR, - EBPF_TRACELOG_KEYWORD_PROGRAM, - "Global program information provider module ID type mismatch."); + if (!_ebpf_program_verify_provider_program_data( + EBPF_PROGRAM_INFO_PROVIDER_TYPE_GENERAL_HELPER, provider_registration_instance->ModuleId, program_data)) { status = STATUS_INVALID_PARAMETER; goto Done; } - if (memcmp( - &provider_registration_instance->ModuleId->Guid, - &ebpf_general_helper_function_module_id.Guid, - sizeof(GUID)) != 0) { - status = STATUS_NOINTERFACE; - // This is expected as the attach callback will be called for each provider of NPI - // EBPF_PROGRAM_INFO_EXTENSION_IID. - goto Done; - } + state = ebpf_lock_lock(&program->lock); + lock_held = true; - if (program->general_helper_provider_data != NULL) { + if (program->general_helper_program_data != NULL) { EBPF_LOG_MESSAGE( EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_PROGRAM, @@ -245,8 +338,7 @@ _ebpf_program_general_program_information_attach_provider( goto Done; } - program->general_helper_provider_data = provider_data; - const ebpf_program_data_t* program_data = (const ebpf_program_data_t*)program->general_helper_provider_data->data; + program->general_helper_program_data = program_data; program->global_helper_function_count = program_data->program_type_specific_helper_function_addresses->helper_function_count; @@ -270,7 +362,7 @@ _ebpf_program_general_program_information_attach_provider( EBPF_TRACELOG_KEYWORD_PROGRAM, "NmrClientAttachProvider failed for global program information provider.", status); - program->general_helper_provider_data = NULL; + program->general_helper_program_data = NULL; goto Done; } @@ -287,7 +379,7 @@ _ebpf_program_general_program_information_detach_provider(void* client_binding_c { ebpf_program_t* program = (ebpf_program_t*)client_binding_context; ebpf_lock_state_t state = ebpf_lock_lock(&program->lock); - program->general_helper_provider_data = NULL; + program->general_helper_program_data = NULL; ebpf_lock_unlock(&program->lock, state); return STATUS_SUCCESS; } @@ -298,10 +390,9 @@ _ebpf_program_type_specific_program_information_attach_provider( _In_ void* client_context, _In_ const NPI_REGISTRATION_INSTANCE* provider_registration_instance) { - const ebpf_extension_data_t* provider_data = - (const ebpf_extension_data_t*)provider_registration_instance->NpiSpecificCharacteristics; ebpf_program_t* program = (ebpf_program_t*)client_context; - const ebpf_program_data_t* type_specific_program_information_data; + const ebpf_program_data_t* extension_program_data = + (const ebpf_program_data_t*)provider_registration_instance->NpiSpecificCharacteristics; const ebpf_program_data_t* general_program_information_data; cxplat_utf8_string_t hash_algorithm = {0}; NTSTATUS status; @@ -313,65 +404,52 @@ _ebpf_program_type_specific_program_information_attach_provider( void* provider_binding_context; void* provider_dispatch; - + ebpf_lock_state_t state = 0; bool lock_held = false; - ebpf_lock_state_t state = ebpf_lock_lock(&program->lock); - lock_held = true; - - if (ebpf_duplicate_utf8_string(&hash_algorithm, &program->parameters.program_info_hash_type) != EBPF_SUCCESS) { - status = STATUS_NO_MEMORY; - goto Done; - } - - if (!program->general_helper_provider_data) { + if (!_ebpf_program_match_provider_data_module_id( + provider_registration_instance->ModuleId, &program->parameters.program_type)) { EBPF_LOG_MESSAGE( EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_PROGRAM, - "Type specific program information provider attached before global program information provider."); + "Program information provider module ID mismatch."); status = STATUS_INVALID_PARAMETER; goto Done; } - general_program_information_data = (ebpf_program_data_t*)program->general_helper_provider_data->data; - - actual_helper_function_ids = program->helper_function_ids; - actual_helper_function_count = program->helper_function_count; - actual_helper_ids_set = program->helper_ids_set; - - ebpf_lock_unlock(&program->lock, state); - lock_held = false; - - // Verify that that the provider is using the same version of the extension as the client. - if (provider_data->version > EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION || - provider_data->size < sizeof(ebpf_program_data_t)) { - EBPF_LOG_MESSAGE_GUID( - EBPF_TRACELOG_LEVEL_ERROR, - EBPF_TRACELOG_KEYWORD_PROGRAM, - "Program information provider version mismatch.", - &program->parameters.program_type); + if (!_ebpf_program_verify_provider_program_data( + EBPF_PROGRAM_INFO_PROVIDER_TYPE_EXTENSION, + provider_registration_instance->ModuleId, + extension_program_data)) { status = STATUS_INVALID_PARAMETER; goto Done; } - if (provider_registration_instance->ModuleId->Type != MIT_GUID) { - EBPF_LOG_MESSAGE_GUID( + state = ebpf_lock_lock(&program->lock); + lock_held = true; + + if (!program->general_helper_program_data) { + EBPF_LOG_MESSAGE( EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_PROGRAM, - "Program information provider module ID type mismatch.", - &program->parameters.program_type); + "Type specific program information provider attached before global program information provider."); status = STATUS_INVALID_PARAMETER; goto Done; } - if (memcmp(&provider_registration_instance->ModuleId->Guid, &program->parameters.program_type, sizeof(GUID)) != 0) { - // This is expected as the attach callback will be called for each provider of NPI - // EBPF_PROGRAM_INFO_EXTENSION_IID. - status = STATUS_NOINTERFACE; + if (ebpf_duplicate_utf8_string(&hash_algorithm, &program->parameters.program_info_hash_type) != EBPF_SUCCESS) { + status = STATUS_NO_MEMORY; goto Done; } - type_specific_program_information_data = (ebpf_program_data_t*)provider_data->data; + general_program_information_data = program->general_helper_program_data; + + actual_helper_function_ids = program->helper_function_ids; + actual_helper_function_count = program->helper_function_count; + actual_helper_ids_set = program->helper_ids_set; + + ebpf_lock_unlock(&program->lock, state); + lock_held = false; // Compute (and compare) the hash only if the actual helper IDs have been set. if (actual_helper_ids_set) { @@ -381,7 +459,7 @@ _ebpf_program_type_specific_program_information_attach_provider( actual_helper_function_ids, actual_helper_function_count, general_program_information_data, - type_specific_program_information_data, + extension_program_data, &hash_algorithm, &hash, &hash_length) != EBPF_SUCCESS) { @@ -393,7 +471,7 @@ _ebpf_program_type_specific_program_information_attach_provider( state = ebpf_lock_lock(&program->lock); lock_held = true; - if (program->info_extension_provider_data != NULL) { + if (program->extension_program_data != NULL) { EBPF_LOG_MESSAGE_GUID( EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_PROGRAM, @@ -402,7 +480,6 @@ _ebpf_program_type_specific_program_information_attach_provider( status = STATUS_INVALID_PARAMETER; goto Done; } - program->info_extension_provider_data = provider_data; // Compare the hash only if actual helper IDs have been set. if (actual_helper_ids_set) { @@ -419,63 +496,15 @@ _ebpf_program_type_specific_program_information_attach_provider( } } - const ebpf_program_data_t* program_data = (const ebpf_program_data_t*)provider_data->data; - if (program_data == NULL) { - EBPF_LOG_MESSAGE_GUID( - EBPF_TRACELOG_LEVEL_ERROR, - EBPF_TRACELOG_KEYWORD_PROGRAM, - "An extension cannot have empty program_data", - &program->parameters.program_type); - // An extension cannot have empty program_data. - status = STATUS_INVALID_PARAMETER; - goto Done; - } - - if (program_data->required_irql > HIGH_LEVEL) { - EBPF_LOG_MESSAGE_GUID( - EBPF_TRACELOG_LEVEL_ERROR, - EBPF_TRACELOG_KEYWORD_PROGRAM, - "An extension cannot have required_irql higher than HIGH_LEVEL", - &program->parameters.program_type); - status = STATUS_INVALID_PARAMETER; - goto Done; - } - - if ((program_data->program_type_specific_helper_function_addresses) && - program_data->program_type_specific_helper_function_addresses->helper_function_count != - program_data->program_info->count_of_program_type_specific_helpers) { - EBPF_LOG_MESSAGE_GUID( - EBPF_TRACELOG_LEVEL_ERROR, - EBPF_TRACELOG_KEYWORD_PROGRAM, - "An extension cannot have a mismatch between the number of helper functions and the number of helper " - "function addresses", - &program->parameters.program_type); - status = STATUS_INVALID_PARAMETER; - goto Done; - } - - if ((program_data->global_helper_function_addresses) && - (program_data->global_helper_function_addresses->helper_function_count != - program_data->program_info->count_of_global_helpers)) { - EBPF_LOG_MESSAGE_GUID( - EBPF_TRACELOG_LEVEL_ERROR, - EBPF_TRACELOG_KEYWORD_PROGRAM, - "An extension cannot have a mismatch between the number of helper functions and the number of helper " - "function addresses", - &program->parameters.program_type); - status = STATUS_INVALID_PARAMETER; - goto Done; - } - // This should be done after the call to NmrClientAttachProvider, but _ebpf_program_update_helpers requires // the program information to be set. // Unblock calls to use the program information. - program->info_extension_provider_data = provider_data; + program->extension_program_data = extension_program_data; ExInitializeRundownProtection(&program->program_information_rundown_reference); program->program_type_specific_helper_function_count = - program_data->program_info->count_of_program_type_specific_helpers; + extension_program_data->program_info->count_of_program_type_specific_helpers; if (_ebpf_program_update_helpers(program) != EBPF_SUCCESS) { EBPF_LOG_MESSAGE( @@ -484,7 +513,7 @@ _ebpf_program_type_specific_program_information_attach_provider( goto Done; } - program->bpf_prog_type = program_data->program_info->program_type_descriptor.bpf_prog_type; + program->bpf_prog_type = extension_program_data->program_info->program_type_descriptor->bpf_prog_type; ebpf_lock_unlock(&program->lock, state); lock_held = false; @@ -506,7 +535,7 @@ _ebpf_program_type_specific_program_information_attach_provider( state = ebpf_lock_lock(&program->lock); lock_held = true; - program->general_helper_provider_data = NULL; + program->general_helper_program_data = NULL; ebpf_lock_unlock(&program->lock, state); lock_held = false; goto Done; @@ -531,7 +560,7 @@ _ebpf_program_type_specific_program_information_detach_provider(void* client_bin ExWaitForRundownProtectionRelease(&program->program_information_rundown_reference); ebpf_lock_state_t state = ebpf_lock_lock(&program->lock); - program->info_extension_provider_data = NULL; + program->extension_program_data = NULL; ebpf_lock_unlock(&program->lock, state); return STATUS_SUCCESS; } @@ -788,7 +817,7 @@ ebpf_program_create(_In_ const ebpf_program_parameters_t* program_parameters, _O goto Done; } - if (local_program->general_helper_provider_data == NULL || local_program->info_extension_provider_data == NULL) { + if (local_program->general_helper_program_data == NULL || local_program->extension_program_data == NULL) { EBPF_LOG_MESSAGE_GUID_GUID( EBPF_TRACELOG_LEVEL_INFO, EBPF_TRACELOG_KEYWORD_PROGRAM, @@ -1073,7 +1102,7 @@ _ebpf_program_update_jit_helpers( UNREFERENCED_PARAMETER(address_count); UNREFERENCED_PARAMETER(addresses); ebpf_program_t* program = (ebpf_program_t*)context; - ebpf_program_data_t* program_data = NULL; + const ebpf_program_data_t* program_data = NULL; const ebpf_helper_function_addresses_t* helper_function_addresses = NULL; const ebpf_helper_function_addresses_t* global_helper_function_addresses = NULL; @@ -1092,7 +1121,7 @@ _ebpf_program_update_jit_helpers( goto Exit; } provider_data_referenced = true; - program_data = (ebpf_program_data_t*)program->info_extension_provider_data->data; + program_data = program->extension_program_data; helper_function_addresses = program_data->program_type_specific_helper_function_addresses; global_helper_function_addresses = program_data->global_helper_function_addresses; @@ -1372,7 +1401,7 @@ ebpf_program_set_tail_call(_In_ const ebpf_program_t* next_program) _Must_inspect_result_ ebpf_result_t ebpf_program_reference_providers(_Inout_ ebpf_program_t* program) { - if (program->info_extension_provider_data == NULL) { + if (program->extension_program_data == NULL) { return EBPF_EXTENSION_FAILED_TO_LOAD; } if (!ExAcquireRundownProtection(&program->program_information_rundown_reference)) { @@ -1434,8 +1463,8 @@ _Requires_lock_held_(program->lock) static ebpf_result_t _ebpf_program_get_helpe { ebpf_result_t return_value; uint64_t* function_address = NULL; - ebpf_program_data_t* program_data = NULL; - ebpf_program_data_t* general_program_data = NULL; + const ebpf_program_data_t* program_data = NULL; + const ebpf_program_data_t* general_program_data = NULL; EBPF_LOG_ENTRY(); @@ -1454,8 +1483,8 @@ _Requires_lock_held_(program->lock) static ebpf_result_t _ebpf_program_get_helpe } provider_data_referenced = true; - program_data = (ebpf_program_data_t*)program->info_extension_provider_data->data; - general_program_data = (ebpf_program_data_t*)program->general_helper_provider_data->data; + program_data = program->extension_program_data; + general_program_data = program->general_helper_program_data; use_trampoline = program->parameters.code_type == EBPF_CODE_JIT; if (use_trampoline && !program->trampoline_table) { @@ -1573,7 +1602,6 @@ ebpf_program_set_helper_function_ids( state = ebpf_lock_lock(&program->lock); if (helper_function_count == 0) { - program->helper_ids_set = true; goto Exit; } @@ -1599,6 +1627,8 @@ ebpf_program_set_helper_function_ids( program->helper_function_ids[index] = helper_function_ids[index]; } + program->helper_ids_set = true; + Exit: ebpf_lock_unlock(&program->lock, state); EBPF_RETURN_RESULT(result); @@ -1627,7 +1657,7 @@ ebpf_program_set_program_info_hash(_Inout_ ebpf_program_t* program) ebpf_result_t result = EBPF_SUCCESS; bool provider_data_referenced = false; - const ebpf_program_data_t* type_specific_program_information_data; + const ebpf_program_data_t* extension_program_data; const ebpf_program_data_t* general_program_information_data; cxplat_utf8_string_t hash_algorithm = {0}; uint32_t* actual_helper_function_ids = NULL; @@ -1657,8 +1687,8 @@ ebpf_program_set_program_info_hash(_Inout_ ebpf_program_t* program) goto Exit; } - general_program_information_data = (ebpf_program_data_t*)program->general_helper_provider_data->data; - type_specific_program_information_data = (ebpf_program_data_t*)program->info_extension_provider_data->data; + general_program_information_data = program->general_helper_program_data; + extension_program_data = program->extension_program_data; actual_helper_function_ids = program->helper_function_ids; actual_helper_function_count = program->helper_function_count; @@ -1670,7 +1700,7 @@ ebpf_program_set_program_info_hash(_Inout_ ebpf_program_t* program) actual_helper_function_ids, actual_helper_function_count, general_program_information_data, - type_specific_program_information_data, + extension_program_data, &hash_algorithm, &hash, &hash_length); @@ -1718,8 +1748,8 @@ ebpf_program_get_program_info(_In_ const ebpf_program_t* program, _Outptr_ ebpf_ { EBPF_LOG_ENTRY(); ebpf_result_t result = EBPF_SUCCESS; - ebpf_program_data_t* program_data = NULL; - ebpf_program_data_t* general_helper_program_data = NULL; + const ebpf_program_data_t* program_data = NULL; + const ebpf_program_data_t* general_helper_program_data = NULL; ebpf_program_info_t* local_program_info = NULL; uint32_t total_count_of_helpers = 0; uint32_t helper_index = 0; @@ -1738,9 +1768,9 @@ ebpf_program_get_program_info(_In_ const ebpf_program_t* program, _Outptr_ ebpf_ goto Exit; } provider_data_referenced = true; - program_data = (ebpf_program_data_t*)program->info_extension_provider_data->data; + program_data = program->extension_program_data; - if (!program->general_helper_provider_data) { + if (!program->general_helper_program_data) { EBPF_LOG_MESSAGE_GUID( EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_PROGRAM, @@ -1749,7 +1779,7 @@ ebpf_program_get_program_info(_In_ const ebpf_program_t* program, _Outptr_ ebpf_ result = EBPF_EXTENSION_FAILED_TO_LOAD; goto Exit; } - general_helper_program_data = (ebpf_program_data_t*)program->general_helper_provider_data->data; + general_helper_program_data = program->general_helper_program_data; total_count_of_helpers = program_data->program_info->count_of_program_type_specific_helpers + general_helper_program_data->program_info->count_of_program_type_specific_helpers; @@ -1984,7 +2014,7 @@ _IRQL_requires_max_(PASSIVE_LEVEL) static ebpf_result_t _ebpf_program_compute_pr _In_ const uint32_t* actual_helper_ids, size_t count_of_actual_helper_ids, _In_ const ebpf_program_data_t* general_program_information_data, - _In_ const ebpf_program_data_t* type_specific_program_information_data, + _In_ const ebpf_program_data_t* extension_program_data, _In_ const cxplat_utf8_string_t* hash_algorithm, _Outptr_ uint8_t** hash, _Out_ size_t* hash_length) @@ -1993,7 +2023,7 @@ _IRQL_requires_max_(PASSIVE_LEVEL) static ebpf_result_t _ebpf_program_compute_pr ebpf_result_t result; ebpf_cryptographic_hash_t* cryptographic_hash = NULL; ebpf_helper_id_to_index_t* helper_id_to_index = NULL; - const ebpf_program_info_t* type_specific_program_info = type_specific_program_information_data->program_info; + const ebpf_program_info_t* type_specific_program_info = extension_program_data->program_info; const ebpf_program_info_t* general_program_info = general_program_information_data->program_info; size_t helper_function_count = count_of_actual_helper_ids; uint32_t helper_function_index = 0; @@ -2070,31 +2100,31 @@ _IRQL_requires_max_(PASSIVE_LEVEL) static ebpf_result_t _ebpf_program_compute_pr // new fields, both here and in bpf2c. result = EBPF_CRYPTOGRAPHIC_HASH_APPEND_STR( - cryptographic_hash, type_specific_program_info->program_type_descriptor.name); + cryptographic_hash, type_specific_program_info->program_type_descriptor->name); if (result != EBPF_SUCCESS) { goto Exit; } result = EBPF_CRYPTOGRAPHIC_HASH_APPEND_VALUE( - cryptographic_hash, *type_specific_program_info->program_type_descriptor.context_descriptor); + cryptographic_hash, *type_specific_program_info->program_type_descriptor->context_descriptor); if (result != EBPF_SUCCESS) { goto Exit; } result = EBPF_CRYPTOGRAPHIC_HASH_APPEND_VALUE( - cryptographic_hash, type_specific_program_info->program_type_descriptor.program_type); + cryptographic_hash, type_specific_program_info->program_type_descriptor->program_type); if (result != EBPF_SUCCESS) { goto Exit; } result = EBPF_CRYPTOGRAPHIC_HASH_APPEND_VALUE( - cryptographic_hash, type_specific_program_info->program_type_descriptor.bpf_prog_type); + cryptographic_hash, type_specific_program_info->program_type_descriptor->bpf_prog_type); if (result != EBPF_SUCCESS) { goto Exit; } result = EBPF_CRYPTOGRAPHIC_HASH_APPEND_VALUE( - cryptographic_hash, type_specific_program_info->program_type_descriptor.is_privileged); + cryptographic_hash, type_specific_program_info->program_type_descriptor->is_privileged); if (result != EBPF_SUCCESS) { goto Exit; } @@ -2158,7 +2188,7 @@ _IRQL_requires_max_(PASSIVE_LEVEL) static ebpf_result_t _ebpf_program_compute_pr typedef struct _ebpf_program_test_run_context { const ebpf_program_t* program; - ebpf_program_data_t* program_data; + const ebpf_program_data_t* program_data; ebpf_program_test_run_options_t* options; uint8_t required_irql; bool canceled; @@ -2313,7 +2343,7 @@ ebpf_program_execute_test_run( ebpf_result_t return_value = EBPF_SUCCESS; ebpf_program_test_run_context_t* test_run_context = NULL; cxplat_preemptible_work_item_t* work_item = NULL; - ebpf_program_data_t* program_data = NULL; + const ebpf_program_data_t* program_data = NULL; bool provider_data_referenced = false; // Prevent the provider from detaching while the program is running. @@ -2328,7 +2358,7 @@ ebpf_program_execute_test_run( } provider_data_referenced = true; - program_data = (ebpf_program_data_t*)program->info_extension_provider_data->data; + program_data = program->extension_program_data; if (program_data->context_create == NULL || program_data->context_destroy == NULL) { return_value = EBPF_INVALID_ARGUMENT; diff --git a/libs/execution_context/unit/execution_context_unit_test.cpp b/libs/execution_context/unit/execution_context_unit_test.cpp index 7c5703bdc7..4313c13638 100644 --- a/libs/execution_context/unit/execution_context_unit_test.cpp +++ b/libs/execution_context/unit/execution_context_unit_test.cpp @@ -761,7 +761,9 @@ TEST_CASE("program", "[execution_context]") uint32_t test_function_ids[] = {(EBPF_MAX_GENERAL_HELPER_FUNCTION + 1)}; const void* helper_functions[] = {(void*)function_pointer1}; ebpf_helper_function_addresses_t helper_function_addresses = { - EBPF_COUNT_OF(helper_functions), (uint64_t*)helper_functions}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(helper_functions), + (uint64_t*)helper_functions}; { ebpf_trampoline_table_t* local_table = nullptr; diff --git a/libs/runtime/unit/platform_unit_test.cpp b/libs/runtime/unit/platform_unit_test.cpp index c70971b5f3..65382d0767 100644 --- a/libs/runtime/unit/platform_unit_test.cpp +++ b/libs/runtime/unit/platform_unit_test.cpp @@ -621,13 +621,17 @@ TEST_CASE("trampoline_test", "[platform]") const void* helper_functions1[] = {(void*)function_pointer1}; const uint32_t provider_helper_function_ids[] = {(uint32_t)(EBPF_MAX_GENERAL_HELPER_FUNCTION + 1)}; ebpf_helper_function_addresses_t helper_function_addresses1 = { - EBPF_COUNT_OF(helper_functions1), (uint64_t*)helper_functions1}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(helper_functions1), + (uint64_t*)helper_functions1}; auto provider_function2 = []() { return EBPF_OBJECT_ALREADY_EXISTS; }; ebpf_result_t (*function_pointer2)() = provider_function2; const void* helper_functions2[] = {(void*)function_pointer2}; ebpf_helper_function_addresses_t helper_function_addresses2 = { - EBPF_COUNT_OF(helper_functions1), (uint64_t*)helper_functions2}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(helper_functions1), + (uint64_t*)helper_functions2}; ebpf_trampoline_table_t* local_table = nullptr; REQUIRE(ebpf_allocate_trampoline_table(1, &local_table) == EBPF_SUCCESS); @@ -799,11 +803,13 @@ TEST_CASE("serialize_program_info_test", "[platform]") test_helper.initialize(); ebpf_helper_function_prototype_t helper_prototype[] = { - {1000, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + 1000, "helper_0", EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}}, - {1001, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + 1001, "helper_1", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE}}}; @@ -811,8 +817,16 @@ TEST_CASE("serialize_program_info_test", "[platform]") // and have no effect on the test. ebpf_context_descriptor_t context_descriptor = {32, 0, 8, -1}; GUID program_type_test = {0x7ebe418c, 0x76dd, 0x4c2c, {0x99, 0xbc, 0x5c, 0x48, 0xa2, 0x30, 0x4b, 0x90}}; - ebpf_program_type_descriptor_t program_type = {"unit_test_program", &context_descriptor, program_type_test}; - ebpf_program_info_t in_program_info = {program_type, EBPF_COUNT_OF(helper_prototype), helper_prototype}; + ebpf_program_type_descriptor_t program_type = { + {EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, sizeof(ebpf_program_type_descriptor_t)}, + "unit_test_program", + &context_descriptor, + program_type_test}; + ebpf_program_info_t in_program_info = { + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &program_type, + EBPF_COUNT_OF(helper_prototype), + helper_prototype}; size_t buffer_length = 0; size_t required_length; @@ -843,21 +857,23 @@ TEST_CASE("serialize_program_info_test", "[platform]") REQUIRE(ebpf_deserialize_program_info(serialized_length, unique_buffer.get(), &out_program_info) == EBPF_SUCCESS); // Verify de-serialized program info matches input. + REQUIRE(in_program_info.program_type_descriptor != nullptr); REQUIRE( - in_program_info.program_type_descriptor.program_type == out_program_info->program_type_descriptor.program_type); + in_program_info.program_type_descriptor->program_type == + out_program_info->program_type_descriptor->program_type); REQUIRE( - in_program_info.program_type_descriptor.is_privileged == - out_program_info->program_type_descriptor.is_privileged); - REQUIRE(in_program_info.program_type_descriptor.context_descriptor != nullptr); + in_program_info.program_type_descriptor->is_privileged == + out_program_info->program_type_descriptor->is_privileged); + REQUIRE(in_program_info.program_type_descriptor->context_descriptor != nullptr); REQUIRE( memcmp( - in_program_info.program_type_descriptor.context_descriptor, - out_program_info->program_type_descriptor.context_descriptor, + in_program_info.program_type_descriptor->context_descriptor, + out_program_info->program_type_descriptor->context_descriptor, sizeof(ebpf_context_descriptor_t)) == 0); REQUIRE( strncmp( - in_program_info.program_type_descriptor.name, - out_program_info->program_type_descriptor.name, + in_program_info.program_type_descriptor->name, + out_program_info->program_type_descriptor->name, EBPF_MAX_PROGRAM_DESCRIPTOR_NAME_LENGTH) == 0); REQUIRE( in_program_info.count_of_program_type_specific_helpers == diff --git a/libs/shared/ebpf_serialize.c b/libs/shared/ebpf_serialize.c index 5df3cd2f77..732da0ba83 100644 --- a/libs/shared/ebpf_serialize.c +++ b/libs/shared/ebpf_serialize.c @@ -13,6 +13,7 @@ typedef struct _ebpf_serialized_program_type_descriptor { size_t size; + ebpf_extension_header_t header; ebpf_context_descriptor_t context_descriptor; GUID program_type; unsigned char is_privileged; @@ -26,6 +27,7 @@ typedef struct _ebpf_serialized_program_type_descriptor typedef struct _ebpf_serialized_helper_function_prototype { size_t size; + ebpf_extension_header_t header; uint32_t helper_id; ebpf_return_type_t return_type; ebpf_argument_type_t arguments[5]; @@ -39,6 +41,7 @@ typedef struct _ebpf_serialized_helper_function_prototype typedef struct _ebpf_serialized_helper_function_prototype_array { size_t size; + ebpf_extension_header_t header; uint32_t helper_function_count; uint8_t prototypes[1]; } ebpf_serialized_helper_function_prototype_array_t; @@ -255,8 +258,11 @@ ebpf_program_info_free(_In_opt_ _Post_invalid_ ebpf_program_info_t* program_info { EBPF_LOG_ENTRY(); if (program_info != NULL) { - ebpf_free((void*)program_info->program_type_descriptor.context_descriptor); - ebpf_free((void*)program_info->program_type_descriptor.name); + if (program_info->program_type_descriptor != NULL) { + ebpf_free((void*)program_info->program_type_descriptor->context_descriptor); + ebpf_free((void*)program_info->program_type_descriptor->name); + ebpf_free((void*)program_info->program_type_descriptor); + } if (program_info->program_type_specific_helper_prototype != NULL) { for (uint32_t i = 0; i < program_info->count_of_program_type_specific_helpers; i++) { const ebpf_helper_function_prototype_t* helper_prototype = @@ -302,7 +308,12 @@ ebpf_serialize_program_info( *serialized_data_length = 0; // Perform sanity check on input program info. - program_type_descriptor = &program_info->program_type_descriptor; + program_type_descriptor = program_info->program_type_descriptor; + if (program_type_descriptor == NULL) { + EBPF_LOG_MESSAGE(EBPF_TRACELOG_LEVEL_WARNING, EBPF_TRACELOG_KEYWORD_BASE, "program_type_descriptor is NULL"); + result = EBPF_INVALID_ARGUMENT; + goto Exit; + } if (program_type_descriptor->name == NULL) { EBPF_LOG_MESSAGE( @@ -426,6 +437,7 @@ ebpf_serialize_program_info( if (program_type_descriptor->context_descriptor != NULL) { serialized_program_type_descriptor->context_descriptor = *program_type_descriptor->context_descriptor; } + serialized_program_type_descriptor->header = program_type_descriptor->header; serialized_program_type_descriptor->program_type = program_type_descriptor->program_type; serialized_program_type_descriptor->is_privileged = program_type_descriptor->is_privileged; serialized_program_type_descriptor->name_length = program_type_descriptor_name_length; @@ -457,6 +469,7 @@ ebpf_serialize_program_info( // Serialize individual helper function prototypes. serialized_helper_prototype->size = EBPF_OFFSET_OF(ebpf_serialized_helper_function_prototype_t, name) + helper_function_name_length; + serialized_helper_prototype->header = helper_prototype->header; serialized_helper_prototype->helper_id = helper_prototype->helper_id; serialized_helper_prototype->return_type = helper_prototype->return_type; for (uint16_t index = 0; index < EBPF_COUNT_OF(helper_prototype->arguments); index++) { @@ -501,12 +514,18 @@ ebpf_deserialize_program_info( result = EBPF_NO_MEMORY; goto Exit; } - local_program_type_descriptor = &local_program_info->program_type_descriptor; current = input_buffer; buffer_left = input_buffer_length; - // Deserialize program type descriptor. + // Allocate and deserialize program type descriptor. + local_program_type_descriptor = + (ebpf_program_type_descriptor_t*)ebpf_allocate(sizeof(ebpf_program_type_descriptor_t)); + if (local_program_type_descriptor == NULL) { + result = EBPF_NO_MEMORY; + goto Exit; + } + local_program_info->program_type_descriptor = local_program_type_descriptor; // Check if sufficient input buffer remaining. if (buffer_left < sizeof(ebpf_serialized_program_type_descriptor_t)) { @@ -516,6 +535,7 @@ ebpf_deserialize_program_info( serialized_program_type_descriptor = (const ebpf_serialized_program_type_descriptor_t*)current; + local_program_type_descriptor->header = serialized_program_type_descriptor->header; local_program_type_descriptor->program_type = serialized_program_type_descriptor->program_type; local_program_type_descriptor->is_privileged = serialized_program_type_descriptor->is_privileged; @@ -627,7 +647,8 @@ ebpf_deserialize_program_info( goto Exit; } - // Serialize helper prototype. + // De-serialize helper prototype. + helper_prototype->header = serialized_helper_prototype->header; helper_prototype->helper_id = serialized_helper_prototype->helper_id; helper_prototype->return_type = serialized_helper_prototype->return_type; for (int i = 0; i < EBPF_COUNT_OF(helper_prototype->arguments); i++) { diff --git a/libs/shared/ebpf_shared_framework.h b/libs/shared/ebpf_shared_framework.h index 9b508e736e..d77f38766d 100644 --- a/libs/shared/ebpf_shared_framework.h +++ b/libs/shared/ebpf_shared_framework.h @@ -3,6 +3,7 @@ #pragma once #include "cxplat.h" +#include "ebpf_program_types.h" #include "ebpf_result.h" #include "shared_context.h" @@ -24,6 +25,25 @@ CXPLAT_EXTERN_C_BEGIN #define EBPF_SYMBOLIC_DEVICE_NAME L"\\GLOBAL??\\EbpfIoDevice" #define EBPF_DEVICE_WIN32_NAME L"\\\\.\\EbpfIoDevice" +// Latest version of the eBPF extension program information data structures. +#define EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_LATEST EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0 +#define EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_LATEST EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0 +#define EBPF_PROGRAM_INFORMATION_VERSION_LATEST EBPF_PROGRAM_INFORMATION_VERSION_0 +#define EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_LATEST EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0 +#define EBPF_PROGRAM_DATA_VERSION_LATEST EBPF_PROGRAM_DATA_VERSION_0 +#define EBPF_PROGRAM_SECTION_VERSION_LATEST EBPF_PROGRAM_SECTION_VERSION_0 + +// Minumum length of the eBPF extension program information data structures. +#define EBPF_PROGRAM_DATA_MINIMUM_SIZE (EBPF_OFFSET_OF(ebpf_program_data_t, required_irql) + sizeof(uint8_t)) +#define EBPF_PROGRAM_INFO_MINIMUM_SIZE \ + (EBPF_OFFSET_OF(ebpf_program_info_t, global_helper_prototype) + sizeof(ebpf_helper_function_prototype_t*)) +#define EBPF_PROGRAM_TYPE_DESCRIPTOR_MINIMUM_SIZE \ + (EBPF_OFFSET_OF(ebpf_program_type_descriptor_t, is_privileged) + sizeof(char)) +#define EBPF_CONTEXT_DESCRIPTOR_MINIMUM_SIZE \ + (EBPF_OFFSET_OF(ebpf_context_descriptor_t, context_destroy) + sizeof(ebpf_program_context_destroy_t)) +#define EBPF_HELPER_FUNCTION_PROTOTYPE_MINIMUM_SIZE \ + (EBPF_OFFSET_OF(ebpf_helper_function_prototype_t, arguments) + 5 * sizeof(ebpf_argument_type_t)) + // Macro locally suppresses "Unreferenced variable" warning, which in 'Release' builds is treated as an error. #define ebpf_assert_success(x) \ _Pragma("warning(push)") _Pragma("warning(disable : 4189)") do \ @@ -92,4 +112,14 @@ __forceinline __drv_allocatesMem(Mem) _Must_inspect_result_ ebpf_result_t ebpf_result_from_cxplat_status(cxplat_status_t status); +bool +ebpf_validate_program_section_info(_In_ const ebpf_program_section_info_t* section_info); + +bool +ebpf_validate_program_info(_In_ const ebpf_program_info_t* program_info); + +bool +ebpf_validate_helper_function_prototype_array( + _In_reads_(count) const ebpf_helper_function_prototype_t* helper_prototype, uint32_t count); + CXPLAT_EXTERN_C_END diff --git a/libs/shared/shared_common.c b/libs/shared/shared_common.c index 6f2b7a495f..d0c102a634 100644 --- a/libs/shared/shared_common.c +++ b/libs/shared/shared_common.c @@ -1,8 +1,72 @@ // Copyright (c) Microsoft Corporation // SPDX-License-Identifier: MIT +#include "ebpf_program_types.h" #include "ebpf_shared_framework.h" +static bool +_ebpf_validate_helper_function_prototype(const ebpf_helper_function_prototype_t* helper_prototype) +{ + return ( + (helper_prototype != NULL) && (helper_prototype->header.size >= EBPF_HELPER_FUNCTION_PROTOTYPE_MINIMUM_SIZE) && + (helper_prototype->header.version <= EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_LATEST) && + (helper_prototype->name != NULL)); +} + +bool +ebpf_validate_helper_function_prototype_array( + _In_reads_(count) const ebpf_helper_function_prototype_t* helper_prototype, uint32_t count) +{ + if (count > 0) { + for (uint32_t i = 0; i < count; i++) { + if (!_ebpf_validate_helper_function_prototype(&helper_prototype[i])) { + return false; + } + } + } + return true; +} + +static bool +_ebpf_validate_context_descriptor(_In_ const ebpf_context_descriptor_t* context_descriptor) +{ + return ((context_descriptor != NULL) && (context_descriptor->size >= sizeof(ebpf_context_descriptor_t))); +} + +static bool +_ebpf_validate_program_type_descriptor(_In_ const ebpf_program_type_descriptor_t* program_type_descriptor) +{ + return ( + (program_type_descriptor != NULL) && + (program_type_descriptor->header.size >= EBPF_PROGRAM_TYPE_DESCRIPTOR_MINIMUM_SIZE) && + (program_type_descriptor->header.version <= EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_LATEST) && + (program_type_descriptor->name != NULL) && + _ebpf_validate_context_descriptor(program_type_descriptor->context_descriptor)); +} + +bool +ebpf_validate_program_info(_In_ const ebpf_program_info_t* program_info) +{ + return ( + (program_info != NULL) && (program_info->header.size >= EBPF_PROGRAM_INFO_MINIMUM_SIZE) && + (program_info->header.version <= EBPF_PROGRAM_INFORMATION_VERSION_LATEST) && + _ebpf_validate_program_type_descriptor(program_info->program_type_descriptor) && + ebpf_validate_helper_function_prototype_array( + program_info->program_type_specific_helper_prototype, + program_info->count_of_program_type_specific_helpers) && + ebpf_validate_helper_function_prototype_array( + program_info->global_helper_prototype, program_info->count_of_global_helpers)); +} + +bool +ebpf_validate_program_section_info(_In_ const ebpf_program_section_info_t* section_info) +{ + return ( + (section_info != NULL) && (section_info->header.size >= sizeof(ebpf_program_section_info_t)) && + (section_info->header.version <= EBPF_PROGRAM_SECTION_VERSION_LATEST) && (section_info->section_name != NULL) && + (section_info->program_type != NULL) && (section_info->attach_type != NULL)); +} + ebpf_result_t ebpf_result_from_cxplat_status(cxplat_status_t status) { diff --git a/libs/store_helper/ebpf_store_helper.c b/libs/store_helper/ebpf_store_helper.c index 94f95537b8..4f3bd81229 100644 --- a/libs/store_helper/ebpf_store_helper.c +++ b/libs/store_helper/ebpf_store_helper.c @@ -3,6 +3,7 @@ #include "ebpf_program_types.h" #include "ebpf_registry_helper.h" +#include "ebpf_shared_framework.h" #include "ebpf_store_helper.h" #include "ebpf_windows.h" @@ -89,6 +90,11 @@ ebpf_store_update_global_helper_information( return result; } + if (!ebpf_validate_helper_function_prototype_array(helper_info, helper_info_count)) { + result = EBPF_INVALID_ARGUMENT; + goto Exit; + } + // Open (or create) provider registry path. result = _ebpf_store_open_or_create_provider_registry_key(&provider_key); if (!IS_SUCCESS(result)) { @@ -103,7 +109,6 @@ ebpf_store_update_global_helper_information( } for (uint32_t i = 0; i < helper_info_count; i++) { - result = _ebpf_store_update_helper_prototype(helper_info_key, &helper_info[i]); if (!IS_SUCCESS(result)) { goto Exit; @@ -144,6 +149,11 @@ ebpf_store_update_section_information( for (uint32_t i = 0; i < section_info_count; i++) { ebpf_store_key_t section_key = NULL; + if (!ebpf_validate_program_section_info(§ion_info[i])) { + result = EBPF_INVALID_ARGUMENT; + goto Exit; + } + // Open or create the registry path. result = ebpf_create_registry_key(section_info_key, section_info[i].section_name, REG_CREATE_FLAGS, §ion_key); @@ -228,10 +238,15 @@ ebpf_store_update_program_information( ebpf_store_key_t program_key = {0}; ebpf_store_key_t helper_info_key = {0}; + if (!ebpf_validate_program_info(&program_info[i])) { + result = EBPF_INVALID_ARGUMENT; + goto Exit; + } + // Convert program type GUID to string. wchar_t guid_string[GUID_STRING_LENGTH + 1]; result = ebpf_convert_guid_to_string( - &program_info[i].program_type_descriptor.program_type, guid_string, GUID_STRING_LENGTH + 1); + &program_info[i].program_type_descriptor->program_type, guid_string, GUID_STRING_LENGTH + 1); if (!IS_SUCCESS(result)) { return result; } @@ -242,7 +257,7 @@ ebpf_store_update_program_information( } // Save the friendly program type name. - wchar_t* wide_program_name = ebpf_get_wstring_from_string(program_info[i].program_type_descriptor.name); + wchar_t* wide_program_name = ebpf_get_wstring_from_string(program_info[i].program_type_descriptor->name); if (wide_program_name == NULL) { result = EBPF_NO_MEMORY; goto Exit; @@ -259,7 +274,7 @@ ebpf_store_update_program_information( result = ebpf_write_registry_value_binary( program_key, EBPF_PROGRAM_DATA_CONTEXT_DESCRIPTOR, - (uint8_t*)program_info[i].program_type_descriptor.context_descriptor, + (uint8_t*)program_info[i].program_type_descriptor->context_descriptor, sizeof(ebpf_context_descriptor_t)); if (!IS_SUCCESS(result)) { ebpf_close_registry_key(program_key); @@ -268,7 +283,7 @@ ebpf_store_update_program_information( // Save bpf_prog_type. result = ebpf_write_registry_value_dword( - program_key, EBPF_DATA_BPF_PROG_TYPE, program_info[i].program_type_descriptor.bpf_prog_type); + program_key, EBPF_DATA_BPF_PROG_TYPE, program_info[i].program_type_descriptor->bpf_prog_type); if (!IS_SUCCESS(result)) { ebpf_close_registry_key(program_key); goto Exit; @@ -276,7 +291,7 @@ ebpf_store_update_program_information( // Save "is_privileged". result = ebpf_write_registry_value_dword( - program_key, EBPF_PROGRAM_DATA_PRIVILEGED, program_info[i].program_type_descriptor.is_privileged); + program_key, EBPF_PROGRAM_DATA_PRIVILEGED, program_info[i].program_type_descriptor->is_privileged); if (!IS_SUCCESS(result)) { ebpf_close_registry_key(program_key); goto Exit; @@ -344,7 +359,7 @@ ebpf_store_delete_program_information(_In_ const ebpf_program_info_t* program_in // Convert program type GUID to string. wchar_t guid_string[GUID_STRING_LENGTH + 1]; result = ebpf_convert_guid_to_string( - &program_info->program_type_descriptor.program_type, guid_string, GUID_STRING_LENGTH + 1); + &program_info->program_type_descriptor->program_type, guid_string, GUID_STRING_LENGTH + 1); if (!IS_SUCCESS(result)) { goto Exit; } diff --git a/libs/ubpf/kernel/ubpf_kernel.vcxproj b/libs/ubpf/kernel/ubpf_kernel.vcxproj index 86b3f0658c..13159212dc 100644 --- a/libs/ubpf/kernel/ubpf_kernel.vcxproj +++ b/libs/ubpf/kernel/ubpf_kernel.vcxproj @@ -83,7 +83,7 @@ _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);_NO_CRT_STDIO_INLINE=1 - $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)libs\ubpf;$(SolutionDir)libs\ubpf\kernel;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm + $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)libs\ubpf;$(SolutionDir)libs\ubpf\kernel;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;$(SolutionDir)external\ebpf-verifier\src %(DisableSpecificWarnings) false @@ -91,7 +91,7 @@ _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);_NO_CRT_STDIO_INLINE=1 - $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)libs\ubpf;$(SolutionDir)libs\ubpf\kernel;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm + $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)libs\ubpf;$(SolutionDir)libs\ubpf\kernel;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;$(SolutionDir)external\ebpf-verifier\src %(DisableSpecificWarnings) false @@ -102,7 +102,7 @@ WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions);_NO_CRT_STDIO_INLINE=1;NDEBUG - $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)libs\ubpf;$(SolutionDir)libs\ubpf\kernel;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm + $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)libs\ubpf;$(SolutionDir)libs\ubpf\kernel;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;$(SolutionDir)external\ebpf-verifier\src %(DisableSpecificWarnings) false diff --git a/libs/ubpf/user/ubpf_user.vcxproj b/libs/ubpf/user/ubpf_user.vcxproj index a48a4abc3e..47de318954 100644 --- a/libs/ubpf/user/ubpf_user.vcxproj +++ b/libs/ubpf/user/ubpf_user.vcxproj @@ -84,7 +84,7 @@ true NotUsing pch.h - $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\user;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)libs\ubpf;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;%(AdditionalIncludeDirectories) + $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\user;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)libs\ubpf;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;$(SolutionDir)external\ebpf-verifier\src;%(AdditionalIncludeDirectories) false @@ -99,7 +99,7 @@ true NotUsing pch.h - $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\user;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)libs\ubpf;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;%(AdditionalIncludeDirectories) + $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\user;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)libs\ubpf;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;$(SolutionDir)external\ebpf-verifier\src;%(AdditionalIncludeDirectories) false @@ -117,7 +117,7 @@ true NotUsing pch.h - $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\user;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)libs\ubpf;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;%(AdditionalIncludeDirectories) + $(SolutionDir)include;$(SolutionDir)libs\shared;$(SolutionDir)libs\shared\user;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)libs\ubpf;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ubpf\build\vm;$(SolutionDir)external\ebpf-verifier\src;%(AdditionalIncludeDirectories) false diff --git a/netebpfext/net_ebpf_ext_bind.c b/netebpfext/net_ebpf_ext_bind.c index 1c65c291c2..2f4c580783 100644 --- a/netebpfext/net_ebpf_ext_bind.c +++ b/netebpfext/net_ebpf_ext_bind.c @@ -57,28 +57,30 @@ _ebpf_bind_context_destroy( // Bind Program Information NPI Provider. // static ebpf_program_data_t _ebpf_bind_program_data = { + .header = {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, .program_info = &_ebpf_bind_program_info, .context_create = _ebpf_bind_context_create, .context_destroy = _ebpf_bind_context_destroy, .required_irql = PASSIVE_LEVEL, }; -static ebpf_extension_data_t _ebpf_bind_program_info_provider_data = { - NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_bind_program_data), &_ebpf_bind_program_data}; - -NPI_MODULEID DECLSPEC_SELECTANY _ebpf_bind_program_info_provider_moduleid = {sizeof(NPI_MODULEID), MIT_GUID, {0}}; +// Set the program type as the provider module id. +NPI_MODULEID DECLSPEC_SELECTANY _ebpf_bind_program_info_provider_moduleid = { + sizeof(NPI_MODULEID), MIT_GUID, EBPF_PROGRAM_TYPE_BIND_GUID}; static net_ebpf_extension_program_info_provider_t* _ebpf_bind_program_info_provider_context = NULL; // // Bind Hook NPI Provider. // -ebpf_attach_provider_data_t _net_ebpf_bind_hook_provider_data; - -ebpf_extension_data_t _net_ebpf_extension_bind_hook_provider_data = { - EBPF_ATTACH_PROVIDER_DATA_VERSION, sizeof(_net_ebpf_bind_hook_provider_data), &_net_ebpf_bind_hook_provider_data}; +ebpf_attach_provider_data_t _net_ebpf_bind_hook_provider_data = { + {EBPF_ATTACH_PROVIDER_DATA_VERSION_0, sizeof(_net_ebpf_bind_hook_provider_data)}, + EBPF_PROGRAM_TYPE_BIND_GUID, + BPF_ATTACH_TYPE_BIND, + BPF_LINK_TYPE_PLAIN}; -NPI_MODULEID DECLSPEC_SELECTANY _ebpf_bind_hook_provider_moduleid = {sizeof(NPI_MODULEID), MIT_GUID, {0}}; +NPI_MODULEID DECLSPEC_SELECTANY _ebpf_bind_hook_provider_moduleid = { + sizeof(NPI_MODULEID), MIT_GUID, EBPF_ATTACH_TYPE_BIND_GUID}; static net_ebpf_extension_hook_provider_t* _ebpf_bind_hook_provider_context = NULL; @@ -159,12 +161,10 @@ net_ebpf_ext_bind_register_providers() NET_EBPF_EXT_LOG_ENTRY(); const net_ebpf_extension_program_info_provider_parameters_t program_info_provider_parameters = { - &_ebpf_bind_program_info_provider_moduleid, &_ebpf_bind_program_info_provider_data}; + &_ebpf_bind_program_info_provider_moduleid, &_ebpf_bind_program_data}; const net_ebpf_extension_hook_provider_parameters_t hook_provider_parameters = { - &_ebpf_bind_hook_provider_moduleid, &_net_ebpf_extension_bind_hook_provider_data}; + &_ebpf_bind_hook_provider_moduleid, &_net_ebpf_bind_hook_provider_data}; - // Set the program type as the provider module id. - _ebpf_bind_program_info_provider_moduleid.Guid = EBPF_PROGRAM_TYPE_BIND; status = net_ebpf_extension_program_info_provider_register( &program_info_provider_parameters, &_ebpf_bind_program_info_provider_context); if (!NT_SUCCESS(status)) { @@ -176,11 +176,6 @@ net_ebpf_ext_bind_register_providers() goto Exit; } - _net_ebpf_bind_hook_provider_data.supported_program_type = EBPF_PROGRAM_TYPE_BIND; - // Set the attach type as the provider module id. - _ebpf_bind_hook_provider_moduleid.Guid = EBPF_ATTACH_TYPE_BIND; - _net_ebpf_bind_hook_provider_data.bpf_attach_type = BPF_ATTACH_TYPE_BIND; - _net_ebpf_bind_hook_provider_data.link_type = BPF_LINK_TYPE_PLAIN; status = net_ebpf_extension_hook_provider_register( &hook_provider_parameters, _net_ebpf_extension_bind_on_client_attach, diff --git a/netebpfext/net_ebpf_ext_hook_provider.h b/netebpfext/net_ebpf_ext_hook_provider.h index 6f02c78227..7aae0356b7 100644 --- a/netebpfext/net_ebpf_ext_hook_provider.h +++ b/netebpfext/net_ebpf_ext_hook_provider.h @@ -112,8 +112,8 @@ typedef void (*net_ebpf_extension_hook_on_client_detach)(_In_ const net_ebpf_ext */ typedef struct _net_ebpf_extension_hook_provider_parameters { - const NPI_MODULEID* provider_module_id; ///< NPI provider module ID. - const ebpf_extension_data_t* provider_data; ///< Hook provider data (contains supported program types). + const NPI_MODULEID* provider_module_id; ///< NPI provider module ID. + const ebpf_attach_provider_data_t* provider_data; ///< Hook provider data (contains supported program types). } net_ebpf_extension_hook_provider_parameters_t; /** diff --git a/netebpfext/net_ebpf_ext_prog_info_provider.h b/netebpfext/net_ebpf_ext_prog_info_provider.h index e89e2d6c83..4065494a60 100644 --- a/netebpfext/net_ebpf_ext_prog_info_provider.h +++ b/netebpfext/net_ebpf_ext_prog_info_provider.h @@ -12,8 +12,8 @@ typedef struct _net_ebpf_extension_program_info_provider net_ebpf_extension_prog */ typedef struct _net_ebpf_extension_program_info_provider_parameters { - const NPI_MODULEID* provider_module_id; ///< NPI provider module ID. - const ebpf_extension_data_t* provider_data; ///< Program info NPI provider data (contains ebpf_program_data_t). + const NPI_MODULEID* provider_module_id; ///< NPI provider module ID. + const ebpf_program_data_t* provider_data; ///< Program info NPI provider data. } net_ebpf_extension_program_info_provider_parameters_t; /** diff --git a/netebpfext/net_ebpf_ext_program_info.h b/netebpfext/net_ebpf_ext_program_info.h index b3aeccb204..66b7d9e366 100644 --- a/netebpfext/net_ebpf_ext_program_info.h +++ b/netebpfext/net_ebpf_ext_program_info.h @@ -11,7 +11,8 @@ // XDP_TEST helper function prototype descriptors. static const ebpf_helper_function_prototype_t _xdp_test_ebpf_extension_helper_function_prototype[] = { - {XDP_EXT_HELPER_FUNCTION_START + 1, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + XDP_EXT_HELPER_FUNCTION_START + 1, "bpf_xdp_adjust_head", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX, EBPF_ARGUMENT_TYPE_ANYTHING}}}; @@ -23,13 +24,22 @@ static const ebpf_context_descriptor_t _ebpf_xdp_test_context_descriptor = { EBPF_OFFSET_OF(xdp_md_t, data_end), EBPF_OFFSET_OF(xdp_md_t, data_meta)}; +static const ebpf_program_type_descriptor_t _ebpf_xdp_test_program_type_descriptor = { + {EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, sizeof(ebpf_program_type_descriptor_t)}, + "xdp_test", + &_ebpf_xdp_test_context_descriptor, + EBPF_PROGRAM_TYPE_XDP_TEST_GUID, + BPF_PROG_TYPE_XDP_TEST, + 0}; static const ebpf_program_info_t _ebpf_xdp_test_program_info = { - {"xdp_test", &_ebpf_xdp_test_context_descriptor, EBPF_PROGRAM_TYPE_XDP_TEST_GUID, BPF_PROG_TYPE_XDP_TEST}, + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &_ebpf_xdp_test_program_type_descriptor, EBPF_COUNT_OF(_xdp_test_ebpf_extension_helper_function_prototype), _xdp_test_ebpf_extension_helper_function_prototype}; static const ebpf_program_section_info_t _ebpf_xdp_test_section_info[] = { - {(const wchar_t*)L"xdp_test", + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"xdp_test", &EBPF_PROGRAM_TYPE_XDP_TEST, &EBPF_ATTACH_TYPE_XDP_TEST, BPF_PROG_TYPE_XDP_TEST, @@ -39,30 +49,54 @@ static const ebpf_program_section_info_t _ebpf_xdp_test_section_info[] = { static const ebpf_context_descriptor_t _ebpf_bind_context_descriptor = { sizeof(bind_md_t), EBPF_OFFSET_OF(bind_md_t, app_id_start), EBPF_OFFSET_OF(bind_md_t, app_id_end), -1}; +static const ebpf_program_type_descriptor_t _ebpf_bind_program_type_descriptor = { + {EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, sizeof(ebpf_program_type_descriptor_t)}, + "bind", + &_ebpf_bind_context_descriptor, + EBPF_PROGRAM_TYPE_BIND_GUID, + BPF_PROG_TYPE_BIND, + 0}; static const ebpf_program_info_t _ebpf_bind_program_info = { - {"bind", &_ebpf_bind_context_descriptor, EBPF_PROGRAM_TYPE_BIND_GUID, BPF_PROG_TYPE_BIND}, 0, NULL}; + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &_ebpf_bind_program_type_descriptor, + 0, + NULL, + 0, + NULL}; static const ebpf_program_section_info_t _ebpf_bind_section_info[] = { - {L"bind", &EBPF_PROGRAM_TYPE_BIND, &EBPF_ATTACH_TYPE_BIND, BPF_PROG_TYPE_BIND, BPF_ATTACH_TYPE_BIND}}; + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"bind", + &EBPF_PROGRAM_TYPE_BIND, + &EBPF_ATTACH_TYPE_BIND, + BPF_PROG_TYPE_BIND, + BPF_ATTACH_TYPE_BIND}}; // CGROUP_SOCK_ADDR extension specific helper function prototypes. static const ebpf_helper_function_prototype_t _sock_addr_ebpf_extension_helper_function_prototype[] = { - {BPF_FUNC_sock_addr_get_current_pid_tgid, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_sock_addr_get_current_pid_tgid, "bpf_sock_addr_get_current_pid_tgid", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX}}, - {BPF_FUNC_sock_addr_set_redirect_context, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_sock_addr_set_redirect_context, "bpf_sock_addr_set_redirect_context", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX, EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, EBPF_ARGUMENT_TYPE_CONST_SIZE}}}; // CGROUP_SOCK_ADDR global helper function prototypes. static const ebpf_helper_function_prototype_t _ebpf_sock_addr_global_helper_function_prototype[] = { - {BPF_FUNC_get_current_logon_id, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_get_current_logon_id, "bpf_get_current_logon_id", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX}}, - {BPF_FUNC_is_current_admin, "bpf_is_current_admin", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX}}}; + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_is_current_admin, + "bpf_is_current_admin", + EBPF_RETURN_TYPE_INTEGER, + {EBPF_ARGUMENT_TYPE_PTR_TO_CTX}}}; // CGROUP_SOCK_ADDR program information. static const ebpf_context_descriptor_t _ebpf_sock_addr_context_descriptor = { @@ -72,33 +106,42 @@ static const ebpf_context_descriptor_t _ebpf_sock_addr_context_descriptor = { -1, // Offset into ctx struct for pointer to metadata, or -1 if none. }; +static const ebpf_program_type_descriptor_t _ebpf_sock_addr_program_type_desciptor = { + {EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, sizeof(ebpf_program_type_descriptor_t)}, + "sock_addr", + &_ebpf_sock_addr_context_descriptor, + EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR_GUID, + BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + 0}; static const ebpf_program_info_t _ebpf_sock_addr_program_info = { - {"sock_addr", - &_ebpf_sock_addr_context_descriptor, - EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR_GUID, - BPF_PROG_TYPE_CGROUP_SOCK_ADDR}, + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &_ebpf_sock_addr_program_type_desciptor, EBPF_COUNT_OF(_sock_addr_ebpf_extension_helper_function_prototype), _sock_addr_ebpf_extension_helper_function_prototype, EBPF_COUNT_OF(_ebpf_sock_addr_global_helper_function_prototype), _ebpf_sock_addr_global_helper_function_prototype}; static const ebpf_program_section_info_t _ebpf_sock_addr_section_info[] = { - {L"cgroup/connect4", + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"cgroup/connect4", &EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, &EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT, BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_CONNECT}, - {L"cgroup/connect6", + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"cgroup/connect6", &EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, &EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT, BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_CONNECT}, - {L"cgroup/recv_accept4", + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"cgroup/recv_accept4", &EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, &EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT, BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_RECV_ACCEPT}, - {L"cgroup/recv_accept6", + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"cgroup/recv_accept6", &EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, &EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT, BPF_PROG_TYPE_CGROUP_SOCK_ADDR, @@ -112,11 +155,24 @@ static const ebpf_context_descriptor_t _ebpf_sock_ops_context_descriptor = { -1, // Offset into ctx struct for pointer to metadata, or -1 if none. }; +static const ebpf_program_type_descriptor_t _ebpf_sock_ops_program_type_descriptor = { + {EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, sizeof(ebpf_program_type_descriptor_t)}, + "sockops", + &_ebpf_sock_ops_context_descriptor, + EBPF_PROGRAM_TYPE_SOCK_OPS_GUID, + BPF_PROG_TYPE_SOCK_OPS, + 0}; static const ebpf_program_info_t _ebpf_sock_ops_program_info = { - {"sockops", &_ebpf_sock_ops_context_descriptor, EBPF_PROGRAM_TYPE_SOCK_OPS_GUID, BPF_PROG_TYPE_SOCK_OPS}, 0, NULL}; + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &_ebpf_sock_ops_program_type_descriptor, + 0, + NULL, + 0, + NULL}; static const ebpf_program_section_info_t _ebpf_sock_ops_section_info[] = { - {L"sockops", + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"sockops", &EBPF_PROGRAM_TYPE_SOCK_OPS, &EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS, BPF_PROG_TYPE_SOCK_OPS, diff --git a/netebpfext/net_ebpf_ext_sock_addr.c b/netebpfext/net_ebpf_ext_sock_addr.c index dbbd1b7c57..e626ad7410 100644 --- a/netebpfext/net_ebpf_ext_sock_addr.c +++ b/netebpfext/net_ebpf_ext_sock_addr.c @@ -470,15 +470,20 @@ static const void* _ebpf_sock_addr_specific_helper_functions[] = { (void*)_ebpf_sock_addr_get_current_pid_tgid, (void*)_ebpf_sock_addr_set_redirect_context}; static ebpf_helper_function_addresses_t _ebpf_sock_addr_specific_helper_function_address_table = { - EBPF_COUNT_OF(_ebpf_sock_addr_specific_helper_functions), (uint64_t*)_ebpf_sock_addr_specific_helper_functions}; + {EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, EBPF_MAX_GENERAL_HELPER_FUNCTION}, + EBPF_COUNT_OF(_ebpf_sock_addr_specific_helper_functions), + (uint64_t*)_ebpf_sock_addr_specific_helper_functions}; static const void* _ebpf_sock_addr_global_helper_functions[] = { (void*)_ebpf_sock_addr_get_current_logon_id, (void*)_ebpf_sock_addr_is_current_admin}; static ebpf_helper_function_addresses_t _ebpf_sock_addr_global_helper_function_address_table = { - EBPF_COUNT_OF(_ebpf_sock_addr_global_helper_functions), (uint64_t*)_ebpf_sock_addr_global_helper_functions}; + {EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, EBPF_MAX_GENERAL_HELPER_FUNCTION}, + EBPF_COUNT_OF(_ebpf_sock_addr_global_helper_functions), + (uint64_t*)_ebpf_sock_addr_global_helper_functions}; static ebpf_program_data_t _ebpf_sock_addr_program_data = { + .header = {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, .program_info = &_ebpf_sock_addr_program_info, .program_type_specific_helper_function_addresses = &_ebpf_sock_addr_specific_helper_function_address_table, .global_helper_function_addresses = &_ebpf_sock_addr_global_helper_function_address_table, @@ -487,10 +492,9 @@ static ebpf_program_data_t _ebpf_sock_addr_program_data = { .required_irql = DISPATCH_LEVEL, }; -static ebpf_extension_data_t _ebpf_sock_addr_program_info_provider_data = { - NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_sock_addr_program_data), &_ebpf_sock_addr_program_data}; - -NPI_MODULEID DECLSPEC_SELECTANY _ebpf_sock_addr_program_info_provider_moduleid = {sizeof(NPI_MODULEID), MIT_GUID, {0}}; +// Set the program type as the provider module id. +NPI_MODULEID DECLSPEC_SELECTANY _ebpf_sock_addr_program_info_provider_moduleid = { + sizeof(NPI_MODULEID), MIT_GUID, EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR_GUID}; static net_ebpf_extension_program_info_provider_t* _ebpf_sock_addr_program_info_provider_context = NULL; @@ -499,7 +503,6 @@ static net_ebpf_extension_program_info_provider_t* _ebpf_sock_addr_program_info_ // ebpf_attach_provider_data_t _net_ebpf_sock_addr_hook_provider_data[NET_EBPF_SOCK_ADDR_HOOK_PROVIDER_COUNT] = {0}; -ebpf_extension_data_t _net_ebpf_extension_sock_addr_hook_provider_data[NET_EBPF_SOCK_ADDR_HOOK_PROVIDER_COUNT] = {0}; NPI_MODULEID DECLSPEC_SELECTANY _ebpf_sock_addr_hook_provider_moduleid[NET_EBPF_SOCK_ADDR_HOOK_PROVIDER_COUNT] = {0}; static net_ebpf_extension_hook_provider_t* @@ -535,8 +538,8 @@ _net_ebpf_extension_sock_addr_on_client_attach( goto Exit; } - if (client_data->size > 0) { - if ((client_data->size != sizeof(uint32_t)) || (client_data->data == NULL)) { + if (client_data->header.size > 0) { + if ((client_data->header.size != sizeof(uint32_t)) || (client_data->data == NULL)) { NET_EBPF_EXT_LOG_MESSAGE( NET_EBPF_EXT_TRACELOG_LEVEL_ERROR, NET_EBPF_EXT_TRACELOG_KEYWORD_SOCK_ADDR, @@ -883,7 +886,7 @@ net_ebpf_ext_sock_addr_register_providers() NET_EBPF_EXT_LOG_ENTRY(); const net_ebpf_extension_program_info_provider_parameters_t program_info_provider_parameters = { - &_ebpf_sock_addr_program_info_provider_moduleid, &_ebpf_sock_addr_program_info_provider_data}; + &_ebpf_sock_addr_program_info_provider_moduleid, &_ebpf_sock_addr_program_data}; status = _net_ebpf_sock_addr_create_security_descriptor(); if (!NT_SUCCESS(status)) { @@ -898,8 +901,6 @@ net_ebpf_ext_sock_addr_register_providers() _net_ebpf_sock_addr_initialize_globals(); sock_addr_globals_initialized = TRUE; - // Set the program type as the provider module id. - _ebpf_sock_addr_program_info_provider_moduleid.Guid = EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR; status = net_ebpf_extension_program_info_provider_register( &program_info_provider_parameters, &_ebpf_sock_addr_program_info_provider_context); if (!NT_SUCCESS(status)) { @@ -913,15 +914,14 @@ net_ebpf_ext_sock_addr_register_providers() for (int i = 0; i < NET_EBPF_SOCK_ADDR_HOOK_PROVIDER_COUNT; i++) { const net_ebpf_extension_hook_provider_parameters_t hook_provider_parameters = { - &_ebpf_sock_addr_hook_provider_moduleid[i], &_net_ebpf_extension_sock_addr_hook_provider_data[i]}; + &_ebpf_sock_addr_hook_provider_moduleid[i], &_net_ebpf_sock_addr_hook_provider_data[i]}; + _net_ebpf_sock_addr_hook_provider_data[i].header.version = EBPF_ATTACH_PROVIDER_DATA_VERSION_0; + _net_ebpf_sock_addr_hook_provider_data[i].header.size = sizeof(ebpf_attach_provider_data_t); _net_ebpf_sock_addr_hook_provider_data[i].supported_program_type = EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR; _net_ebpf_sock_addr_hook_provider_data[i].bpf_attach_type = (bpf_attach_type_t)_net_ebpf_extension_sock_addr_bpf_attach_types[i]; _net_ebpf_sock_addr_hook_provider_data[i].link_type = BPF_LINK_TYPE_CGROUP; - _net_ebpf_extension_sock_addr_hook_provider_data[i].version = EBPF_ATTACH_PROVIDER_DATA_VERSION; - _net_ebpf_extension_sock_addr_hook_provider_data[i].data = &_net_ebpf_sock_addr_hook_provider_data[i]; - _net_ebpf_extension_sock_addr_hook_provider_data[i].size = sizeof(ebpf_attach_provider_data_t); // Set the attach type as the provider module id. _ebpf_sock_addr_hook_provider_moduleid[i].Length = sizeof(NPI_MODULEID); diff --git a/netebpfext/net_ebpf_ext_sock_ops.c b/netebpfext/net_ebpf_ext_sock_ops.c index 12a577399a..d51ba94df1 100644 --- a/netebpfext/net_ebpf_ext_sock_ops.c +++ b/netebpfext/net_ebpf_ext_sock_ops.c @@ -79,16 +79,16 @@ _ebpf_sock_ops_context_destroy( _Inout_ size_t* context_size_out); static ebpf_program_data_t _ebpf_sock_ops_program_data = { + .header = {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, .program_info = &_ebpf_sock_ops_program_info, .context_create = &_ebpf_sock_ops_context_create, .context_destroy = &_ebpf_sock_ops_context_destroy, .required_irql = DISPATCH_LEVEL, }; -static ebpf_extension_data_t _ebpf_sock_ops_program_info_provider_data = { - NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_sock_ops_program_data), &_ebpf_sock_ops_program_data}; - -NPI_MODULEID DECLSPEC_SELECTANY _ebpf_sock_ops_program_info_provider_moduleid = {sizeof(NPI_MODULEID), MIT_GUID, {0}}; +// Set the program type as the provider module id. +NPI_MODULEID DECLSPEC_SELECTANY _ebpf_sock_ops_program_info_provider_moduleid = { + sizeof(NPI_MODULEID), MIT_GUID, EBPF_PROGRAM_TYPE_SOCK_OPS_GUID}; static net_ebpf_extension_program_info_provider_t* _ebpf_sock_ops_program_info_provider_context = NULL; @@ -96,14 +96,14 @@ static net_ebpf_extension_program_info_provider_t* _ebpf_sock_ops_program_info_p // SOCK_OPS Hook NPI Provider. // -ebpf_attach_provider_data_t _net_ebpf_sock_ops_hook_provider_data; - -ebpf_extension_data_t _net_ebpf_extension_sock_ops_hook_provider_data = { - EBPF_ATTACH_PROVIDER_DATA_VERSION, - sizeof(_net_ebpf_sock_ops_hook_provider_data), - &_net_ebpf_sock_ops_hook_provider_data}; +ebpf_attach_provider_data_t _net_ebpf_sock_ops_hook_provider_data = { + {EBPF_ATTACH_PROVIDER_DATA_VERSION_0, sizeof(ebpf_attach_provider_data_t)}, + EBPF_PROGRAM_TYPE_SOCK_OPS_GUID, + BPF_CGROUP_SOCK_OPS, + BPF_LINK_TYPE_CGROUP}; -NPI_MODULEID DECLSPEC_SELECTANY _ebpf_sock_ops_hook_provider_moduleid = {sizeof(NPI_MODULEID), MIT_GUID, {0}}; +NPI_MODULEID DECLSPEC_SELECTANY _ebpf_sock_ops_hook_provider_moduleid = { + sizeof(NPI_MODULEID), MIT_GUID, EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS_GUID}; static net_ebpf_extension_hook_provider_t* _ebpf_sock_ops_hook_provider_context = NULL; @@ -132,8 +132,8 @@ net_ebpf_extension_sock_ops_on_client_attach( goto Exit; } - if (client_data->size > 0) { - if ((client_data->size != sizeof(uint32_t)) || (client_data->data == NULL)) { + if (client_data->header.size > 0) { + if ((client_data->header.size != sizeof(uint32_t)) || (client_data->data == NULL)) { result = EBPF_INVALID_ARGUMENT; goto Exit; } @@ -255,15 +255,13 @@ net_ebpf_ext_sock_ops_register_providers() { NTSTATUS status = STATUS_SUCCESS; const net_ebpf_extension_hook_provider_parameters_t hook_provider_parameters = { - &_ebpf_sock_ops_hook_provider_moduleid, &_net_ebpf_extension_sock_ops_hook_provider_data}; + &_ebpf_sock_ops_hook_provider_moduleid, &_net_ebpf_sock_ops_hook_provider_data}; const net_ebpf_extension_program_info_provider_parameters_t program_info_provider_parameters = { - &_ebpf_sock_ops_program_info_provider_moduleid, &_ebpf_sock_ops_program_info_provider_data}; + &_ebpf_sock_ops_program_info_provider_moduleid, &_ebpf_sock_ops_program_data}; NET_EBPF_EXT_LOG_ENTRY(); - // Set the program type as the provider module id. - _ebpf_sock_ops_program_info_provider_moduleid.Guid = EBPF_PROGRAM_TYPE_SOCK_OPS; status = net_ebpf_extension_program_info_provider_register( &program_info_provider_parameters, &_ebpf_sock_ops_program_info_provider_context); if (!NT_SUCCESS(status)) { @@ -275,12 +273,6 @@ net_ebpf_ext_sock_ops_register_providers() goto Exit; } - _net_ebpf_sock_ops_hook_provider_data.supported_program_type = EBPF_PROGRAM_TYPE_SOCK_OPS; - _net_ebpf_sock_ops_hook_provider_data.bpf_attach_type = BPF_CGROUP_SOCK_OPS; - _net_ebpf_sock_ops_hook_provider_data.link_type = BPF_LINK_TYPE_CGROUP; - - // Set the attach type as the provider module id. - _ebpf_sock_ops_hook_provider_moduleid.Guid = EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS; // Register the provider context and pass the pointer to the WFP filter parameters // corresponding to this hook type as custom data. status = net_ebpf_extension_hook_provider_register( diff --git a/netebpfext/net_ebpf_ext_xdp.c b/netebpfext/net_ebpf_ext_xdp.c index a9e68e8389..785392ec70 100644 --- a/netebpfext/net_ebpf_ext_xdp.c +++ b/netebpfext/net_ebpf_ext_xdp.c @@ -83,9 +83,12 @@ _ebpf_xdp_context_delete( static const void* _ebpf_xdp_test_helper_functions[] = {(void*)&_net_ebpf_xdp_adjust_head}; static ebpf_helper_function_addresses_t _ebpf_xdp_test_helper_function_address_table = { - EBPF_COUNT_OF(_ebpf_xdp_test_helper_functions), (uint64_t*)_ebpf_xdp_test_helper_functions}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(_ebpf_xdp_test_helper_functions), + (uint64_t*)_ebpf_xdp_test_helper_functions}; static ebpf_program_data_t _ebpf_xdp_test_program_data = { + .header = {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, .program_info = &_ebpf_xdp_test_program_info, .program_type_specific_helper_function_addresses = &_ebpf_xdp_test_helper_function_address_table, .context_create = _ebpf_xdp_context_create, @@ -93,10 +96,9 @@ static ebpf_program_data_t _ebpf_xdp_test_program_data = { .required_irql = DISPATCH_LEVEL, }; -static ebpf_extension_data_t _ebpf_xdp_test_program_info_provider_data = { - NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_xdp_test_program_data), &_ebpf_xdp_test_program_data}; - -NPI_MODULEID DECLSPEC_SELECTANY _ebpf_xdp_test_program_info_provider_moduleid = {sizeof(NPI_MODULEID), MIT_GUID, {0}}; +// Set the program type as the provider module id. +NPI_MODULEID DECLSPEC_SELECTANY _ebpf_xdp_test_program_info_provider_moduleid = { + sizeof(NPI_MODULEID), MIT_GUID, EBPF_PROGRAM_TYPE_XDP_TEST_GUID}; static net_ebpf_extension_program_info_provider_t* _ebpf_xdp_test_program_info_provider_context = NULL; @@ -104,14 +106,14 @@ static net_ebpf_extension_program_info_provider_t* _ebpf_xdp_test_program_info_p // XDP Hook NPI Provider. // -ebpf_attach_provider_data_t _net_ebpf_xdp_test_hook_provider_data; - -ebpf_extension_data_t _net_ebpf_extension_xdp_test_hook_provider_data = { - EBPF_ATTACH_PROVIDER_DATA_VERSION, - sizeof(_net_ebpf_xdp_test_hook_provider_data), - &_net_ebpf_xdp_test_hook_provider_data}; +ebpf_attach_provider_data_t _net_ebpf_xdp_test_hook_provider_data = { + {EBPF_ATTACH_PROVIDER_DATA_VERSION_0, sizeof(ebpf_attach_provider_data_t)}, + EBPF_PROGRAM_TYPE_XDP_TEST_GUID, + BPF_XDP_TEST, + BPF_LINK_TYPE_XDP}; -NPI_MODULEID DECLSPEC_SELECTANY _ebpf_xdp_test_hook_provider_moduleid = {sizeof(NPI_MODULEID), MIT_GUID, {0}}; +NPI_MODULEID DECLSPEC_SELECTANY _ebpf_xdp_test_hook_provider_moduleid = { + sizeof(NPI_MODULEID), MIT_GUID, EBPF_ATTACH_TYPE_XDP_TEST_GUID}; static net_ebpf_extension_hook_provider_t* _ebpf_xdp_test_hook_provider_context = NULL; @@ -144,8 +146,8 @@ net_ebpf_extension_xdp_on_client_attach( goto Exit; } - if (client_data->size > 0) { - if ((client_data->size != sizeof(uint32_t)) || (client_data->data == NULL)) { + if (client_data->header.size > 0) { + if ((client_data->header.size != sizeof(uint32_t)) || (client_data->data == NULL)) { result = EBPF_INVALID_ARGUMENT; NET_EBPF_EXT_LOG_MESSAGE( NET_EBPF_EXT_TRACELOG_LEVEL_ERROR, @@ -251,14 +253,12 @@ net_ebpf_ext_xdp_register_providers() NTSTATUS status = STATUS_SUCCESS; const net_ebpf_extension_program_info_provider_parameters_t program_info_provider_parameters = { - &_ebpf_xdp_test_program_info_provider_moduleid, &_ebpf_xdp_test_program_info_provider_data}; + &_ebpf_xdp_test_program_info_provider_moduleid, &_ebpf_xdp_test_program_data}; const net_ebpf_extension_hook_provider_parameters_t hook_provider_parameters = { - &_ebpf_xdp_test_hook_provider_moduleid, &_net_ebpf_extension_xdp_test_hook_provider_data}; + &_ebpf_xdp_test_hook_provider_moduleid, &_net_ebpf_xdp_test_hook_provider_data}; NET_EBPF_EXT_LOG_ENTRY(); - // Set the program type as the provider module id. - _ebpf_xdp_test_program_info_provider_moduleid.Guid = EBPF_PROGRAM_TYPE_XDP_TEST; status = net_ebpf_extension_program_info_provider_register( &program_info_provider_parameters, &_ebpf_xdp_test_program_info_provider_context); if (!NT_SUCCESS(status)) { @@ -270,11 +270,6 @@ net_ebpf_ext_xdp_register_providers() goto Exit; } - _net_ebpf_xdp_test_hook_provider_data.supported_program_type = EBPF_PROGRAM_TYPE_XDP_TEST; - // Set the attach type as the provider module id. - _ebpf_xdp_test_hook_provider_moduleid.Guid = EBPF_ATTACH_TYPE_XDP_TEST; - _net_ebpf_xdp_test_hook_provider_data.bpf_attach_type = BPF_XDP_TEST; - _net_ebpf_xdp_test_hook_provider_data.link_type = BPF_LINK_TYPE_XDP; status = net_ebpf_extension_hook_provider_register( &hook_provider_parameters, net_ebpf_extension_xdp_on_client_attach, diff --git a/tests/end_to_end/end_to_end.cpp b/tests/end_to_end/end_to_end.cpp index e30fadd4eb..0ffe14da32 100644 --- a/tests/end_to_end/end_to_end.cpp +++ b/tests/end_to_end/end_to_end.cpp @@ -3001,19 +3001,17 @@ extension_reload_test(ebpf_execution_type_t execution_type) // Reload the extension provider with missing helper function. { - ebpf_helper_function_addresses_t changed_helper_function_address_table = - _sample_ebpf_ext_helper_function_address_table; + ebpf_helper_function_addresses_t changed_helper_function_address_table = { + .header = {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + .helper_function_count = 0, + .helper_function_address = nullptr}; ebpf_program_data_t changed_program_data = _test_ebpf_sample_extension_program_data; changed_program_data.program_type_specific_helper_function_addresses = &changed_helper_function_address_table; - changed_helper_function_address_table.helper_function_count = 0; - - ebpf_extension_data_t changed_provider_data = { - TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(changed_program_data), &changed_program_data}; single_instance_hook_t hook(EBPF_PROGRAM_TYPE_SAMPLE, EBPF_ATTACH_TYPE_SAMPLE); REQUIRE(hook.initialize() == EBPF_SUCCESS); program_info_provider_t sample_program_info; - REQUIRE(sample_program_info.initialize(EBPF_PROGRAM_TYPE_SAMPLE, &changed_provider_data) == EBPF_SUCCESS); + REQUIRE(sample_program_info.initialize(EBPF_PROGRAM_TYPE_SAMPLE, &changed_program_data) == EBPF_SUCCESS); // Program should re-attach to the hook. @@ -3025,21 +3023,23 @@ extension_reload_test(ebpf_execution_type_t execution_type) // Reload the extension provider with changed helper function data. { + ebpf_helper_function_prototype_t helper_function_prototypes[3]; + std::copy( + _sample_ebpf_extension_helper_function_prototype, + _sample_ebpf_extension_helper_function_prototype + 3, + helper_function_prototypes); + // Change the return type of the helper function from EBPF_RETURN_TYPE_INTEGER to + // EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL. + helper_function_prototypes[0].return_type = EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL; ebpf_program_info_t changed_program_info = _sample_ebpf_extension_program_info; - ebpf_helper_function_prototype_t helper_function_prototypes[] = { - _sample_ebpf_extension_global_helper_function_prototype[0]}; - helper_function_prototypes[0].return_type = EBPF_RETURN_TYPE_INTEGER; changed_program_info.program_type_specific_helper_prototype = helper_function_prototypes; ebpf_program_data_t changed_program_data = _test_ebpf_sample_extension_program_data; changed_program_data.program_info = &changed_program_info; - ebpf_extension_data_t changed_provider_data = { - TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(changed_program_data), &changed_program_data}; - single_instance_hook_t hook(EBPF_PROGRAM_TYPE_SAMPLE, EBPF_ATTACH_TYPE_SAMPLE); REQUIRE(hook.initialize() == EBPF_SUCCESS); program_info_provider_t sample_program_info; - REQUIRE(sample_program_info.initialize(EBPF_PROGRAM_TYPE_SAMPLE, &changed_provider_data) == EBPF_SUCCESS); + REQUIRE(sample_program_info.initialize(EBPF_PROGRAM_TYPE_SAMPLE, &changed_program_data) == EBPF_SUCCESS); // Program should re-attach to the hook. diff --git a/tests/end_to_end/helpers.h b/tests/end_to_end/helpers.h index f8ef633754..fc6a05a02b 100644 --- a/tests/end_to_end/helpers.h +++ b/tests/end_to_end/helpers.h @@ -117,6 +117,8 @@ typedef class _single_instance_hook : public _hook_helper client_dispatch_table(nullptr), link_object(nullptr), client_registration_instance(nullptr), nmr_binding_handle(nullptr), nmr_provider_handle(nullptr) { + attach_provider_data.header.version = EBPF_ATTACH_PROVIDER_DATA_VERSION_0; + attach_provider_data.header.size = sizeof(attach_provider_data); attach_provider_data.supported_program_type = program_type; attach_provider_data.bpf_attach_type = get_bpf_attach_type(&attach_type); this->attach_type = attach_type; @@ -308,8 +310,6 @@ typedef class _single_instance_hook : public _hook_helper ebpf_attach_type_t attach_type; ebpf_attach_provider_data_t attach_provider_data; - ebpf_extension_data_t provider_data = { - EBPF_ATTACH_PROVIDER_DATA_VERSION, sizeof(attach_provider_data), &attach_provider_data}; NPI_MODULEID module_id = { sizeof(NPI_MODULEID), MIT_GUID, @@ -321,12 +321,12 @@ typedef class _single_instance_hook : public _hook_helper (NPI_PROVIDER_DETACH_CLIENT_FN*)provider_detach_client_callback, NULL, { - EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION, + 0, sizeof(NPI_REGISTRATION_INSTANCE), &EBPF_HOOK_EXTENSION_IID, &module_id, 0, - &provider_data, + &attach_provider_data, }, }; HANDLE nmr_provider_handle; @@ -621,51 +621,52 @@ _sample_test_context_destroy( static const void* _mock_xdp_helper_functions[] = {(void*)&test_xdp_helper_t::adjust_head}; static ebpf_helper_function_addresses_t _mock_xdp_helper_function_address_table = { - EBPF_COUNT_OF(_mock_xdp_helper_functions), (uint64_t*)_mock_xdp_helper_functions}; - + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(_mock_xdp_helper_functions), + (uint64_t*)_mock_xdp_helper_functions}; + +static const ebpf_program_type_descriptor_t _mock_xdp_program_type_descriptor = { + EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, + sizeof(ebpf_program_type_descriptor_t), + "xdp", + &_ebpf_xdp_test_context_descriptor, + EBPF_PROGRAM_TYPE_XDP_GUID, + BPF_PROG_TYPE_XDP, + 0}; static const ebpf_program_info_t _mock_xdp_program_info = { - {"xdp", &_ebpf_xdp_test_context_descriptor, EBPF_PROGRAM_TYPE_XDP_GUID, BPF_PROG_TYPE_XDP}, + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &_mock_xdp_program_type_descriptor, EBPF_COUNT_OF(_xdp_test_ebpf_extension_helper_function_prototype), _xdp_test_ebpf_extension_helper_function_prototype}; static ebpf_program_data_t _mock_xdp_program_data = { + {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, &_mock_xdp_program_info, &_mock_xdp_helper_function_address_table, nullptr, _xdp_context_create, _xdp_context_destroy}; -static ebpf_extension_data_t _mock_xdp_program_info_provider_data = { - TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_mock_xdp_program_data), &_mock_xdp_program_data}; - // XDP_TEST. static ebpf_program_data_t _ebpf_xdp_test_program_data = { + {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, &_ebpf_xdp_test_program_info, &_mock_xdp_helper_function_address_table, nullptr, _xdp_context_create, _xdp_context_destroy}; -static ebpf_extension_data_t _ebpf_xdp_test_program_info_provider_data = { - TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_xdp_test_program_data), &_ebpf_xdp_test_program_data}; - // Bind. -static ebpf_program_data_t _ebpf_bind_program_data = {&_ebpf_bind_program_info, NULL}; - -static ebpf_extension_data_t _ebpf_bind_program_info_provider_data = { - TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_bind_program_data), &_ebpf_bind_program_data}; +static ebpf_program_data_t _ebpf_bind_program_data = { + {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, &_ebpf_bind_program_info, NULL}; // CGROUP_SOCK_ADDR. -static ebpf_program_data_t _ebpf_sock_addr_program_data = {&_ebpf_sock_addr_program_info, NULL}; - -static ebpf_extension_data_t _ebpf_sock_addr_program_info_provider_data = { - TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_sock_addr_program_data), &_ebpf_sock_addr_program_data}; +static ebpf_program_data_t _ebpf_sock_addr_program_data = { + {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, &_ebpf_sock_addr_program_info, NULL}; // SOCK_OPS. -static ebpf_program_data_t _ebpf_sock_ops_program_data = {&_ebpf_sock_ops_program_info, NULL}; - -static ebpf_extension_data_t _ebpf_sock_ops_program_info_provider_data = { - TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_sock_ops_program_data), &_ebpf_sock_ops_program_data}; +static ebpf_program_data_t _ebpf_sock_ops_program_data = { + {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, &_ebpf_sock_ops_program_info, NULL}; // Sample extension. static const void* _sample_ebpf_ext_helper_functions[] = { @@ -674,14 +675,19 @@ static const void* _sample_ebpf_ext_helper_functions[] = { test_sample_helper_t::_sample_ebpf_extension_replace}; static ebpf_helper_function_addresses_t _sample_ebpf_ext_helper_function_address_table = { - EBPF_COUNT_OF(_sample_ebpf_ext_helper_functions), (uint64_t*)_sample_ebpf_ext_helper_functions}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(_sample_ebpf_ext_helper_functions), + (uint64_t*)_sample_ebpf_ext_helper_functions}; static const void* _test_global_helper_functions[] = {test_global_helper_t::_sample_get_pid_tgid}; static ebpf_helper_function_addresses_t _test_global_helper_function_address_table = { - EBPF_COUNT_OF(_test_global_helper_functions), (uint64_t*)_test_global_helper_functions}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(_test_global_helper_functions), + (uint64_t*)_test_global_helper_functions}; static ebpf_program_data_t _test_ebpf_sample_extension_program_data = { + {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, &_sample_ebpf_extension_program_info, &_sample_ebpf_ext_helper_function_address_table, &_test_global_helper_function_address_table, @@ -690,46 +696,40 @@ static ebpf_program_data_t _test_ebpf_sample_extension_program_data = { #define TEST_EBPF_SAMPLE_EXTENSION_NPI_PROVIDER_VERSION 0 -static ebpf_extension_data_t _test_ebpf_sample_extension_program_info_provider_data = { - TEST_EBPF_SAMPLE_EXTENSION_NPI_PROVIDER_VERSION, - sizeof(_test_ebpf_sample_extension_program_data), - &_test_ebpf_sample_extension_program_data}; - typedef class _program_info_provider { public: - _program_info_provider() : provider_data(nullptr), nmr_provider_handle(INVALID_HANDLE_VALUE) + _program_info_provider() : program_data(nullptr), nmr_provider_handle(INVALID_HANDLE_VALUE) { memset(&_program_type, 0, sizeof(_program_type)); } ebpf_result_t - initialize(ebpf_program_type_t program_type, ebpf_extension_data_t* custom_provider_data = nullptr) + initialize(ebpf_program_type_t program_type, ebpf_program_data_t* custom_program_data = nullptr) { this->_program_type = program_type; - if (custom_provider_data != nullptr) { - provider_data = custom_provider_data; + if (custom_program_data != nullptr) { + program_data = custom_program_data; } else if (program_type == EBPF_PROGRAM_TYPE_XDP) { - provider_data = &_mock_xdp_program_info_provider_data; + program_data = &_mock_xdp_program_data; } else if (program_type == EBPF_PROGRAM_TYPE_XDP_TEST) { - provider_data = &_ebpf_xdp_test_program_info_provider_data; + program_data = &_ebpf_xdp_test_program_data; } else if (program_type == EBPF_PROGRAM_TYPE_BIND) { - provider_data = &_ebpf_bind_program_info_provider_data; + program_data = &_ebpf_bind_program_data; } else if (program_type == EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR) { - provider_data = &_ebpf_sock_addr_program_info_provider_data; + program_data = &_ebpf_sock_addr_program_data; } else if (program_type == EBPF_PROGRAM_TYPE_SOCK_OPS) { - provider_data = &_ebpf_sock_ops_program_info_provider_data; + program_data = &_ebpf_sock_ops_program_data; } else if (program_type == EBPF_PROGRAM_TYPE_SAMPLE) { - provider_data = &_test_ebpf_sample_extension_program_info_provider_data; + program_data = &_test_ebpf_sample_extension_program_data; } else { // Unsupported program type. return EBPF_INVALID_ARGUMENT; } - ebpf_program_data_t* program_data = (ebpf_program_data_t*)provider_data->data; - module_id.Guid = program_data->program_info->program_type_descriptor.program_type; - provider_characteristics.ProviderRegistrationInstance.NpiSpecificCharacteristics = provider_data; + module_id.Guid = program_data->program_info->program_type_descriptor->program_type; + provider_characteristics.ProviderRegistrationInstance.NpiSpecificCharacteristics = program_data; NTSTATUS status = NmrRegisterProvider(&provider_characteristics, this, &nmr_provider_handle); return (NT_SUCCESS(status)) ? EBPF_SUCCESS : EBPF_FAILED; @@ -780,8 +780,8 @@ typedef class _program_info_provider }; ebpf_program_type_t _program_type; + const ebpf_program_data_t* program_data; - const ebpf_extension_data_t* provider_data; NPI_MODULEID module_id = { sizeof(NPI_MODULEID), MIT_GUID, @@ -794,7 +794,7 @@ typedef class _program_info_provider (NPI_PROVIDER_DETACH_CLIENT_FN*)provider_detach_client_callback, NULL, { - EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION, + 0, sizeof(NPI_REGISTRATION_INSTANCE), &EBPF_PROGRAM_INFO_EXTENSION_IID, &module_id, diff --git a/tests/libfuzzer/netebpfext_fuzzer/libfuzz_harness.cpp b/tests/libfuzzer/netebpfext_fuzzer/libfuzz_harness.cpp index 1b6ba9a40a..b41dc546b5 100644 --- a/tests/libfuzzer/netebpfext_fuzzer/libfuzz_harness.cpp +++ b/tests/libfuzzer/netebpfext_fuzzer/libfuzz_harness.cpp @@ -80,20 +80,21 @@ FUZZ_EXPORT int __cdecl LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) bpf_prog_type_t prog_type = (bpf_prog_type_t)metadata->prog_type; NET_IFINDEX if_index = 0; - ebpf_extension_data_t npi_specific_characteristics = {.size = sizeof(if_index), .data = &if_index}; + ebpf_extension_data_t npi_specific_characteristics = {.data = &if_index}; test_client_context_t client_context = {}; netebpf_ext_helper_t helper( &npi_specific_characteristics, (_ebpf_extension_dispatch_function)netebpfext_unit_invoke_program, &client_context.base); + npi_specific_characteristics.header.size = sizeof(if_index); + // Look up the context descriptor for the requested program type. std::vector guids = helper.program_info_provider_guids(); for (const auto& guid : guids) { - ebpf_extension_data_t extension_data = helper.get_program_info_provider_data(guid); - auto& program_data = *reinterpret_cast(extension_data.data); - if (prog_type == (bpf_prog_type_t)program_data.program_info->program_type_descriptor.bpf_prog_type) { - client_context.ctx_descriptor = program_data.program_info->program_type_descriptor.context_descriptor; + auto& program_data = *helper.get_program_info_provider_data(guid); + if (prog_type == (bpf_prog_type_t)program_data.program_info->program_type_descriptor->bpf_prog_type) { + client_context.ctx_descriptor = program_data.program_info->program_type_descriptor->context_descriptor; break; } } diff --git a/tests/netebpfext_unit/netebpf_ext_helper.cpp b/tests/netebpfext_unit/netebpf_ext_helper.cpp index f63954f682..2fdc7b431c 100644 --- a/tests/netebpfext_unit/netebpf_ext_helper.cpp +++ b/tests/netebpfext_unit/netebpf_ext_helper.cpp @@ -134,7 +134,7 @@ _netebpf_ext_helper::program_info_provider_guids() return guids; } -ebpf_extension_data_t +ebpf_program_data_t* _netebpf_ext_helper::get_program_info_provider_data(_In_ const GUID& program_info_provider) { auto iter = program_info_providers.find(program_info_provider); @@ -142,7 +142,7 @@ _netebpf_ext_helper::get_program_info_provider_data(_In_ const GUID& program_inf // We might not find the provider if some allocation failed during initialization. REQUIRE(iter != program_info_providers.end()); - return *iter->second->provider_data; + return const_cast(iter->second->program_data); } NTSTATUS @@ -155,8 +155,8 @@ _netebpf_ext_helper::_program_info_client_attach_provider( auto client_binding_context = std::make_unique(); client_binding_context->module_id = *provider_registration_instance->ModuleId; client_binding_context->parent = &helper; - client_binding_context->provider_data = - reinterpret_cast(provider_registration_instance->NpiSpecificCharacteristics); + client_binding_context->program_data = + reinterpret_cast(provider_registration_instance->NpiSpecificCharacteristics); NTSTATUS status = NmrClientAttachProvider( nmr_binding_handle, @@ -199,9 +199,7 @@ _netebpf_ext_helper::_hook_client_attach_provider( } const ebpf_extension_dispatch_table_t client_dispatch_table = { .version = 1, .count = 1, .function = base_client_context->helper->hook_invoke_function}; - auto provider_characteristics = - (const ebpf_extension_data_t*)provider_registration_instance->NpiSpecificCharacteristics; - auto provider_data = (const ebpf_attach_provider_data_t*)provider_characteristics->data; + auto provider_data = (const ebpf_attach_provider_data_t*)provider_registration_instance->NpiSpecificCharacteristics; if (base_client_context->desired_attach_type != BPF_ATTACH_TYPE_UNSPEC && provider_data->bpf_attach_type != base_client_context->desired_attach_type) { return STATUS_ACCESS_DENIED; diff --git a/tests/netebpfext_unit/netebpf_ext_helper.h b/tests/netebpfext_unit/netebpf_ext_helper.h index f2f843f88a..c642350102 100644 --- a/tests/netebpfext_unit/netebpf_ext_helper.h +++ b/tests/netebpfext_unit/netebpf_ext_helper.h @@ -44,7 +44,7 @@ typedef class _netebpf_ext_helper std::vector program_info_provider_guids(); - ebpf_extension_data_t + ebpf_program_data_t* get_program_info_provider_data(_In_ const GUID& program_info_provider); FWP_ACTION_TYPE @@ -111,7 +111,7 @@ typedef class _netebpf_ext_helper NPI_MODULEID module_id; void* context; const void* dispatch; - const ebpf_extension_data_t* provider_data; + const ebpf_program_data_t* program_data; } program_info_provider_t; std::map, NPI_MODULEID_LESS> program_info_providers; diff --git a/tests/netebpfext_unit/netebpfext_unit.cpp b/tests/netebpfext_unit/netebpfext_unit.cpp index e748d112fe..ffc25a1b4c 100644 --- a/tests/netebpfext_unit/netebpfext_unit.cpp +++ b/tests/netebpfext_unit/netebpfext_unit.cpp @@ -64,9 +64,8 @@ TEST_CASE("query program info", "[netebpfext]") // Get the names of the program types. std::vector program_names; for (const auto& guid : guids) { - ebpf_extension_data_t extension_data = helper.get_program_info_provider_data(guid); - auto& program_data = *reinterpret_cast(extension_data.data); - program_names.push_back(program_data.program_info->program_type_descriptor.name); + auto& program_data = *helper.get_program_info_provider_data(guid); + program_names.push_back(program_data.program_info->program_type_descriptor->name); } // Make sure they match. @@ -118,10 +117,12 @@ netebpfext_unit_invoke_xdp_program( TEST_CASE("classify_packet", "[netebpfext]") { NET_IFINDEX if_index = 0; - ebpf_extension_data_t npi_specific_characteristics = {.size = sizeof(if_index), .data = &if_index}; + ebpf_extension_data_t npi_specific_characteristics = {.data = &if_index}; test_xdp_client_context_t client_context = {}; client_context.base.desired_attach_type = BPF_XDP_TEST; + npi_specific_characteristics.header.size = sizeof(if_index); + netebpf_ext_helper_t helper( &npi_specific_characteristics, (_ebpf_extension_dispatch_function)netebpfext_unit_invoke_xdp_program, @@ -151,8 +152,7 @@ TEST_CASE("classify_packet", "[netebpfext]") TEST_CASE("xdp_context", "[netebpfext]") { netebpf_ext_helper_t helper; - auto xdp_extension_data = helper.get_program_info_provider_data(EBPF_PROGRAM_TYPE_XDP_TEST); - auto xdp_program_data = (ebpf_program_data_t*)xdp_extension_data.data; + auto xdp_program_data = helper.get_program_info_provider_data(EBPF_PROGRAM_TYPE_XDP_TEST); std::vector input_data(100); std::vector output_data(100); @@ -258,8 +258,7 @@ TEST_CASE("bind_invoke", "[netebpfext]") TEST_CASE("bind_context", "[netebpfext]") { netebpf_ext_helper_t helper; - auto bind_extension_data = helper.get_program_info_provider_data(EBPF_PROGRAM_TYPE_BIND); - auto bind_program_data = (ebpf_program_data_t*)bind_extension_data.data; + auto bind_program_data = helper.get_program_info_provider_data(EBPF_PROGRAM_TYPE_BIND); std::vector input_data(100); std::vector output_data(100); @@ -367,9 +366,8 @@ netebpfext_unit_invoke_sock_addr_program( int action = SOCK_ADDR_TEST_ACTION_BLOCK; int32_t is_admin = 0; - ebpf_extension_data_t sock_addr_extension_data = + auto sock_addr_program_data = client_context->base.helper->get_program_info_provider_data(EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR); - auto sock_addr_program_data = (ebpf_program_data_t*)sock_addr_extension_data.data; // Test _ebpf_sock_addr_is_current_admin global helper function. // If the user is not admin, then the default action is to block. @@ -695,8 +693,7 @@ TEST_CASE("sock_addr_invoke_concurrent3", "[netebpfext_concurrent]") TEST_CASE("sock_addr_context", "[netebpfext]") { netebpf_ext_helper_t helper; - auto sock_addr_extension_data = helper.get_program_info_provider_data(EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR); - auto sock_addr_program_data = (ebpf_program_data_t*)sock_addr_extension_data.data; + auto sock_addr_program_data = helper.get_program_info_provider_data(EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR); size_t output_data_size = 0; bpf_sock_addr_t input_context = { @@ -815,8 +812,7 @@ TEST_CASE("sock_ops_invoke", "[netebpfext]") TEST_CASE("sock_ops_context", "[netebpfext]") { netebpf_ext_helper_t helper; - auto sock_ops_extension_data = helper.get_program_info_provider_data(EBPF_PROGRAM_TYPE_SOCK_OPS); - auto sock_ops_program_data = (ebpf_program_data_t*)sock_ops_extension_data.data; + auto sock_ops_program_data = helper.get_program_info_provider_data(EBPF_PROGRAM_TYPE_SOCK_OPS); size_t output_data_size = 0; bpf_sock_ops_t input_context = { diff --git a/tools/bpf2c/bpf2c.cpp b/tools/bpf2c/bpf2c.cpp index 1afc40b7f2..ef1c1e7034 100644 --- a/tools/bpf2c/bpf2c.cpp +++ b/tools/bpf2c/bpf2c.cpp @@ -87,11 +87,11 @@ get_program_info_type_hash(const std::vector& actual_helper_ids, const // being hashed in _ebpf_program_verify_program_info_hash. If new fields are added to the program info, then the // hash must be updated to include the new fields, both here and in _ebpf_program_verify_program_info_hash. hash_t::byte_range_t byte_range; - hash_t::append_byte_range(byte_range, program_info->program_type_descriptor.name); - hash_t::append_byte_range(byte_range, *program_info->program_type_descriptor.context_descriptor); - hash_t::append_byte_range(byte_range, program_info->program_type_descriptor.program_type); - hash_t::append_byte_range(byte_range, program_info->program_type_descriptor.bpf_prog_type); - hash_t::append_byte_range(byte_range, program_info->program_type_descriptor.is_privileged); + hash_t::append_byte_range(byte_range, program_info->program_type_descriptor->name); + hash_t::append_byte_range(byte_range, *program_info->program_type_descriptor->context_descriptor); + hash_t::append_byte_range(byte_range, program_info->program_type_descriptor->program_type); + hash_t::append_byte_range(byte_range, program_info->program_type_descriptor->bpf_prog_type); + hash_t::append_byte_range(byte_range, program_info->program_type_descriptor->is_privileged); hash_t::append_byte_range(byte_range, actual_helper_id_count); // First, create a map of helper_id to index in the program_type_specific_helper_prototype array. diff --git a/tools/export_program_info/export_program_info.cpp b/tools/export_program_info/export_program_info.cpp index 4ecb7248d7..f0a1e3ba85 100644 --- a/tools/export_program_info/export_program_info.cpp +++ b/tools/export_program_info/export_program_info.cpp @@ -16,8 +16,15 @@ #include "ebpf_general_helpers.c" // Export XDP program information to allow for our unit tests to mock the XDP API surface. +static const ebpf_program_type_descriptor_t _mock_xdp_program_type_descriptor = { + {EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, sizeof(ebpf_program_type_descriptor_t)}, + "xdp", + &_ebpf_xdp_test_context_descriptor, + EBPF_PROGRAM_TYPE_XDP_GUID, + BPF_PROG_TYPE_XDP}; static const ebpf_program_info_t _mock_xdp_program_info = { - {"xdp", &_ebpf_xdp_test_context_descriptor, EBPF_PROGRAM_TYPE_XDP_GUID, BPF_PROG_TYPE_XDP}, + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &_mock_xdp_program_type_descriptor, EBPF_COUNT_OF(_xdp_test_ebpf_extension_helper_function_prototype), _xdp_test_ebpf_extension_helper_function_prototype}; @@ -35,7 +42,12 @@ static const ebpf_program_info_t* _program_information_array[] = { &_ebpf_xdp_test_program_info}; ebpf_program_section_info_t _mock_xdp_section_info[] = { - {L"xdp", &EBPF_PROGRAM_TYPE_XDP, &EBPF_ATTACH_TYPE_XDP, BPF_PROG_TYPE_XDP, BPF_XDP}}; + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"xdp", + &EBPF_PROGRAM_TYPE_XDP, + &EBPF_ATTACH_TYPE_XDP, + BPF_PROG_TYPE_XDP, + BPF_XDP}}; static std::vector _section_information = { {&_ebpf_bind_section_info[0], _countof(_ebpf_bind_section_info)}, diff --git a/undocked/tests/sample/ext/drv/sample_ext.c b/undocked/tests/sample/ext/drv/sample_ext.c index 711a24f54b..d325e91cfd 100644 --- a/undocked/tests/sample/ext/drv/sample_ext.c +++ b/undocked/tests/sample/ext/drv/sample_ext.c @@ -46,12 +46,16 @@ static const void* _sample_ebpf_extension_helpers[] = { (void*)&_sample_ebpf_extension_replace}; static const ebpf_helper_function_addresses_t _sample_ebpf_extension_helper_function_address_table = { - EBPF_COUNT_OF(_sample_ebpf_extension_helpers), (uint64_t*)_sample_ebpf_extension_helpers}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(_sample_ebpf_extension_helpers), + (uint64_t*)_sample_ebpf_extension_helpers}; static const void* _sample_global_helpers[] = {(void*)&_sample_get_pid_tgid}; static const ebpf_helper_function_addresses_t _sample_global_helper_function_address_table = { - EBPF_COUNT_OF(_sample_global_helpers), (uint64_t*)_sample_global_helpers}; + {EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0, sizeof(ebpf_helper_function_addresses_t)}, + EBPF_COUNT_OF(_sample_global_helpers), + (uint64_t*)_sample_global_helpers}; static ebpf_result_t _sample_context_create( @@ -70,17 +74,13 @@ _sample_context_destroy( _Inout_ size_t* context_size_out); static ebpf_program_data_t _sample_ebpf_extension_program_data = { + {EBPF_PROGRAM_DATA_VERSION_0, sizeof(ebpf_program_data_t)}, .program_info = &_sample_ebpf_extension_program_info, .program_type_specific_helper_function_addresses = &_sample_ebpf_extension_helper_function_address_table, .global_helper_function_addresses = &_sample_global_helper_function_address_table, .context_create = &_sample_context_create, .context_destroy = &_sample_context_destroy}; -static const ebpf_extension_data_t _sample_ebpf_extension_program_info_provider_data = { - SAMPLE_EBPF_EXTENSION_NPI_PROVIDER_VERSION, - sizeof(_sample_ebpf_extension_program_data), - &_sample_ebpf_extension_program_data}; - NPI_MODULEID DECLSPEC_SELECTANY _sample_ebpf_extension_program_info_provider_moduleid = { sizeof(NPI_MODULEID), MIT_GUID, {0}}; @@ -140,7 +140,7 @@ const NPI_PROVIDER_CHARACTERISTICS _sample_ebpf_extension_program_info_provider_ &EBPF_PROGRAM_INFO_EXTENSION_IID, &_sample_ebpf_extension_program_info_provider_moduleid, 0, - &_sample_ebpf_extension_program_info_provider_data}, + &_sample_ebpf_extension_program_data}, }; /** @@ -164,7 +164,8 @@ static sample_ebpf_extension_program_info_provider_t _sample_ebpf_extension_prog // Hook Provider. // -NPI_MODULEID DECLSPEC_SELECTANY _sample_ebpf_extension_hook_provider_moduleid = {sizeof(NPI_MODULEID), MIT_GUID, {0}}; +NPI_MODULEID DECLSPEC_SELECTANY _sample_ebpf_extension_hook_provider_moduleid = { + sizeof(NPI_MODULEID), MIT_GUID, EBPF_ATTACH_TYPE_SAMPLE_GUID}; /** * @brief Callback invoked when a eBPF hook NPI client attaches. @@ -210,12 +211,11 @@ static void _sample_ebpf_extension_hook_provider_cleanup_binding_context(_Frees_ptr_ void* provider_binding_context); // Sample eBPF extension Hook NPI provider characteristics -ebpf_attach_provider_data_t _sample_ebpf_extension_attach_provider_data; - -ebpf_extension_data_t _sample_ebpf_extension_hook_provider_data = { - EBPF_ATTACH_PROVIDER_DATA_VERSION, - sizeof(_sample_ebpf_extension_attach_provider_data), - &_sample_ebpf_extension_attach_provider_data}; +ebpf_attach_provider_data_t _sample_ebpf_extension_attach_provider_data = { + {EBPF_ATTACH_PROVIDER_DATA_VERSION_0, sizeof(ebpf_attach_provider_data_t)}, + EBPF_PROGRAM_TYPE_SAMPLE_GUID, + BPF_ATTACH_TYPE_SAMPLE, + BPF_LINK_TYPE_UNSPEC}; const NPI_PROVIDER_CHARACTERISTICS _sample_ebpf_extension_hook_provider_characteristics = { 0, @@ -228,7 +228,7 @@ const NPI_PROVIDER_CHARACTERISTICS _sample_ebpf_extension_hook_provider_characte &EBPF_HOOK_EXTENSION_IID, &_sample_ebpf_extension_hook_provider_moduleid, 0, - &_sample_ebpf_extension_hook_provider_data}, + &_sample_ebpf_extension_attach_provider_data}, }; typedef struct _sample_ebpf_extension_hook_provider sample_ebpf_extension_hook_provider_t; @@ -338,16 +338,8 @@ NTSTATUS sample_ebpf_extension_program_info_provider_register() { sample_ebpf_extension_program_info_provider_t* local_provider_context; - ebpf_extension_data_t* extension_data; - ebpf_program_data_t* program_data; - NTSTATUS status = STATUS_SUCCESS; - extension_data = (ebpf_extension_data_t*)_sample_ebpf_extension_program_info_provider_characteristics - .ProviderRegistrationInstance.NpiSpecificCharacteristics; - program_data = (ebpf_program_data_t*)extension_data->data; - _sample_ebpf_extension_program_info_provider_moduleid.Guid = EBPF_PROGRAM_TYPE_SAMPLE; - local_provider_context = &_sample_ebpf_extension_program_info_provider_context; status = NmrRegisterProvider( @@ -487,10 +479,6 @@ sample_ebpf_extension_hook_provider_register() sample_ebpf_extension_hook_provider_t* local_provider_context; NTSTATUS status = STATUS_SUCCESS; - _sample_ebpf_extension_attach_provider_data.supported_program_type = EBPF_PROGRAM_TYPE_SAMPLE; - _sample_ebpf_extension_attach_provider_data.bpf_attach_type = BPF_ATTACH_TYPE_SAMPLE; - _sample_ebpf_extension_hook_provider_moduleid.Guid = EBPF_ATTACH_TYPE_SAMPLE; - local_provider_context = &_sample_ebpf_extension_hook_provider_context; status = NmrRegisterProvider( diff --git a/undocked/tests/sample/ext/inc/sample_ext_program_info.h b/undocked/tests/sample/ext/inc/sample_ext_program_info.h index 556af60d9d..e9a85f02b8 100644 --- a/undocked/tests/sample/ext/inc/sample_ext_program_info.h +++ b/undocked/tests/sample/ext/inc/sample_ext_program_info.h @@ -24,18 +24,21 @@ static const ebpf_context_descriptor_t _sample_ebpf_context_descriptor = { // Sample Extension Helper function prototype descriptors. static const ebpf_helper_function_prototype_t _sample_ebpf_extension_helper_function_prototype[] = { - {SAMPLE_EXT_HELPER_FUNCTION_START + 1, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + SAMPLE_EXT_HELPER_FUNCTION_START + 1, "sample_ebpf_extension_helper_function1", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_CTX}}, - {SAMPLE_EXT_HELPER_FUNCTION_START + 2, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + SAMPLE_EXT_HELPER_FUNCTION_START + 2, "sample_ebpf_extension_find", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, EBPF_ARGUMENT_TYPE_CONST_SIZE, EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, EBPF_ARGUMENT_TYPE_CONST_SIZE}}, - {SAMPLE_EXT_HELPER_FUNCTION_START + 3, + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + SAMPLE_EXT_HELPER_FUNCTION_START + 3, "sample_ebpf_extension_replace", EBPF_RETURN_TYPE_INTEGER, {EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM, @@ -46,10 +49,21 @@ static const ebpf_helper_function_prototype_t _sample_ebpf_extension_helper_func // Global helper function prototype descriptors. static const ebpf_helper_function_prototype_t _sample_ebpf_extension_global_helper_function_prototype[] = { - {BPF_FUNC_get_current_pid_tgid, "bpf_get_current_pid_tgid", EBPF_RETURN_TYPE_INTEGER, {0}}}; + {{EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0, sizeof(ebpf_helper_function_prototype_t)}, + BPF_FUNC_get_current_pid_tgid, + "bpf_get_current_pid_tgid", + EBPF_RETURN_TYPE_INTEGER, + {0}}}; +static const ebpf_program_type_descriptor_t _sample_ebpf_extension_program_type_descriptor = { + {EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0, sizeof(ebpf_program_type_descriptor_t)}, + "sample", + &_sample_ebpf_context_descriptor, + EBPF_PROGRAM_TYPE_SAMPLE_GUID, + BPF_PROG_TYPE_SAMPLE}; static const ebpf_program_info_t _sample_ebpf_extension_program_info = { - {"sample", &_sample_ebpf_context_descriptor, EBPF_PROGRAM_TYPE_SAMPLE_GUID, BPF_PROG_TYPE_SAMPLE}, + {EBPF_PROGRAM_INFORMATION_VERSION_0, sizeof(ebpf_program_info_t)}, + &_sample_ebpf_extension_program_type_descriptor, EBPF_COUNT_OF(_sample_ebpf_extension_helper_function_prototype), _sample_ebpf_extension_helper_function_prototype, EBPF_COUNT_OF(_sample_ebpf_extension_global_helper_function_prototype), diff --git a/undocked/tools/export_program_info_sample/export_program_info_sample.cpp b/undocked/tools/export_program_info_sample/export_program_info_sample.cpp index bccd414b9d..7f94475c72 100644 --- a/undocked/tools/export_program_info_sample/export_program_info_sample.cpp +++ b/undocked/tools/export_program_info_sample/export_program_info_sample.cpp @@ -25,7 +25,12 @@ typedef struct _ebpf_program_section_info_with_count static const ebpf_program_info_t* _program_information_array[] = {&_sample_ebpf_extension_program_info}; ebpf_program_section_info_t _sample_ext_section_info[] = { - {L"sample_ext", &EBPF_PROGRAM_TYPE_SAMPLE, &EBPF_ATTACH_TYPE_SAMPLE, BPF_PROG_TYPE_SAMPLE, BPF_ATTACH_TYPE_SAMPLE}}; + {{EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0, sizeof(ebpf_program_section_info_t)}, + L"sample_ext", + &EBPF_PROGRAM_TYPE_SAMPLE, + &EBPF_ATTACH_TYPE_SAMPLE, + BPF_PROG_TYPE_SAMPLE, + BPF_ATTACH_TYPE_SAMPLE}}; static std::vector _section_information = { {&_sample_ext_section_info[0], _countof(_sample_ext_section_info)},