Wrap registry APIs behind store APIs. (#2114)

* Wrap registry APIs

* pr feedback

* PR feedback: revert splitting implementation from .

* nit

* nit

* nit

* rev

* fix unicode size calc

* remove redundant success check

* revert string length calculation, var rename

* var rename for clarity

* revise store api location, reorg externals

* add error trace, fix cmake

* convert error codes
This commit is contained in:
Gianni Trevisiol 2023-03-06 15:10:51 -08:00 коммит произвёл GitHub
Родитель b6b559f49f
Коммит 1f6d85c999
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
17 изменённых файлов: 125 добавлений и 91 удалений

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

@ -12,7 +12,7 @@ extern ebpf_registry_key_t ebpf_root_registry_key;
#endif
static uint32_t
_open_or_create_provider_registry_key(_Out_ ebpf_registry_key_t* provider_key)
_ebpf_store_open_or_create_provider_registry_key(_Out_ ebpf_registry_key_t* provider_key)
{
__return_type status = _SUCCESS;
ebpf_registry_key_t root_key = NULL;
@ -42,7 +42,8 @@ Exit:
}
static __return_type
_update_helper_prototype(ebpf_registry_key_t helper_info_key, _In_ const ebpf_helper_function_prototype_t* helper_info)
_ebpf_store_update_helper_prototype(
ebpf_registry_key_t helper_info_key, _In_ const ebpf_helper_function_prototype_t* helper_info)
{
__return_type status = _SUCCESS;
uint32_t offset;
@ -89,7 +90,7 @@ Exit:
* @returns Status of the operation.
*/
static __return_type
ebpf_store_update_section_information(
_ebpf_store_update_section_information(
_In_reads_(section_info_count) ebpf_program_section_info_t* section_info, uint32_t section_info_count)
{
__return_type status = _SUCCESS;
@ -101,7 +102,7 @@ ebpf_store_update_section_information(
}
// Open (or create) provider registry path.
status = _open_or_create_provider_registry_key(&provider_key);
status = _ebpf_store_open_or_create_provider_registry_key(&provider_key);
if (!IS_SUCCESS(status)) {
goto Exit;
}
@ -180,7 +181,7 @@ Exit:
* @returns Status of the operation.
*/
static __return_type
ebpf_store_update_program_information(
_ebpf_store_update_program_information(
_In_reads_(program_info_count) ebpf_program_info_t* program_info, uint32_t program_info_count)
{
__return_type status = _SUCCESS;
@ -192,7 +193,7 @@ ebpf_store_update_program_information(
}
// Open (or create) provider registry path.
status = _open_or_create_provider_registry_key(&provider_key);
status = _ebpf_store_open_or_create_provider_registry_key(&provider_key);
if (!IS_SUCCESS(status)) {
goto Exit;
}
@ -274,7 +275,7 @@ ebpf_store_update_program_information(
// Iterate over all the helper prototypes and save in registry.
for (uint32_t count = 0; count < program_info[i].count_of_program_type_specific_helpers; count++) {
status = _update_helper_prototype(
status = _ebpf_store_update_helper_prototype(
helper_info_key, &(program_info[i].program_type_specific_helper_prototype[count]));
if (!IS_SUCCESS(status)) {
close_registry_key(program_key);
@ -308,7 +309,7 @@ Exit:
* @returns Status of the operation.
*/
static __return_type
ebpf_store_update_global_helper_information(
_ebpf_store_update_global_helper_information(
_In_reads_(helper_info_count) ebpf_helper_function_prototype_t* helper_info, uint32_t helper_info_count)
{
__return_type status = _SUCCESS;
@ -320,7 +321,7 @@ ebpf_store_update_global_helper_information(
}
// Open (or create) provider registry path.
status = _open_or_create_provider_registry_key(&provider_key);
status = _ebpf_store_open_or_create_provider_registry_key(&provider_key);
if (!IS_SUCCESS(status)) {
goto Exit;
}
@ -333,7 +334,7 @@ ebpf_store_update_global_helper_information(
for (uint32_t i = 0; i < helper_info_count; i++) {
status = _update_helper_prototype(helper_info_key, &helper_info[i]);
status = _ebpf_store_update_helper_prototype(helper_info_key, &helper_info[i]);
if (!IS_SUCCESS(status)) {
goto Exit;
}
@ -348,4 +349,4 @@ Exit:
}
return status;
}
}

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

@ -22,27 +22,32 @@ close_registry_key(ebpf_registry_key_t key)
ZwClose(key);
}
_Success_(return == 0) static NTSTATUS
convert_guid_to_string(_In_ const GUID* guid, _Out_writes_all_(string_size) wchar_t* string, size_t string_size)
static NTSTATUS
convert_guid_to_string(_In_ const GUID* guid, _Out_writes_all_(string_length) wchar_t* string, size_t string_length)
{
UNICODE_STRING unicode_string;
UNICODE_STRING unicode_string = {0};
NTSTATUS status = RtlStringFromGUID(guid, &unicode_string);
if (status != STATUS_SUCCESS) {
goto Exit;
}
if (string_size < GUID_STRING_LENGTH + 1) {
if (string_length < GUID_STRING_LENGTH + 1) {
status = STATUS_BUFFER_TOO_SMALL;
goto Exit;
}
__analysis_assume(unicode_string.MaximumLength >= GUID_STRING_LENGTH * 2);
__analysis_assume(unicode_string.MaximumLength >= GUID_STRING_LENGTH * sizeof(wchar_t));
__analysis_assume(unicode_string.Buffer != NULL);
// Copy the buffer to the output string.
memcpy(string, unicode_string.Buffer, GUID_STRING_LENGTH * 2);
memcpy(string, unicode_string.Buffer, GUID_STRING_LENGTH * sizeof(wchar_t));
string[GUID_STRING_LENGTH] = L'\0';
Exit:
if (unicode_string.Buffer != NULL) {
RtlFreeUnicodeString(&unicode_string);
}
return status;
}

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

@ -7,8 +7,10 @@
#include "store_helper_internal.h"
#include "utilities.hpp"
extern ebpf_registry_key_t root_registry_key_current_user;
extern ebpf_registry_key_t root_registry_key_local_machine;
ebpf_registry_key_t root_registry_key_current_user = HKEY_CURRENT_USER;
ebpf_registry_key_t root_registry_key_local_machine = HKEY_LOCAL_MACHINE;
// TODO: Issue #1231 Change to using HKEY_LOCAL_MACHINE
ebpf_registry_key_t ebpf_root_registry_key = HKEY_CURRENT_USER;
static uint32_t
_open_ebpf_store_key(_Out_ ebpf_registry_key_t* store_key)
@ -691,3 +693,61 @@ Exit:
ebpf_free(helper_name);
return result;
}
_Must_inspect_result_ ebpf_result_t
ebpf_store_clear(_In_ const ebpf_registry_key_t root_key_path)
{
ebpf_registry_key_t root_handle = {0};
ebpf_registry_key_t provider_handle = {0};
uint32_t status;
ebpf_result_t result = EBPF_FAILED;
// Open root registry key.
status = open_registry_key(root_key_path, EBPF_ROOT_RELATIVE_PATH, REG_CREATE_FLAGS, &root_handle);
if (status != ERROR_SUCCESS) {
if (status == ERROR_FILE_NOT_FOUND) {
result = EBPF_SUCCESS;
} else {
result = win32_error_code_to_ebpf_result(status);
}
goto Exit;
}
// Open "providers" registry key.
status = open_registry_key(root_handle, EBPF_PROVIDERS_REGISTRY_PATH, REG_CREATE_FLAGS, &provider_handle);
if (status != ERROR_SUCCESS) {
if (status == ERROR_FILE_NOT_FOUND) {
result = EBPF_SUCCESS;
} else {
result = win32_error_code_to_ebpf_result(status);
}
goto Exit;
}
// Delete subtree of provider reg key.
status = delete_registry_tree(provider_handle, NULL);
if (status != ERROR_SUCCESS) {
result = win32_error_code_to_ebpf_result(status);
goto Exit;
}
close_registry_key(provider_handle);
provider_handle = nullptr;
status = delete_registry_key(root_handle, EBPF_PROVIDERS_REGISTRY_PATH);
if (status != ERROR_SUCCESS) {
result = win32_error_code_to_ebpf_result(status);
goto Exit;
}
result = EBPF_SUCCESS;
Exit:
if (provider_handle) {
close_registry_key(provider_handle);
}
if (root_handle) {
close_registry_key(root_handle);
}
return result;
}

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

@ -18,4 +18,7 @@ ebpf_store_load_section_information(
_Must_inspect_result_ ebpf_result_t
ebpf_store_load_global_helper_information(
_Outptr_result_buffer_maybenull_(*global_helper_info_count) ebpf_helper_function_prototype_t** global_helper_info,
_Out_ uint32_t* global_helper_info_count);
_Out_ uint32_t* global_helper_info_count);
_Must_inspect_result_ ebpf_result_t
ebpf_store_clear(_In_ const ebpf_registry_key_t root_key_path);

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

@ -26,10 +26,6 @@
static thread_local ebpf_handle_t _program_under_verification = ebpf_handle_invalid;
// TODO: Issue #1231 Change to using HKEY_LOCAL_MACHINE
ebpf_registry_key_t root_registry_key_current_user = HKEY_CURRENT_USER;
ebpf_registry_key_t root_registry_key_local_machine = HKEY_LOCAL_MACHINE;
extern bool use_ebpf_store;
struct guid_compare

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

@ -746,7 +746,7 @@ _Must_inspect_result_ ebpf_result_t
ebpf_update_global_helpers(
_In_reads_(helper_info_count) ebpf_helper_function_prototype_t* helper_info, uint32_t helper_info_count)
{
NTSTATUS status = ebpf_store_update_global_helper_information(helper_info, helper_info_count);
NTSTATUS status = _ebpf_store_update_global_helper_information(helper_info, helper_info_count);
ebpf_result_t result = NT_SUCCESS(status) ? EBPF_SUCCESS : EBPF_FAILED;
return result;

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

@ -152,14 +152,14 @@ _net_ebpf_bind_update_store_entries()
// Update section information.
uint32_t section_info_count = sizeof(_ebpf_bind_section_info) / sizeof(ebpf_program_section_info_t);
status = ebpf_store_update_section_information(&_ebpf_bind_section_info[0], section_info_count);
status = _ebpf_store_update_section_information(&_ebpf_bind_section_info[0], section_info_count);
if (!NT_SUCCESS(status)) {
return status;
}
// Program information
_ebpf_bind_program_info.program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_BIND;
status = ebpf_store_update_program_information(&_ebpf_bind_program_info, 1);
status = _ebpf_store_update_program_information(&_ebpf_bind_program_info, 1);
return status;
}

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

@ -420,14 +420,14 @@ _net_ebpf_sock_addr_update_store_entries()
// Update section information.
uint32_t section_info_count = sizeof(_ebpf_sock_addr_section_info) / sizeof(ebpf_program_section_info_t);
status = ebpf_store_update_section_information(&_ebpf_sock_addr_section_info[0], section_info_count);
status = _ebpf_store_update_section_information(&_ebpf_sock_addr_section_info[0], section_info_count);
if (!NT_SUCCESS(status)) {
NET_EBPF_EXT_RETURN_NTSTATUS(status);
}
// Update program information.
_ebpf_sock_addr_program_info.program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR;
status = ebpf_store_update_program_information(&_ebpf_sock_addr_program_info, 1);
status = _ebpf_store_update_program_information(&_ebpf_sock_addr_program_info, 1);
NET_EBPF_EXT_RETURN_NTSTATUS(status);
}

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

@ -268,14 +268,14 @@ _net_ebpf_sock_ops_update_store_entries()
// Update section information.
uint32_t section_info_count = sizeof(_ebpf_sock_ops_section_info) / sizeof(ebpf_program_section_info_t);
status = ebpf_store_update_section_information(&_ebpf_sock_ops_section_info[0], section_info_count);
status = _ebpf_store_update_section_information(&_ebpf_sock_ops_section_info[0], section_info_count);
if (!NT_SUCCESS(status)) {
return status;
}
// Update program information.
_ebpf_sock_ops_program_info.program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_SOCK_OPS;
status = ebpf_store_update_program_information(&_ebpf_sock_ops_program_info, 1);
status = _ebpf_store_update_program_information(&_ebpf_sock_ops_program_info, 1);
return status;
}

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

@ -224,14 +224,14 @@ _net_ebpf_xdp_update_store_entries()
// Update section information.
uint32_t section_info_count = sizeof(_ebpf_xdp_section_info) / sizeof(ebpf_program_section_info_t);
status = ebpf_store_update_section_information(&_ebpf_xdp_section_info[0], section_info_count);
status = _ebpf_store_update_section_information(&_ebpf_xdp_section_info[0], section_info_count);
if (!NT_SUCCESS(status)) {
return status;
}
// Update program information.
_ebpf_xdp_program_info.program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_XDP;
status = ebpf_store_update_program_information(&_ebpf_xdp_program_info, 1);
status = _ebpf_store_update_program_information(&_ebpf_xdp_program_info, 1);
return status;
}

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

@ -3,6 +3,7 @@
#include "netebpf_ext_helper.h"
// TODO: Issue #1231 Change to using HKEY_LOCAL_MACHINE
ebpf_registry_key_t ebpf_root_registry_key = HKEY_CURRENT_USER;
DEVICE_OBJECT* _net_ebpf_ext_driver_device_object;

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

@ -326,7 +326,7 @@ _sample_ebpf_extension_update_store_entries()
(GUID*)&EBPF_ATTACH_TYPE_SAMPLE,
BPF_PROG_TYPE_SAMPLE,
BPF_ATTACH_TYPE_SAMPLE};
status = ebpf_store_update_section_information(&section_info, 1);
status = _ebpf_store_update_section_information(&section_info, 1);
if (!NT_SUCCESS(status)) {
return status;
}
@ -339,7 +339,7 @@ _sample_ebpf_extension_update_store_entries()
program_data = (ebpf_program_data_t*)extension_data->data;
program_data->program_info->program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_SAMPLE;
status = ebpf_store_update_program_information(program_data->program_info, 1);
status = _ebpf_store_update_program_information(program_data->program_info, 1);
return status;
}

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

@ -5,6 +5,8 @@ add_executable("export_program_info"
export_program_info.cpp
main.cpp
${CMAKE_SOURCE_DIR}/libs/api_common/registry_helper.cpp
${CMAKE_SOURCE_DIR}/libs/api_common/store_helper_internal.cpp
${CMAKE_SOURCE_DIR}/libs/api_common/utilities.cpp
)
target_include_directories("export_program_info" PRIVATE

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

@ -8,6 +8,7 @@
#include "ebpf_nethooks.h"
#include "ebpf_store_helper.h"
#include "export_program_info.h"
#include "store_helper_internal.h"
#include "windows_program_type.h"
#include <codecvt>
@ -17,8 +18,7 @@
#define REG_CREATE_FLAGS (KEY_WRITE | DELETE | KEY_READ)
#define REG_OPEN_FLAGS (DELETE | KEY_READ)
// TODO: Issue #1231 Change to using HKEY_LOCAL_MACHINE
ebpf_registry_key_t ebpf_root_registry_key = HKEY_CURRENT_USER;
extern ebpf_registry_key_t ebpf_root_registry_key;
typedef struct _ebpf_program_section_info_with_count
{
@ -69,7 +69,7 @@ export_all_program_information()
break;
};
status = ebpf_store_update_program_information(program_information_array[i], 1);
status = _ebpf_store_update_program_information(program_information_array[i], 1);
if (status != ERROR_SUCCESS) {
break;
}
@ -83,7 +83,7 @@ export_all_section_information()
{
uint32_t status = ERROR_SUCCESS;
for (const auto& section : _section_information) {
status = ebpf_store_update_section_information(section.section_info, (uint32_t)section.section_info_count);
status = _ebpf_store_update_section_information(section.section_info, (uint32_t)section.section_info_count);
if (status != ERROR_SUCCESS) {
break;
}
@ -95,63 +95,16 @@ export_all_section_information()
int
export_global_helper_information()
{
return ebpf_store_update_global_helper_information(
return _ebpf_store_update_global_helper_information(
ebpf_core_helper_function_prototype, ebpf_core_helper_functions_count);
}
static uint32_t
_clear_ebpf_store(ebpf_registry_key_t root_key_path)
{
ebpf_registry_key_t root_handle = {0};
ebpf_registry_key_t provider_handle = {0};
uint32_t status;
// Open root registry key.
status = open_registry_key(root_key_path, EBPF_ROOT_RELATIVE_PATH, REG_CREATE_FLAGS, &root_handle);
if (status != ERROR_SUCCESS) {
if (status == ERROR_FILE_NOT_FOUND) {
status = ERROR_SUCCESS;
}
goto Exit;
}
// Open "providers" registry key.
status = open_registry_key(root_handle, EBPF_PROVIDERS_REGISTRY_PATH, REG_CREATE_FLAGS, &provider_handle);
if (status != ERROR_SUCCESS) {
if (status == ERROR_FILE_NOT_FOUND) {
status = ERROR_SUCCESS;
}
goto Exit;
}
// Delete subtree of provider reg key.
status = delete_registry_tree(provider_handle, nullptr);
if (status != ERROR_SUCCESS) {
goto Exit;
}
close_registry_key(provider_handle);
provider_handle = nullptr;
status = delete_registry_key(root_handle, EBPF_PROVIDERS_REGISTRY_PATH);
Exit:
if (provider_handle) {
close_registry_key(provider_handle);
}
if (root_handle) {
close_registry_key(root_handle);
}
return status;
}
uint32_t
clear_all_ebpf_stores()
{
// TODO: Issue #1231 Change to using HKEY_LOCAL_MACHINE
std::cout << "Clearing eBPF store HKEY_CURRENT_USER" << std::endl;
return _clear_ebpf_store(ebpf_root_registry_key);
return ebpf_store_clear(ebpf_root_registry_key);
}
void

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

@ -104,6 +104,8 @@ $(OutputPath)export_program_info.exe</Command>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\libs\api_common\registry_helper.cpp" />
<ClCompile Include="..\..\libs\api_common\store_helper_internal.cpp" />
<ClCompile Include="..\..\libs\api_common\utilities.cpp" />
<ClCompile Include="export_program_info.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>

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

@ -25,9 +25,15 @@
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\libs\api_common\store_helper_internal.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\libs\api_common\registry_helper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\libs\api_common\utilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

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

@ -10,6 +10,7 @@ int
main(int argc, char** argv)
{
bool clear = false;
if (argc != 1 && argc != 2) {
print_help(argv[0]);
return 1;
@ -24,8 +25,8 @@ main(int argc, char** argv)
}
}
uint32_t status;
if (!clear) {
uint32_t status;
std::cout << "Exporting program information." << std::endl;
status = export_all_program_information();
@ -45,7 +46,11 @@ main(int argc, char** argv)
std::cout << "Failed export_global_helper_information() - ERROR #" << status << std::endl;
}
} else {
clear_all_ebpf_stores();
std::cout << "Clearing eBPF store." << std::endl;
status = clear_all_ebpf_stores();
if (status != EBPF_SUCCESS) {
std::cout << "Failed clear_all_ebpf_stores() - ERROR #" << status << std::endl;
}
}
return 0;