API to create map and enumerate all pinned maps. (#246)

* API to create map and enumerate all pinned maps.

* Apply suggestions from code review

Co-authored-by: Dave Thaler <dthaler@microsoft.com>

* Address code review comments

* Address code review comments #2

* Address code review comments #3

Co-authored-by: Dave Thaler <dthaler@microsoft.com>
Co-authored-by: Alan Jowett <alanjo@microsoft.com>
This commit is contained in:
Shankar Seal 2021-06-09 08:44:24 -07:00 коммит произвёл GitHub
Родитель a69d6f55ad
Коммит 27f8d49888
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
48 изменённых файлов: 1879 добавлений и 120 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -56,3 +56,6 @@ docs/html
pipeline.log
endortemp/
artifacts/
# Visual Code.
**/.vscode/**/*

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

@ -113,6 +113,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpc_interface", "rpc_interf
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api_common", "libs\api_common\api_common.vcxproj", "{E79382B2-FED9-4CD4-9498-DBDDD6C46C91}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api_test", "tests\api_test\api_test.vcxproj", "{12161211-5463-4AA9-9B6E-552552B475DC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common_tests", "tests\libs\common\common_tests.vcxproj", "{3617528A-CB85-418B-82C1-E9CFC16755F6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_util", "tests\libs\util\test_util.vcxproj", "{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@ -929,6 +935,90 @@ Global
{E79382B2-FED9-4CD4-9498-DBDDD6C46C91}.RelWithDebInfo|x64.Build.0 = Release|x64
{E79382B2-FED9-4CD4-9498-DBDDD6C46C91}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
{E79382B2-FED9-4CD4-9498-DBDDD6C46C91}.RelWithDebInfo|x86.Build.0 = Release|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.Debug|ARM.ActiveCfg = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.Debug|ARM64.ActiveCfg = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.Debug|x64.ActiveCfg = Debug|x64
{12161211-5463-4AA9-9B6E-552552B475DC}.Debug|x64.Build.0 = Debug|x64
{12161211-5463-4AA9-9B6E-552552B475DC}.Debug|x86.ActiveCfg = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.Debug|x86.Build.0 = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.MinSizeRel|ARM.ActiveCfg = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.MinSizeRel|ARM.Build.0 = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.MinSizeRel|ARM64.ActiveCfg = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.MinSizeRel|ARM64.Build.0 = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.MinSizeRel|x64.ActiveCfg = Debug|x64
{12161211-5463-4AA9-9B6E-552552B475DC}.MinSizeRel|x64.Build.0 = Debug|x64
{12161211-5463-4AA9-9B6E-552552B475DC}.MinSizeRel|x86.ActiveCfg = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.MinSizeRel|x86.Build.0 = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.Release|ARM.ActiveCfg = Release|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.Release|ARM64.ActiveCfg = Release|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.Release|x64.ActiveCfg = Release|x64
{12161211-5463-4AA9-9B6E-552552B475DC}.Release|x64.Build.0 = Release|x64
{12161211-5463-4AA9-9B6E-552552B475DC}.Release|x86.ActiveCfg = Release|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.Release|x86.Build.0 = Release|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.RelWithDebInfo|ARM.ActiveCfg = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.RelWithDebInfo|ARM.Build.0 = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.RelWithDebInfo|ARM64.Build.0 = Debug|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{12161211-5463-4AA9-9B6E-552552B475DC}.RelWithDebInfo|x64.Build.0 = Release|x64
{12161211-5463-4AA9-9B6E-552552B475DC}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
{12161211-5463-4AA9-9B6E-552552B475DC}.RelWithDebInfo|x86.Build.0 = Release|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Debug|ARM.ActiveCfg = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Debug|ARM64.ActiveCfg = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Debug|x64.ActiveCfg = Debug|x64
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Debug|x64.Build.0 = Debug|x64
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Debug|x86.ActiveCfg = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Debug|x86.Build.0 = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.MinSizeRel|ARM.ActiveCfg = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.MinSizeRel|ARM.Build.0 = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.MinSizeRel|ARM64.ActiveCfg = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.MinSizeRel|ARM64.Build.0 = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.MinSizeRel|x64.ActiveCfg = Debug|x64
{3617528A-CB85-418B-82C1-E9CFC16755F6}.MinSizeRel|x64.Build.0 = Debug|x64
{3617528A-CB85-418B-82C1-E9CFC16755F6}.MinSizeRel|x86.ActiveCfg = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.MinSizeRel|x86.Build.0 = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Release|ARM.ActiveCfg = Release|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Release|ARM64.ActiveCfg = Release|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Release|x64.ActiveCfg = Release|x64
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Release|x64.Build.0 = Release|x64
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Release|x86.ActiveCfg = Release|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.Release|x86.Build.0 = Release|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.RelWithDebInfo|ARM.ActiveCfg = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.RelWithDebInfo|ARM.Build.0 = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.RelWithDebInfo|ARM64.Build.0 = Debug|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{3617528A-CB85-418B-82C1-E9CFC16755F6}.RelWithDebInfo|x64.Build.0 = Release|x64
{3617528A-CB85-418B-82C1-E9CFC16755F6}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
{3617528A-CB85-418B-82C1-E9CFC16755F6}.RelWithDebInfo|x86.Build.0 = Release|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Debug|ARM.ActiveCfg = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Debug|ARM64.ActiveCfg = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Debug|x64.ActiveCfg = Debug|x64
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Debug|x64.Build.0 = Debug|x64
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Debug|x86.ActiveCfg = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Debug|x86.Build.0 = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.MinSizeRel|ARM.ActiveCfg = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.MinSizeRel|ARM.Build.0 = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.MinSizeRel|ARM64.ActiveCfg = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.MinSizeRel|ARM64.Build.0 = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.MinSizeRel|x64.ActiveCfg = Debug|x64
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.MinSizeRel|x64.Build.0 = Debug|x64
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.MinSizeRel|x86.ActiveCfg = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.MinSizeRel|x86.Build.0 = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Release|ARM.ActiveCfg = Release|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Release|ARM64.ActiveCfg = Release|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Release|x64.ActiveCfg = Release|x64
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Release|x64.Build.0 = Release|x64
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Release|x86.ActiveCfg = Release|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.Release|x86.Build.0 = Release|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.RelWithDebInfo|ARM.ActiveCfg = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.RelWithDebInfo|ARM.Build.0 = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.RelWithDebInfo|ARM64.Build.0 = Debug|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.RelWithDebInfo|x64.Build.0 = Release|x64
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F}.RelWithDebInfo|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -962,6 +1052,9 @@ Global
{AF85C549-57CC-40A5-BDFC-DCF1998DE80F} = {69CDB6A1-434D-4BC9-9BFF-D12DF7EDBB6B}
{1423245D-0249-40FC-A077-FF7780ACFE3F} = {7978FF80-0017-4BD7-A91D-3B113F1F9F9E}
{E79382B2-FED9-4CD4-9498-DBDDD6C46C91} = {69CDB6A1-434D-4BC9-9BFF-D12DF7EDBB6B}
{12161211-5463-4AA9-9B6E-552552B475DC} = {492C9B22-9237-4996-9E33-CA14D3533616}
{3617528A-CB85-418B-82C1-E9CFC16755F6} = {492C9B22-9237-4996-9E33-CA14D3533616}
{D6725F19-B9BF-435F-80F2-C5F3EF0F4B8F} = {492C9B22-9237-4996-9E33-CA14D3533616}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3D5F862D-74C6-4357-9F95-0B152E33B7B8}

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

@ -8,6 +8,7 @@ EXPORTS
ebpf_api_initiate
ebpf_api_terminate
ebpf_api_load_program
ebpf_api_create_map
ebpf_api_free_string
ebpf_api_map_find_element
ebpf_api_map_update_element
@ -24,4 +25,6 @@ EXPORTS
ebpf_api_get_next_program
ebpf_api_program_query_information
ebpf_api_link_program
ebpf_api_close_handle
ebpf_api_close_handle
ebpf_api_get_pinned_map_info
ebpf_api_map_info_free

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

@ -110,7 +110,7 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);BINARY_COMPATIBLE=0;NT;UNICODE;_UNICODE;NDIS60;POOL_NX_OPTIN_AUTO</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Midl>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>

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

@ -56,26 +56,49 @@ _ebpf_driver_io_device_control(
inline NTSTATUS
_ebpf_result_to_ntstatus(ebpf_result_t result)
{
NTSTATUS status;
switch (result) {
case EBPF_SUCCESS:
return STATUS_SUCCESS;
case EBPF_NO_MEMORY:
return STATUS_INSUFFICIENT_RESOURCES;
case EBPF_ERROR_NOT_FOUND:
return STATUS_NOT_FOUND;
case EBPF_INVALID_ARGUMENT:
return STATUS_INVALID_PARAMETER;
case EBPF_ERROR_BLOCKED_BY_POLICY:
return STATUS_CONTENT_BLOCKED;
case EBPF_ERROR_NO_MORE_KEYS:
return STATUS_NO_MORE_MATCHES;
case EBPF_ERROR_INVALID_HANDLE:
return STATUS_INVALID_HANDLE;
case EBPF_ERROR_NOT_SUPPORTED:
return STATUS_NOT_SUPPORTED;
default:
return STATUS_INVALID_PARAMETER;
case EBPF_SUCCESS: {
status = STATUS_SUCCESS;
break;
}
case EBPF_NO_MEMORY: {
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
case EBPF_ERROR_NOT_FOUND: {
status = STATUS_NOT_FOUND;
break;
}
case EBPF_INVALID_ARGUMENT: {
status = STATUS_INVALID_PARAMETER;
break;
}
case EBPF_ERROR_BLOCKED_BY_POLICY: {
status = STATUS_CONTENT_BLOCKED;
break;
}
case EBPF_ERROR_NO_MORE_KEYS: {
status = STATUS_NO_MORE_MATCHES;
break;
}
case EBPF_ERROR_INVALID_HANDLE: {
status = STATUS_INVALID_HANDLE;
break;
}
case EBPF_ERROR_NOT_SUPPORTED: {
status = STATUS_NOT_SUPPORTED;
break;
}
case EBPF_ERROR_INSUFFICIENT_BUFFER: {
status = STATUS_BUFFER_OVERFLOW;
break;
}
default:
status = STATUS_INVALID_PARAMETER;
}
return status;
}
static _Function_class_(EVT_WDF_DRIVER_UNLOAD) _IRQL_requires_same_

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

@ -9,6 +9,8 @@
#include <stdint.h>
#include "ebpf_execution_type.h"
#include "ebpf_result.h"
#include "ebpf_core_structs.h"
#include "ebpf_result.h"
#include "ebpf_windows.h"
#ifdef __cplusplus
@ -68,6 +70,26 @@ extern "C"
ebpf_handle_t* map_handles,
const char** error_message);
/**
* @brief Create an eBPF map with input parameters.
* @param[in] type Map type.
* @param[in] key_size Key size.
* @param[in] value_size Value size.
* @param[in] max_entries Maximum number of entries in the map.
*
* @retval EBPF_SUCCESS Map created successfully.
* @retval EBPF_ERROR_NOT_SUPPORTED Unsupported map type.
* @retval EBPF_INVALID_ARGUMENT One or more parameters are incorrect.
*/
ebpf_result_t
ebpf_api_create_map(
ebpf_map_type_t type,
uint32_t key_size,
uint32_t value_size,
uint32_t max_entries,
uint32_t map_flags,
_Out_ ebpf_handle_t* handle);
/**
* @brief Find an element in an eBPF map.
* @param[in] handle Handle to eBPF map.
@ -302,6 +324,30 @@ extern "C"
uint32_t
ebpf_api_close_handle(ebpf_handle_t handle);
/**
* @brief Returns an array of ebpf_map_information_t for all pinned maps.
*
* @param[out] map_count Number of pinned maps.
* @param[out] map_info Array of ebpf_map_information_t for pinned maps.
*
* @retval EBPF_SUCCESS The API suceeded.
* @retval EBPF_NO_MEMORY Out of memory.
* @retval EBPF_INVALID_ARGUMENT One or more parameters are wrong.
*/
ebpf_result_t
ebpf_api_get_pinned_map_info(
_Out_ uint16_t* map_count, _Outptr_result_buffer_maybenull_(*map_count) ebpf_map_information_t** map_info);
/**
* @brief Helper Function to free array of ebpf_map_information_t allocated by
* ebpf_api_get_pinned_map_info function.
*
* @param[in] map_count Length of array to be freed.
* @param[in] map_info Map to be freed.
*/
void
ebpf_api_map_info_free(uint16_t map_count, _In_count_(map_count) const ebpf_map_information_t* map_info);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
// This file contains eBPF definitions common to eBPF core libraries as well as
// the eBPF API library.
#pragma once
#include <stdint.h>
#include "ebpf_structs.h"
#define EBPF_MAX_PIN_PATH_LENGTH 256
/**
* @brief eBPF Map Information
*/
typedef struct _ebpf_map_information
{
ebpf_map_definition_t definition;
_Field_z_ char* pin_path;
} ebpf_map_information_t;

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

@ -4,25 +4,11 @@
#include <stdint.h>
#include "ebpf_structs.h"
// This file contains APIs for global helpers that are
// exposed for use by all eBPF programs.
typedef struct _ebpf_map_definition
{
uint32_t size;
uint32_t type;
uint32_t key_size;
uint32_t value_size;
uint32_t max_entries;
} ebpf_map_definition_t;
typedef enum _ebpf_map_type
{
EBPF_MAP_TYPE_UNSPECIFIED = 0,
EBPF_MAP_TYPE_HASH = 1,
EBPF_MAP_TYPE_ARRAY = 2,
} ebpf_map_type_t;
typedef void* (*ebpf_map_lookup_element_t)(ebpf_map_definition_t* map, void* key);
#define ebpf_map_lookup_element ((ebpf_map_lookup_element_t)1)

30
include/ebpf_structs.h Normal file
Просмотреть файл

@ -0,0 +1,30 @@
/*
* Copyright (c) Microsoft Corporation
* SPDX-License-Identifier: MIT
*/
// This file contains eBPF definitions common to eBPF programs, core execution engine
// as well as eBPF API library.
#pragma once
#include <stdint.h>
typedef enum _ebpf_map_type
{
EBPF_MAP_TYPE_UNSPECIFIED = 0,
EBPF_MAP_TYPE_HASH = 1,
EBPF_MAP_TYPE_ARRAY = 2,
} ebpf_map_type_t;
/**
* @brief eBPF Map Definition
*/
typedef struct _ebpf_map_definition
{
uint32_t size;
ebpf_map_type_t type;
uint32_t key_size;
uint32_t value_size;
uint32_t max_entries;
} ebpf_map_definition_t;

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

@ -135,6 +135,7 @@
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

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

@ -6,7 +6,9 @@
#include "api_common.hpp"
#include "device_helper.hpp"
#include "ebpf_api.h"
#include "ebpf_platform.h"
#include "ebpf_protocol.h"
#include "ebpf_serialize.h"
#include "map_descriptors.hpp"
#include "rpc_client.h"
extern "C"
@ -42,10 +44,17 @@ ebpf_api_terminate()
clean_up_rpc_binding();
}
int
create_map_function(
uint32_t type, uint32_t key_size, uint32_t value_size, uint32_t max_entries, ebpf_verifier_options_t)
ebpf_result_t
ebpf_api_create_map(
ebpf_map_type_t type,
uint32_t key_size,
uint32_t value_size,
uint32_t max_entries,
uint32_t map_flags,
_Out_ handle_t* handle)
{
UNREFERENCED_PARAMETER(map_flags);
_ebpf_operation_create_map_request request{
sizeof(_ebpf_operation_create_map_request),
ebpf_operation_id_t::EBPF_OPERATION_CREATE_MAP,
@ -53,16 +62,40 @@ create_map_function(
_ebpf_operation_create_map_reply reply{};
uint32_t retval = invoke_ioctl(request, reply);
if (retval != ERROR_SUCCESS) {
throw std::runtime_error(std::string("Error ") + std::to_string(retval) + " trying to create map");
uint32_t return_value = EBPF_SUCCESS;
if (handle == nullptr) {
return_value = ERROR_INVALID_PARAMETER;
goto Exit;
}
*handle = INVALID_HANDLE_VALUE;
return_value = invoke_ioctl(request, reply);
if (return_value != ERROR_SUCCESS)
goto Exit;
ebpf_assert(reply.header.id == ebpf_operation_id_t::EBPF_OPERATION_CREATE_MAP);
*handle = reinterpret_cast<ebpf_handle_t>(reply.handle);
Exit:
return windows_error_to_ebpf_result(return_value);
}
int
create_map_internal(
uint32_t type, uint32_t key_size, uint32_t value_size, uint32_t max_entries, ebpf_verifier_options_t)
{
handle_t map_handle = INVALID_HANDLE_VALUE;
ebpf_result_t result =
ebpf_api_create_map(static_cast<ebpf_map_type_t>(type), key_size, value_size, max_entries, 0, &map_handle);
if (result != EBPF_SUCCESS) {
throw std::runtime_error(std::string("Error ") + std::to_string(result) + " trying to create map");
}
if (reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_CREATE_MAP) {
throw std::runtime_error(std::string("reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_CREATE_MAP"));
}
return cache_map_handle(reply.handle, type, key_size, value_size, max_entries);
return cache_map_handle(reinterpret_cast<uint64_t>(map_handle), type, key_size, value_size, max_entries);
}
static ebpf_result_t
@ -533,3 +566,108 @@ ebpf_api_close_handle(ebpf_handle_t handle)
return invoke_ioctl(request);
}
ebpf_result_t
ebpf_api_get_pinned_map_info(
_Out_ uint16_t* map_count, _Outptr_result_buffer_maybenull_(*map_count) ebpf_map_information_t** map_info)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_operation_get_map_information_request_t request = {
sizeof(request), EBPF_OPERATION_GET_MAP_INFORMATION, reinterpret_cast<uint64_t>(INVALID_HANDLE_VALUE)};
ebpf_protocol_buffer_t reply_buffer;
ebpf_operation_get_map_information_reply_t* reply = nullptr;
size_t min_expected_buffer_length = 0;
size_t serialized_buffer_length = 0;
uint16_t local_map_count = 0;
ebpf_map_information_t* local_map_info = nullptr;
size_t output_buffer_length = 4 * 1024;
uint8_t attempt_count = 0;
if ((map_count == nullptr) || (map_info == nullptr)) {
result = EBPF_INVALID_ARGUMENT;
goto Exit;
}
while (attempt_count < IOCTL_MAX_ATTEMPTS) {
size_t reply_length;
result = ebpf_safe_size_t_add(
EBPF_OFFSET_OF(ebpf_operation_get_map_information_reply_t, data), output_buffer_length, &reply_length);
if (result != EBPF_SUCCESS)
goto Exit;
try {
reply_buffer.resize(reply_length);
} catch (const std::bad_alloc&) {
result = EBPF_NO_MEMORY;
goto Exit;
} catch (...) {
result = EBPF_FAILED;
goto Exit;
}
// Invoke IOCTL.
result = windows_error_to_ebpf_result(invoke_ioctl(request, reply_buffer));
if ((result != EBPF_SUCCESS) && (result != EBPF_ERROR_INSUFFICIENT_BUFFER))
goto Exit;
reply = reinterpret_cast<ebpf_operation_get_map_information_reply_t*>(reply_buffer.data());
if (result == EBPF_ERROR_INSUFFICIENT_BUFFER) {
output_buffer_length = reply->size;
attempt_count++;
continue;
} else
// Success.
break;
}
if (attempt_count == IOCTL_MAX_ATTEMPTS)
goto Exit;
local_map_count = reply->map_count;
serialized_buffer_length = reply->size;
if (local_map_count == 0)
// No pinned maps present.
goto Exit;
// Check if the data buffer in IOCTL reply is at least as long as the
// minimum expected length needed to hold the array of ebpf map information objects.
result = ebpf_safe_size_t_multiply(
EBPF_OFFSET_OF(ebpf_serialized_map_information_t, pin_path),
(size_t)local_map_count,
&min_expected_buffer_length);
if (result != EBPF_SUCCESS)
goto Exit;
ebpf_assert(serialized_buffer_length >= min_expected_buffer_length);
if (serialized_buffer_length < min_expected_buffer_length) {
result = EBPF_INVALID_ARGUMENT;
goto Exit;
}
// Deserialize reply buffer.
result =
ebpf_deserialize_map_information_array(serialized_buffer_length, reply->data, local_map_count, &local_map_info);
if (result != EBPF_SUCCESS)
goto Exit;
Exit:
if (result != EBPF_SUCCESS) {
ebpf_api_map_info_free(local_map_count, local_map_info);
local_map_count = 0;
local_map_info = nullptr;
}
*map_count = local_map_count;
*map_info = local_map_info;
return result;
}
void
ebpf_api_map_info_free(_In_ const uint16_t map_count, _In_count_(map_count) const ebpf_map_information_t* map_info)
{
ebpf_map_information_array_free(map_count, map_info);
}

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

@ -21,7 +21,7 @@
#include "windows_platform_common.hpp"
int
create_map_function(
create_map_internal(
uint32_t type, uint32_t key_size, uint32_t value_size, uint32_t max_entries, ebpf_verifier_options_t options);
static int
@ -36,7 +36,7 @@ create_map_windows(
return fd;
}
return create_map_function(map_type, key_size, value_size, max_entries, options);
return create_map_internal(map_type, key_size, value_size, max_entries, options);
}
void
@ -58,7 +58,7 @@ parse_maps_section_windows(
for (auto s : mapdefs) {
map_descriptors.emplace_back(EbpfMapDescriptor{
.original_fd = create_map_windows(s.type, s.key_size, s.value_size, s.max_entries, options),
.type = s.type,
.type = (uint32_t)s.type,
.key_size = s.key_size,
.value_size = s.value_size,
});

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

@ -5,10 +5,12 @@
#include <string>
#include <vector>
#include <Windows.h>
#include "api_common.hpp"
#include "device_helper.hpp"
#include "ebpf_protocol.h"
#include "ebpf_result.h"
#include "device_helper.hpp"
#pragma warning(push)
#pragma warning(disable : 4100) // 'identifier' : unreferenced formal parameter
#pragma warning(disable : 4244) // 'conversion' conversion from 'type1' to

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

@ -136,6 +136,7 @@
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

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

@ -12,6 +12,9 @@
// Function codes from 0x800 to 0xFFF are for customer use.
#define IOCTL_EBPFCTL_METHOD_BUFFERED CTL_CODE(EBPF_IOCTL_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
// Maxiumum attempts to invoke an IOCTL.
#define IOCTL_MAX_ATTEMPTS 16
typedef std::vector<uint8_t> ebpf_protocol_buffer_t;
typedef std::vector<uint8_t> ebpf_code_buffer_t;
@ -34,6 +37,7 @@ template <typename request_t, typename reply_t = empty_reply_t>
uint32_t
invoke_ioctl(request_t& request, reply_t& reply = _empty_reply)
{
uint32_t return_value = ERROR_SUCCESS;
uint32_t actual_reply_size;
uint32_t request_size;
void* request_ptr;
@ -78,12 +82,21 @@ invoke_ioctl(request_t& request, reply_t& reply = _empty_reply)
nullptr);
if (!result) {
return GetLastError();
return_value = GetLastError();
goto Exit;
}
// Actual reply size cannot be smaller than minimum expected reply size.
if (actual_reply_size < reply_size) {
return_value = ERROR_INVALID_PARAMETER;
goto Exit;
}
if (actual_reply_size != reply_size && !variable_reply_size) {
return ERROR_INVALID_PARAMETER;
return_value = ERROR_INVALID_PARAMETER;
goto Exit;
}
return ERROR_SUCCESS;
}
Exit:
return return_value;
}

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

@ -11,6 +11,7 @@
#include "ebpf_maps.h"
#include "ebpf_pinning_table.h"
#include "ebpf_program.h"
#include "ebpf_serialize.h"
GUID ebpf_global_helper_function_interface_id = {/* 8d2a1d3f-9ce6-473d-b48e-17aa5c5581fe */
0x8d2a1d3f,
@ -33,11 +34,10 @@ _ebpf_core_map_update_element(ebpf_map_t* map, const uint8_t* key, const uint8_t
static void
_ebpf_core_map_delete_element(ebpf_map_t* map, const uint8_t* key);
static const void* _ebpf_program_helpers[] = {
NULL,
(void*)&_ebpf_core_map_find_element,
(void*)&_ebpf_core_map_update_element,
(void*)&_ebpf_core_map_delete_element};
static const void* _ebpf_program_helpers[] = {NULL,
(void*)&_ebpf_core_map_find_element,
(void*)&_ebpf_core_map_update_element,
(void*)&_ebpf_core_map_delete_element};
ebpf_result_t
ebpf_core_initiate()
@ -576,9 +576,9 @@ static ebpf_result_t
_ebpf_core_protocol_update_pinning(_In_ const struct _ebpf_operation_update_map_pinning_request* request)
{
ebpf_result_t retval;
const ebpf_utf8_string_t name = {
(uint8_t*)request->name,
request->header.length - EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, name)};
const ebpf_utf8_string_t name = {(uint8_t*)request->name,
request->header.length -
EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, name)};
ebpf_object_t* object = NULL;
if (name.length == 0) {
@ -681,7 +681,7 @@ _ebpf_core_protocol_get_ec_function(
return EBPF_SUCCESS;
}
static uint64_t
static ebpf_result_t
_ebpf_core_protocol_get_program_information(
_In_ const ebpf_operation_get_program_information_request_t* request,
_Inout_ ebpf_operation_get_program_information_reply_t* reply,
@ -727,6 +727,131 @@ Done:
return retval;
}
static ebpf_result_t
_ebpf_core_protocol_convert_pinning_entries_to_map_information_array(
uint16_t entry_count,
_In_count_(entry_count) ebpf_pinning_entry_t* pinning_entries,
_Outptr_result_buffer_maybenull_(entry_count) ebpf_core_map_information_t** map_info)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_core_map_information_t* local_map_info = NULL;
uint16_t index;
if (map_info == NULL) {
result = EBPF_INVALID_ARGUMENT;
goto Exit;
}
if ((entry_count == 0) || (pinning_entries == NULL))
goto Exit;
local_map_info = (ebpf_core_map_information_t*)ebpf_allocate(sizeof(ebpf_core_map_information_t) * entry_count);
if (local_map_info == NULL) {
result = EBPF_NO_MEMORY;
goto Exit;
}
for (index = 0; index < entry_count; index++) {
ebpf_pinning_entry_t* source = &pinning_entries[index];
ebpf_core_map_information_t* destination = &local_map_info[index];
ebpf_map_definition_t* map_definition;
if (ebpf_object_get_type(source->object) != EBPF_OBJECT_MAP) {
// Bad object type.
result = EBPF_INVALID_ARGUMENT;
goto Exit;
}
// Query map defintion.
map_definition = ebpf_map_get_definition((ebpf_map_t*)source->object);
destination->definition = *map_definition;
// Set pin path. No need to duplicate.
destination->pin_path = source->name;
}
Exit:
if (result != EBPF_SUCCESS) {
ebpf_free(local_map_info);
local_map_info = NULL;
}
*map_info = local_map_info;
return result;
}
static ebpf_result_t
_ebpf_core_protocol_serialize_map_information_reply(
uint16_t map_count,
_In_count_(map_count) const ebpf_core_map_information_t* map_info,
size_t output_buffer_length,
_In_ ebpf_operation_get_map_information_reply_t* map_info_reply)
{
ebpf_result_t result = EBPF_SUCCESS;
size_t serialization_buffer_size;
size_t required_serialization_length;
serialization_buffer_size = output_buffer_length - EBPF_OFFSET_OF(ebpf_operation_get_map_information_reply_t, data);
result = ebpf_serialize_core_map_information_array(
map_count,
map_info,
map_info_reply->data,
(const size_t)serialization_buffer_size,
(size_t*)&map_info_reply->size,
&required_serialization_length);
if (result != EBPF_SUCCESS) {
map_info_reply->header.length = (uint16_t)(
required_serialization_length + EBPF_OFFSET_OF(ebpf_operation_get_map_information_reply_t, data));
} else
map_info_reply->map_count = map_count;
return result;
}
static ebpf_result_t
_ebpf_core_protocol_get_map_information(
_In_ const ebpf_operation_get_map_information_request_t* request,
_In_ ebpf_operation_get_map_information_reply_t* reply,
uint16_t reply_length)
{
ebpf_result_t result = EBPF_SUCCESS;
uint16_t entry_count = 0;
ebpf_pinning_entry_t* pinning_entries = NULL;
ebpf_core_map_information_t* map_info = NULL;
UNREFERENCED_PARAMETER(request);
if (reply_length < (uint16_t)sizeof(ebpf_operation_get_map_information_reply_t)) {
result = EBPF_INVALID_ARGUMENT;
goto Exit;
}
// Enumerate all the pinning entries for map objects.
result = ebpf_pinning_table_enumerate_entries(
_ebpf_core_map_pinning_table, EBPF_OBJECT_MAP, &entry_count, &pinning_entries);
if (result != EBPF_SUCCESS)
goto Exit;
if (entry_count == 0)
// No pinned map entries to return.
goto Exit;
// Convert pinning entries to map_information_t array.
result =
_ebpf_core_protocol_convert_pinning_entries_to_map_information_array(entry_count, pinning_entries, &map_info);
if (result != EBPF_SUCCESS)
goto Exit;
// Serialize map information array onto reply structure.
result = _ebpf_core_protocol_serialize_map_information_reply(entry_count, map_info, reply_length, reply);
Exit:
ebpf_free(map_info);
ebpf_pinning_entries_release(entry_count, pinning_entries);
return result;
}
static void*
_ebpf_core_map_find_element(ebpf_map_t* map, const uint8_t* key)
{
@ -759,59 +884,100 @@ typedef struct _ebpf_protocol_handler
size_t minimum_reply_size;
} const ebpf_protocol_handler_t;
static ebpf_protocol_handler_t _ebpf_protocol_handlers[EBPF_OPERATION_GET_PROGRAM_INFORMATION + 1] = {
static ebpf_protocol_handler_t _ebpf_protocol_handlers[] = {
// EBPF_OPERATION_RESOLVE_HELPER
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_resolve_helper,
EBPF_OFFSET_OF(ebpf_operation_resolve_helper_request_t, helper_id),
sizeof(struct _ebpf_operation_resolve_helper_reply)},
// EBPF_OPERATION_RESOLVE_MAP
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_resolve_map,
EBPF_OFFSET_OF(ebpf_operation_resolve_map_request_t, map_handle),
sizeof(struct _ebpf_operation_resolve_map_reply)},
// EBPF_OPERATION_CREATE_PROGRAM
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_create_program,
sizeof(struct _ebpf_operation_create_program_request),
sizeof(struct _ebpf_operation_create_program_reply)},
// EBPF_OPERATION_CREATE_MAP
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_create_map,
sizeof(struct _ebpf_operation_create_map_request),
sizeof(struct _ebpf_operation_create_map_reply)},
// EBPF_OPERATION_LOAD_CODE
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_load_code,
sizeof(struct _ebpf_operation_load_code_request),
0},
// EBPF_OPERATION_MAP_FIND_ELEMENT
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_map_find_element,
sizeof(struct _ebpf_operation_map_find_element_request),
sizeof(struct _ebpf_operation_map_find_element_reply)},
// EBPF_OPERATION_MAP_UPDATE_ELEMENT
{_ebpf_core_protocol_map_update_element, sizeof(struct _ebpf_operation_map_update_element_request), 0},
// EBPF_OPERATION_MAP_DELETE_ELEMENT
{_ebpf_core_protocol_map_delete_element, sizeof(struct _ebpf_operation_map_delete_element_request), 0},
// EBPF_OPERATION_MAP_GET_NEXT_KEY
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_map_get_next_key,
EBPF_OFFSET_OF(ebpf_operation_map_get_next_key_request_t, previous_key),
sizeof(ebpf_operation_map_get_next_key_reply_t)},
// EBPF_OPERATION_GET_NEXT_MAP
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_next_map,
sizeof(struct _ebpf_operation_get_next_map_request),
sizeof(struct _ebpf_operation_get_next_map_reply)},
// EBPF_OPERATION_GET_NEXT_PROGRAM
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_next_program,
sizeof(struct _ebpf_operation_get_next_program_request),
sizeof(struct _ebpf_operation_get_next_program_reply)},
// EBPF_OPERATION_QUERY_MAP_DEFINITION
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_query_map_definition,
sizeof(struct _ebpf_operation_query_map_definition_request),
sizeof(struct _ebpf_operation_query_map_definition_reply)},
// EBPF_OPERATION_QUERY_PROGRAM_INFORMATION
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_query_program_information,
sizeof(struct _ebpf_operation_query_program_information_request),
sizeof(struct _ebpf_operation_query_program_information_reply)},
// EBPF_OPERATION_UPDATE_PINNING
{_ebpf_core_protocol_update_pinning, sizeof(struct _ebpf_operation_update_map_pinning_request), 0},
// EBPF_OPERATION_GET_PINNING
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_pinned_object,
sizeof(struct _ebpf_operation_get_pinning_request),
sizeof(struct _ebpf_operation_get_pinning_reply)},
// EBPF_OPERATION_LINK_PROGRAM
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_link_program,
sizeof(ebpf_operation_link_program_request_t),
sizeof(ebpf_operation_link_program_reply_t)},
// EBPF_OPERATION_CLOSE_HANDLE
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_close_handle,
sizeof(ebpf_operation_close_handle_request_t),
0},
// EBPF_OPERATION_GET_EC_FUNCTION
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_ec_function,
sizeof(ebpf_operation_get_ec_function_request_t),
sizeof(ebpf_operation_get_ec_function_reply_t)},
// EBPF_OPERATION_GET_PROGRAM_INFORMATION
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_program_information,
sizeof(ebpf_operation_get_program_information_request_t),
sizeof(ebpf_operation_get_program_information_reply_t)},
};
// EBPF_OPERATION_GET_MAP_INFORMATION
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_map_information,
sizeof(ebpf_operation_get_map_information_request_t),
sizeof(ebpf_operation_get_map_information_reply_t)}};
ebpf_result_t
ebpf_core_get_protocol_handler_properties(
@ -820,7 +986,7 @@ ebpf_core_get_protocol_handler_properties(
*minimum_request_size = 0;
*minimum_reply_size = 0;
if (operation_id > EBPF_OPERATION_GET_PROGRAM_INFORMATION || operation_id < EBPF_OPERATION_RESOLVE_HELPER)
if (operation_id >= EBPF_COUNT_OF(_ebpf_protocol_handlers) || operation_id < EBPF_OPERATION_RESOLVE_HELPER)
return EBPF_ERROR_NOT_SUPPORTED;
if (!_ebpf_protocol_handlers[operation_id].dispatch.protocol_handler_no_reply)
@ -840,7 +1006,7 @@ ebpf_core_invoke_protocol_handler(
{
ebpf_result_t retval;
if (operation_id > EBPF_OPERATION_GET_PROGRAM_INFORMATION || operation_id < EBPF_OPERATION_RESOLVE_HELPER) {
if (operation_id >= EBPF_COUNT_OF(_ebpf_protocol_handlers) || operation_id < EBPF_OPERATION_RESOLVE_HELPER) {
return EBPF_ERROR_NOT_SUPPORTED;
}

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

@ -3,6 +3,7 @@
* SPDX-License-Identifier: MIT
*/
#pragma once
#include "ebpf_core_structs.h"
#include "ebpf_helpers.h"
#include "ebpf_windows.h"
@ -27,6 +28,7 @@ typedef enum _ebpf_operation_id
EBPF_OPERATION_CLOSE_HANDLE,
EBPF_OPERATION_GET_EC_FUNCTION,
EBPF_OPERATION_GET_PROGRAM_INFORMATION,
EBPF_OPERATION_GET_MAP_INFORMATION,
} ebpf_operation_id_t;
typedef enum _ebpf_code_type
@ -262,3 +264,17 @@ typedef struct _ebpf_operation_get_program_information_reply
uint16_t size;
uint8_t data[1];
} ebpf_operation_get_program_information_reply_t;
typedef struct _ebpf_operation_get_map_information_request
{
struct _ebpf_operation_header header;
uint64_t handle;
} ebpf_operation_get_map_information_request_t;
typedef struct _ebpf_operation_get_map_information_reply
{
struct _ebpf_operation_header header;
uint16_t map_count;
uint16_t size;
uint8_t data[1];
} ebpf_operation_get_map_information_reply_t;

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

@ -40,7 +40,7 @@ test_crud_operations(ebpf_map_type_t map_type)
_ebpf_core_initializer core;
ebpf_map_definition_t map_definition{
sizeof(ebpf_map_definition_t), (uint32_t)map_type, sizeof(uint32_t), sizeof(uint64_t), 10};
sizeof(ebpf_map_definition_t), map_type, sizeof(uint32_t), sizeof(uint64_t), 10};
map_ptr map;
{
ebpf_map_t* local_map;

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

@ -170,12 +170,20 @@ ebpf_hash_table_delete(ebpf_hash_table_t* hash_table, const uint8_t* key)
}
ebpf_result_t
ebpf_hash_table_next_key(ebpf_hash_table_t* hash_table, const uint8_t* previous_key, uint8_t* next_key)
ebpf_hash_table_next_key_and_value(
_In_ ebpf_hash_table_t* hash_table,
_In_opt_ const uint8_t* previous_key,
_Inout_ uint8_t* next_key,
_Outptr_opt_ uint8_t** value)
{
ebpf_result_t result = EBPF_SUCCESS;
RTL_AVL_TABLE* table = (RTL_AVL_TABLE*)hash_table;
uint8_t* entry;
void* restart_key;
if (value != NULL)
*value = NULL;
if (!previous_key) {
entry = RtlEnumerateGenericTableAvl(table, TRUE);
} else {
@ -204,11 +212,22 @@ ebpf_hash_table_next_key(ebpf_hash_table_t* hash_table, const uint8_t* previous_
}
}
if (entry == NULL) {
return EBPF_ERROR_NO_MORE_KEYS;
result = EBPF_ERROR_NO_MORE_KEYS;
goto Exit;
} else {
memcpy(next_key, entry, hash_table->key_size);
if (value != NULL)
*value = entry + hash_table->key_size;
}
return EBPF_SUCCESS;
Exit:
return result;
}
ebpf_result_t
ebpf_hash_table_next_key(ebpf_hash_table_t* hash_table, const uint8_t* previous_key, uint8_t* next_key)
{
return ebpf_hash_table_next_key_and_value(hash_table, previous_key, next_key, NULL);
}
size_t

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

@ -12,12 +12,6 @@ typedef struct _ebpf_pinning_table
ebpf_lock_t lock;
} ebpf_pinning_table_t;
typedef struct _ebpf_pinning_entry
{
ebpf_utf8_string_t name;
ebpf_object_t* object;
} ebpf_pinning_entry_t;
static ebpf_hash_table_compare_result_t
_ebpf_pining_table_compare_function(const uint8_t* key1, const uint8_t* key2)
{
@ -193,3 +187,114 @@ ebpf_pinning_table_delete(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_s
return return_value;
}
ebpf_result_t
ebpf_pinning_table_enumerate_entries(
_In_ ebpf_pinning_table_t* pinning_table,
ebpf_object_type_t object_type,
_Out_ uint16_t* entry_count,
_Outptr_result_buffer_maybenull_(*entry_count) ebpf_pinning_entry_t** pinning_entries)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_lock_state_t state;
bool lock_held = FALSE;
uint16_t local_entry_count = 0;
uint16_t entries_array_length = 0;
ebpf_pinning_entry_t* local_pinning_entries = NULL;
ebpf_utf8_string_t* next_object_name;
ebpf_pinning_entry_t* new_entry = NULL;
if ((entry_count == NULL) || (pinning_entries == NULL)) {
result = EBPF_INVALID_ARGUMENT;
goto Exit;
}
ebpf_lock_lock(&pinning_table->lock, &state);
lock_held = TRUE;
// Get output array length by finding how many entries are there in the pinning table.
entries_array_length = (uint16_t)ebpf_hash_table_key_count(pinning_table->hash_table);
// Exit if there are no entries.
if (entries_array_length == 0)
goto Exit;
// Allocate the output array for storing the pinning entries.
local_pinning_entries = (ebpf_pinning_entry_t*)ebpf_allocate(sizeof(ebpf_pinning_entry_t) * entries_array_length);
if (local_pinning_entries == NULL) {
result = EBPF_NO_MEMORY;
goto Exit;
}
// Loop through the entries in the hashtable.
next_object_name = NULL;
for (;;) {
ebpf_pinning_entry_t** next_pinning_entry = NULL;
// Find next pinning entry, if any.
result = ebpf_hash_table_next_key_and_value(
pinning_table->hash_table,
(const uint8_t*)((next_object_name == NULL) ? NULL : &next_object_name),
(uint8_t*)&next_object_name,
(uint8_t**)&next_pinning_entry);
if (result == EBPF_ERROR_NO_MORE_KEYS) {
// Reached end of hashtable.
result = EBPF_SUCCESS;
break;
}
if (result != EBPF_SUCCESS)
goto Exit;
// Skip entries that don't match the input object type.
if (object_type != ebpf_object_get_type((*next_pinning_entry)->object)) {
continue;
}
local_entry_count++;
ebpf_assert(local_entry_count <= entries_array_length);
// Copy the next pinning entry to a new entry in the output array.
new_entry = &local_pinning_entries[local_entry_count - 1];
new_entry->object = (*next_pinning_entry)->object;
// Take reference on underlying ebpf_object.
ebpf_object_acquire_reference(new_entry->object);
// Duplicate pinning object name.
result = ebpf_duplicate_utf8_string(&new_entry->name, &(*next_pinning_entry)->name);
if (result != EBPF_SUCCESS)
goto Exit;
}
Exit:
// Release lock if held.
if (lock_held)
ebpf_lock_unlock(&pinning_table->lock, &state);
if (result != EBPF_SUCCESS) {
ebpf_pinning_entries_release(local_entry_count, local_pinning_entries);
local_entry_count = 0;
local_pinning_entries = NULL;
}
// Set output parameters.
*entry_count = local_entry_count;
*pinning_entries = local_pinning_entries;
return result;
}
void
ebpf_pinning_entries_release(uint16_t entry_count, _In_count_(entry_count) ebpf_pinning_entry_t* pinning_entries)
{
uint16_t index;
for (index = 0; index < entry_count; index++) {
ebpf_pinning_entry_t* entry = &pinning_entries[index];
ebpf_free(entry->name.value);
ebpf_object_release_reference(entry->object);
}
ebpf_free(pinning_entries);
}

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

@ -12,6 +12,15 @@ extern "C"
#endif
typedef struct _ebpf_pinning_table ebpf_pinning_table_t;
/**
* @brief eBPF pinning table entry.
*/
typedef struct _ebpf_pinning_entry
{
ebpf_utf8_string_t name;
ebpf_object_t* object;
} ebpf_pinning_entry_t;
/**
* @brief Allocate a pinning table.
*
@ -75,6 +84,32 @@ extern "C"
ebpf_result_t
ebpf_pinning_table_delete(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* name);
/**
* @brief Returns all entries in the pinning table of specified object type after acquiring a reference.
*
* @param[in] pinning_table Pinning table to enumerate.
* @param[in] object_type eBPF object type that will be used to filter pinning entries.
* @param[out] entry_count Number of pinning entries being returned.
* @param[out] pinning_entries Array of pinning entries being returned. Must be freed by caller
* using ebpf_pinning_entries_release().
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Output array of entries could not be allocated.
*/
ebpf_result_t
ebpf_pinning_table_enumerate_entries(
_In_ ebpf_pinning_table_t* pinning_table,
ebpf_object_type_t object_type,
_Out_ uint16_t* entry_count,
_Outptr_result_buffer_maybenull_(*entry_count) ebpf_pinning_entry_t** pinning_entries);
/**
* @brief Releases entries returned by ebpf_pinning_table_enumerate_entries.
* @param[in] entry_count Length of input array of entries.
* @param[in] pinning_entries Array of entries to be released.
*/
void
ebpf_pinning_entries_release(uint16_t entry_count, _In_count_(entry_count) ebpf_pinning_entry_t* pinning_entries);
#ifdef __cplusplus
}
#endif

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

@ -207,6 +207,18 @@ extern "C"
ebpf_result_t
ebpf_safe_size_t_add(size_t augend, size_t addend, size_t* result);
/**
* @brief Subtract one value of type size_t from another and check for
* overflow or underflow.
* @param[in] minuend The value from which subtrahend is subtracted.
* @param[in] subtrahend The value subtract from minuend.
* @param[out] result A pointer to the result.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_ERROR_ARITHMETIC_OVERFLOW Addition overflowed or underflowed.
*/
ebpf_result_t
ebpf_safe_size_t_subtract(size_t minuend, size_t subtrahend, size_t* result);
/**
* @brief Create an instance of a lock.
* @param[in] lock Pointer to memory location that will contain the lock.
@ -442,6 +454,24 @@ extern "C"
ebpf_result_t
ebpf_hash_table_next_key(ebpf_hash_table_t* hash_table, const uint8_t* previous_key, uint8_t* next_key);
/**
* @brief Returns the next (key, value) pair in the hash table.
*
* @param[in] hash_table Hash-table to query.
* @param[in] previous_key Previous key or NULL to restart.
* @param[out] next_key Next key if it exists.
* @param[out] next_value If non-NULL, returns the next value if it exists.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MORE_KEYS No keys exist in the hash table that
* are lexicographically after the specified key.
*/
ebpf_result_t
ebpf_hash_table_next_key_and_value(
_In_ ebpf_hash_table_t* hash_table,
_In_opt_ const uint8_t* previous_key,
_Out_ uint8_t* next_key,
_Outptr_opt_ uint8_t** next_value);
/**
* @brief Get the number of keys in the hash table
*

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

@ -0,0 +1,180 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
// This file contains function implementations for serializing and de-serializing
// various eBPF structures to/from ebpf_operation*_request/response structures.
#include "ebpf_serialize.h"
void
ebpf_map_information_array_free(uint16_t map_count, _In_count_(map_count) const ebpf_map_information_t* map_info)
{
uint16_t map_index;
for (map_index = 0; map_index < map_count; map_index++) {
ebpf_free(map_info[map_index].pin_path);
}
ebpf_free((void*)map_info);
}
ebpf_result_t
ebpf_serialize_core_map_information_array(
uint16_t map_count,
_In_count_(map_count) const ebpf_core_map_information_t* map_info,
_Out_writes_bytes_to_(output_buffer_length, *serialized_data_length) uint8_t* output_buffer,
size_t output_buffer_length,
_Out_ size_t* serialized_data_length,
_Out_ size_t* required_length)
{
ebpf_result_t result = EBPF_SUCCESS;
uint16_t map_index;
uint8_t* current = NULL;
*serialized_data_length = 0;
// Compute required length for serialized array of map information objects.
*required_length = 0;
for (map_index = 0; map_index < map_count; map_index++) {
// Increment required_length by EBPF_OFFSET_OF(ebpf_serialized_map_information_t, pin_path).
result = ebpf_safe_size_t_add(
*required_length, EBPF_OFFSET_OF(ebpf_serialized_map_information_t, pin_path), required_length);
if (result != EBPF_SUCCESS)
goto Exit;
// Increment required_length by map_info[map_index].pin_path.length.
result = ebpf_safe_size_t_add(*required_length, map_info[map_index].pin_path.length, required_length);
if (result != EBPF_SUCCESS)
goto Exit;
}
// Output buffer too small.
if (output_buffer_length < *required_length) {
result = EBPF_ERROR_INSUFFICIENT_BUFFER;
goto Exit;
}
*serialized_data_length = *required_length;
current = output_buffer;
for (map_index = 0; map_index < map_count; map_index++) {
size_t serialized_map_information_length;
const ebpf_core_map_information_t* source = &map_info[map_index];
ebpf_serialized_map_information_t* destination = (ebpf_serialized_map_information_t*)current;
// Compute required length for serialized map information.
result = ebpf_safe_size_t_add(
EBPF_OFFSET_OF(ebpf_serialized_map_information_t, pin_path),
source->pin_path.length,
&serialized_map_information_length);
if (result != EBPF_SUCCESS)
goto Exit;
// Copy the map definition fields.
destination->definition = source->definition;
// Set the length of the pin path.
destination->pin_path_length = (uint16_t)source->pin_path.length;
// Copy the pin path buffer.
memcpy(destination->pin_path, source->pin_path.value, source->pin_path.length);
// Move the output buffer current pointer.
current += serialized_map_information_length;
}
Exit:
return result;
}
ebpf_result_t
ebpf_deserialize_map_information_array(
size_t input_buffer_length,
_In_reads_bytes_(input_buffer_length) const uint8_t* input_buffer,
uint16_t map_count,
_Outptr_result_buffer_(map_count) ebpf_map_information_t** map_info)
{
ebpf_result_t result = EBPF_SUCCESS;
uint16_t map_index;
size_t out_map_size;
ebpf_map_information_t* out_map_info = NULL;
uint8_t* current;
size_t buffer_left;
// Allocate the output maps.
result = ebpf_safe_size_t_multiply(sizeof(ebpf_map_information_t), (size_t)map_count, &out_map_size);
if (result != EBPF_SUCCESS)
goto Exit;
out_map_info = (ebpf_map_information_t*)ebpf_allocate(out_map_size);
if (out_map_info == NULL) {
result = EBPF_NO_MEMORY;
goto Exit;
}
current = (uint8_t*)input_buffer;
buffer_left = input_buffer_length;
for (map_index = 0; map_index < map_count; map_index++) {
ebpf_serialized_map_information_t* source;
ebpf_map_information_t* destination;
size_t destination_pin_path_length;
// Check if sufficient input buffer remaining.
if (buffer_left < sizeof(ebpf_serialized_map_information_t)) {
result = EBPF_INVALID_ARGUMENT;
goto Exit;
}
source = (ebpf_serialized_map_information_t*)current;
destination = &out_map_info[map_index];
// Copy the map definition part.
destination->definition = source->definition;
// Advance the input buffer current pointer.
current += EBPF_OFFSET_OF(ebpf_serialized_map_information_t, pin_path);
// Adjust remaining input buffer length.
result = ebpf_safe_size_t_subtract(
buffer_left, EBPF_OFFSET_OF(ebpf_serialized_map_information_t, pin_path), &buffer_left);
if (result != EBPF_SUCCESS)
goto Exit;
// Check if sufficient input buffer remaining.
if (buffer_left < source->pin_path_length) {
result = EBPF_INVALID_ARGUMENT;
goto Exit;
}
if (source->pin_path_length > 0) {
// Allocate the buffer to hold the pin path in destination map information structure.
destination_pin_path_length = source->pin_path_length + 1;
if (result != EBPF_SUCCESS)
goto Exit;
destination->pin_path = ebpf_allocate(destination_pin_path_length);
if (destination->pin_path == NULL) {
result = EBPF_NO_MEMORY;
goto Exit;
}
// Copy the pin path.
memcpy(destination->pin_path, source->pin_path, source->pin_path_length);
// Advance the input buffer current pointer.
current += source->pin_path_length;
// Adjust remaining input buffer length.
result = ebpf_safe_size_t_subtract(buffer_left, source->pin_path_length, &buffer_left);
if (result != EBPF_SUCCESS)
goto Exit;
}
}
*map_info = out_map_info;
out_map_info = NULL;
Exit:
if (out_map_info != NULL)
ebpf_map_information_array_free(map_count, out_map_info);
return result;
}

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

@ -0,0 +1,89 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
// Data structures and functions for serializing and de-serializing eBPF structs
// between API and Execution Context.
#pragma once
#include "ebpf_platform.h"
#include "ebpf_core_structs.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief eBPF Core Map Information
*/
typedef struct _ebpf_core_map_information
{
ebpf_map_definition_t definition;
ebpf_utf8_string_t pin_path;
} ebpf_core_map_information_t;
/**
* @brief Serialized eBPF Map Information.
*/
typedef struct _ebpf_serialized_map_information
{
ebpf_map_definition_t definition;
uint16_t pin_path_length;
uint8_t pin_path[1];
} ebpf_serialized_map_information_t;
/**
* @brief Serialize array of ebpf_map_information_t onto output buffer.
*
* @param[in] map_count Length of input array of ebpf_core_map_information_t structs.
* @param[in] map_info Array of ebpf_map_information_t to serialize.
* @param[out] output_buffer Caller specified output buffer to write serialized data into.
* @param[in] output_buffer_length Output buffer length.
* @param[out] serialized_data_length Length of successfully serialized data.
* @param[out] required_length Length of buffer required to serialize input array.
*
* @retval EBPF_SUCCESS The serialization was successful.
* @retval EBPF_ERROR_INSUFFICIENT_BUFFER The output buffer is insufficient to store serialized data.
*/
ebpf_result_t
ebpf_serialize_core_map_information_array(
uint16_t map_count,
_In_count_(map_count) const ebpf_core_map_information_t* map_info,
_Out_writes_bytes_to_(output_buffer_length, *serialized_data_length) uint8_t* output_buffer,
size_t output_buffer_length,
_Out_ size_t* serialized_data_length,
_Out_ size_t* required_length);
/**
* @brief Deserialize input buffer to an array of ebpf_map_information_t.
*
* @param[in] input_buffer_length Input buffer length.
* @param[in] input_buffer Input buffer that will be de-serialized.
* @param[in] map_count Caller specified expected length of output array.
* @param[out] map_info Array of ebpf_map_information_t deserialized from input buffer.
*
* @retval EBPF_SUCCESS The de-serialization was successful.
* @retval EBPF_INVALID_ARGUMENT One or more input parameters are incorrect.
* @retval EBPF_NO_MEMORY Output array could not be allocated.
*/
ebpf_result_t
ebpf_deserialize_map_information_array(
size_t input_buffer_length,
_In_reads_bytes_(input_buffer_length) const uint8_t* input_buffer,
uint16_t map_count,
_Outptr_result_buffer_(map_count) ebpf_map_information_t** map_info);
/**
* @brief Helper Function to free array of ebpf_map_information_t allocated by
* ebpf_deserialize_map_information_array function.
*
* @param[in] map_count Length of array to be freed.
* @param[in] map_info Map to be freed.
*/
void
ebpf_map_information_array_free(uint16_t map_count, _In_count_(map_count) const ebpf_map_information_t* map_info);
#ifdef __cplusplus
}
#endif

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

@ -157,6 +157,12 @@ ebpf_safe_size_t_add(size_t augend, size_t addend, size_t* result)
return RtlSizeTAdd(augend, addend, result) == STATUS_SUCCESS ? EBPF_SUCCESS : EBPF_ERROR_ARITHMETIC_OVERFLOW;
}
ebpf_result_t
ebpf_safe_size_t_subtract(size_t minuend, size_t subtrahend, size_t* result)
{
return RtlSizeTSub(minuend, subtrahend, result) == STATUS_SUCCESS ? EBPF_SUCCESS : EBPF_ERROR_ARITHMETIC_OVERFLOW;
}
void
ebpf_lock_create(ebpf_lock_t* lock)
{

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

@ -44,6 +44,7 @@
<ClCompile Include="..\ebpf_object.c" />
<ClCompile Include="..\ebpf_pinning_table.c" />
<ClCompile Include="..\ebpf_program_types.c" />
<ClCompile Include="..\ebpf_serialize.c" />
<ClCompile Include="..\ebpf_trampoline.c" />
<ClCompile Include="ebpf_extension_kernel.c" />
<ClCompile Include="ebpf_handle_kernel.c" />
@ -55,6 +56,7 @@
<ClInclude Include="..\ebpf_object.h" />
<ClInclude Include="..\ebpf_pinning_table.h" />
<ClInclude Include="..\ebpf_platform.h" />
<ClInclude Include="..\ebpf_serialize.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="stdbool.h" />
<ClInclude Include="stdint.h" />
@ -199,7 +201,7 @@
<ClCompile>
<PreprocessorDefinitions>_DEBUG;WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions);_KRPCENV_;_NO_CRT_STDIO_INLINE=1</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\kernel;$(SolutionDir)libs\epoch;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)libs\execution_context;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\kernel;$(SolutionDir)libs\epoch;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Midl>
<PreprocessorDefinitions>_KRPCENV_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -208,7 +210,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;_KRPCENV_;%(PreprocessorDefinitions);_NO_CRT_STDIO_INLINE=1</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\kernel;$(SolutionDir)libs\epoch;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)libs\execution_context;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\kernel;$(SolutionDir)libs\epoch;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Midl>
<PreprocessorDefinitions>_KRPCENV_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -239,4 +241,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

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

@ -46,6 +46,9 @@
<ClCompile Include="..\ebpf_program_types.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ebpf_serialize.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\ebpf_epoch.h">
@ -72,6 +75,9 @@
<ClInclude Include="stdint.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ebpf_serialize.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\ebpf_program_types.acf">

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

@ -20,6 +20,7 @@
#include "ebpf_platform.h"
#include "ebpf_pinning_table.h"
#include "ebpf_program_types.h"
#include "ebpf_serialize.h"
#include "ebpf_xdp_program_data.h"
class _test_helper
@ -236,11 +237,10 @@ TEST_CASE("program_type_info", "[program_type_info]")
EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL,
{EBPF_ARGUMENT_TYPE_PTR_TO_MAP, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY}},
};
ebpf_context_descriptor_t context_descriptor{
sizeof(xdp_md_t),
EBPF_OFFSET_OF(xdp_md_t, data),
EBPF_OFFSET_OF(xdp_md_t, data_end),
EBPF_OFFSET_OF(xdp_md_t, data_meta)};
ebpf_context_descriptor_t context_descriptor{sizeof(xdp_md_t),
EBPF_OFFSET_OF(xdp_md_t, data),
EBPF_OFFSET_OF(xdp_md_t, data_end),
EBPF_OFFSET_OF(xdp_md_t, data_meta)};
ebpf_program_type_descriptor_t program_type{"xdp", &context_descriptor};
ebpf_program_information_t program_information{program_type, _countof(helper_functions), helper_functions};
ebpf_program_information_t* new_program_information = nullptr;
@ -311,4 +311,67 @@ TEST_CASE("memory_map_test", "[memory_map_test]")
memset(ebpf_memory_descriptor_get_base_address(memory_descriptor), 0xCC, 100);
REQUIRE(ebpf_protect_memory(memory_descriptor, EBPF_PAGE_PROTECT_READ_ONLY) == EBPF_SUCCESS);
ebpf_unmap_memory(memory_descriptor);
}
TEST_CASE("serialize_map_test", "[serialize_map_test]")
{
_test_helper test_helper;
const int map_count = 10;
ebpf_core_map_information_t core_map_info_array[map_count] = {};
std::string pin_path_prefix = "\\ebpf\\map\\";
std::vector<std::string> pin_paths;
size_t buffer_length = 0;
uint8_t* buffer = nullptr;
size_t required_length;
size_t serialized_length;
ebpf_map_information_t* map_info_array;
// Construct the array of ebpf_core_map_information_t to be serialized.
for (int i = 0; i < map_count; i++) {
pin_paths.push_back(pin_path_prefix + std::to_string(i));
}
for (int i = 0; i < map_count; i++) {
ebpf_core_map_information_t* map_info = &core_map_info_array[i];
map_info->definition.size = (i + 1) * 32;
map_info->definition.type = static_cast<ebpf_map_type_t>(i % (EBPF_MAP_TYPE_ARRAY + 1));
map_info->definition.key_size = i + 1;
map_info->definition.value_size = (i + 1) * (i + 1);
map_info->definition.max_entries = (i + 1) * 128;
map_info->pin_path.length = pin_paths[i].size();
map_info->pin_path.value = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(pin_paths[i].c_str()));
}
// Serialize.
ebpf_result_t result = ebpf_serialize_core_map_information_array(
map_count, core_map_info_array, buffer, buffer_length, &serialized_length, &required_length);
REQUIRE(result == EBPF_ERROR_INSUFFICIENT_BUFFER);
buffer = static_cast<uint8_t*>(calloc(required_length, 1));
buffer_length = required_length;
result = ebpf_serialize_core_map_information_array(
map_count, core_map_info_array, buffer, buffer_length, &serialized_length, &required_length);
REQUIRE(result == EBPF_SUCCESS);
// Deserialize.
result = ebpf_deserialize_map_information_array(serialized_length, buffer, map_count, &map_info_array);
REQUIRE(result == EBPF_SUCCESS);
// Verify de-serialized map info array matches input.
for (int i = 0; i < map_count; i++) {
ebpf_core_map_information_t* input_map_info = &core_map_info_array[i];
ebpf_map_information_t* map_info = &map_info_array[i];
REQUIRE(memcmp(&map_info->definition, &input_map_info->definition, sizeof(ebpf_map_definition_t)) == 0);
REQUIRE(strnlen_s(map_info->pin_path, EBPF_MAX_PIN_PATH_LENGTH) == input_map_info->pin_path.length);
REQUIRE(memcmp(map_info->pin_path, input_map_info->pin_path.value, input_map_info->pin_path.length) == 0);
}
// Free de-serialized map info array.
ebpf_map_information_array_free(map_count, map_info_array);
if (buffer != nullptr)
free(buffer);
}

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

@ -108,7 +108,12 @@ ebpf_get_code_integrity_state(ebpf_code_integrity_state_t* state)
void*
ebpf_allocate(size_t size)
{
return calloc(size, 1);
void* memory;
memory = calloc(size, 1);
if (memory != nullptr)
memset(memory, 0, size);
return memory;
}
void
@ -196,6 +201,12 @@ ebpf_safe_size_t_add(size_t augend, size_t addend, size_t* result)
return SUCCEEDED(SizeTAdd(augend, addend, result)) ? EBPF_SUCCESS : EBPF_ERROR_ARITHMETIC_OVERFLOW;
}
ebpf_result_t
ebpf_safe_size_t_subtract(size_t minuend, size_t subtrahend, size_t* result)
{
return SUCCEEDED(SizeTSub(minuend, subtrahend, result)) ? EBPF_SUCCESS : EBPF_ERROR_ARITHMETIC_OVERFLOW;
}
void
ebpf_lock_create(ebpf_lock_t* lock)
{

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

@ -28,6 +28,7 @@
<ClCompile Include="..\ebpf_object.c" />
<ClCompile Include="..\ebpf_pinning_table.c" />
<ClCompile Include="..\ebpf_program_types.c" />
<ClCompile Include="..\ebpf_serialize.c" />
<ClCompile Include="..\ebpf_trampoline.c" />
<ClCompile Include="ebpf_extension_user.c" />
<ClCompile Include="ebpf_handle_user.c" />
@ -166,8 +167,9 @@
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)libs\execution_context;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>
@ -185,7 +187,7 @@
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)libs\execution_context;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>

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

@ -49,6 +49,9 @@
<ClCompile Include="..\ebpf_program_types.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ebpf_serialize.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Midl Include="..\ebpf_program_types.idl">

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

@ -82,7 +82,7 @@
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
@ -135,6 +135,7 @@
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

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

@ -87,6 +87,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\ubpf;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)\external\ubpf\vm\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>

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

@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
#define CATCH_CONFIG_MAIN
#include <chrono>
#include <mutex>
#include <thread>
#include "api_test.h"
#include "catch2\catch.hpp"
#include "common_tests.h"
#include "service_helper.h"
namespace api_test {
#pragma warning(push)
#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
#include "../sample/ebpf.h"
#pragma warning(pop)
}; // namespace api_test
#define SAMPLE_PATH ""
#define EBPF_CORE_DRIVER_BINARY_NAME L"ebpfcore.sys"
#define EBPF_CORE_DRIVER_NAME L"ebpfcore"
static service_install_helper
_ebpf_core_driver_helper(EBPF_CORE_DRIVER_NAME, EBPF_CORE_DRIVER_BINARY_NAME, SERVICE_KERNEL_DRIVER);
TEST_CASE("pinned_map_enum", "[pinned_map_enum]")
{
REQUIRE(ebpf_api_initiate() == EBPF_SUCCESS);
ebpf_test_pinned_map_enum();
ebpf_api_terminate();
}

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

@ -0,0 +1,6 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
#pragma once
#include "ebpf_api.h"
#include "ebpf_result.h"

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

@ -0,0 +1,193 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: MIT
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props" Condition="Exists('..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{12161211-5463-4AA9-9B6E-552552B475DC}</ProjectGuid>
<RootNamespace>apitest</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\libs\common;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\libs\common;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="api_test.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ebpfapi\ebpfapi.vcxproj">
<Project>{75fe223a-3e45-4b0e-a2e8-04285e52e440}</Project>
</ProjectReference>
<ProjectReference Include="..\..\libs\service\service.vcxproj">
<Project>{af85c549-57cc-40a5-bdfc-dcf1998de80f}</Project>
</ProjectReference>
<ProjectReference Include="..\..\rpc_interface\rpc_interface.vcxproj">
<Project>{1423245d-0249-40fc-a077-ff7780acfe3f}</Project>
</ProjectReference>
<ProjectReference Include="..\libs\common\common_tests.vcxproj">
<Project>{3617528a-cb85-418b-82c1-e9cfc16755f6}</Project>
</ProjectReference>
<ProjectReference Include="..\libs\util\test_util.vcxproj">
<Project>{d6725f19-b9bf-435f-80f2-c5f3ef0f4b8f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="header.h" />
<ClInclude Include="rpc_client.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\packages\boost.1.75.0.0\build\boost.targets" Condition="Exists('..\..\packages\boost.1.75.0.0\build\boost.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\boost.1.75.0.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\boost.1.75.0.0\build\boost.targets'))" />
<Error Condition="!Exists('..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props'))" />
</Target>
</Project>

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

@ -124,8 +124,9 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)libs\api;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)rpc_interface;$(SolutionDir)external\ebpf-verifier\external;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\ebpfsvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)tests\libs\util;$(SolutionDir)libs\api;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)rpc_interface;$(SolutionDir)external\ebpf-verifier\external;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\ebpfsvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -140,8 +141,9 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libs\api;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)rpc_interface;$(SolutionDir)external\ebpf-verifier\external;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\ebpfsvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)tests\libs\util;$(SolutionDir)libs\api;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)rpc_interface;$(SolutionDir)external\ebpf-verifier\external;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\ebpfsvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
@ -155,7 +157,6 @@
<ClCompile Include="..\..\ebpfapi\rpc_client.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="platform.cpp" />
<ClCompile Include="service_helper.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\external\ebpf-verifier\build\ebpfverifier.vcxproj">
@ -179,6 +180,9 @@
<ProjectReference Include="..\..\rpc_interface\rpc_interface.vcxproj">
<Project>{1423245d-0249-40fc-a077-ff7780acfe3f}</Project>
</ProjectReference>
<ProjectReference Include="..\libs\util\test_util.vcxproj">
<Project>{d6725f19-b9bf-435f-80f2-c5f3ef0f4b8f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -186,7 +190,6 @@
<ItemGroup>
<ClInclude Include="..\..\libs\api\rpc_client.h" />
<ClInclude Include="header.h" />
<ClInclude Include="service_helper.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

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

@ -21,9 +21,6 @@
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="service_helper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\ebpfapi\rpc_client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -35,9 +32,6 @@
<ClInclude Include="header.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="service_helper.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\libs\api\rpc_client.h">
<Filter>Header Files</Filter>
</ClInclude>

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

@ -21,7 +21,7 @@
#define EBPF_SERVICE_BINARY_NAME L"ebpfsvc.exe"
#define EBPF_SERVICE_NAME L"ebpfsvc"
static service_install_helper _service_helper(EBPF_SERVICE_NAME, EBPF_SERVICE_BINARY_NAME);
static service_install_helper _service_helper(EBPF_SERVICE_NAME, EBPF_SERVICE_BINARY_NAME, SERVICE_WIN32_OWN_PROCESS);
static void
_get_program_byte_code_helper(const char* file_name, const char* section_name, ebpf_program_verify_info* info)

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

@ -11,6 +11,7 @@
#include <WinSock2.h>
#include "catch2\catch.hpp"
#include "common_tests.h"
#include "ebpf_api.h"
#include "ebpf_bind_program_data.h"
#include "ebpf_core.h"
@ -124,6 +125,9 @@ Fail:
case EBPF_ERROR_NO_MORE_KEYS:
SetLastError(ERROR_NO_MORE_ITEMS);
break;
case EBPF_ERROR_INSUFFICIENT_BUFFER:
SetLastError(ERROR_MORE_DATA);
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
break;
@ -659,3 +663,10 @@ TEST_CASE("enumerate_and_query_programs", "[enumerate_and_query_programs]")
REQUIRE(ebpf_api_get_next_program(program_handle, &program_handle) == EBPF_SUCCESS);
REQUIRE(program_handle == INVALID_HANDLE_VALUE);
}
TEST_CASE("pinned_map_enum", "[pinned_map_enum]")
{
_test_helper test_helper;
ebpf_test_pinned_map_enum();
}

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

@ -65,7 +65,7 @@
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<LinkIncremental>false</LinkIncremental>
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
@ -80,10 +80,11 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)libs\service;$(SolutionDir)rpc_interface;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\api;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)libs\service;$(SolutionDir)rpc_interface;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\api;$(SolutionDir)tests\libs\common;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -98,7 +99,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)libs\service;$(SolutionDir)rpc_interface;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\api;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)libs\service;$(SolutionDir)rpc_interface;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\api;$(SolutionDir)tests\libs\common;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
@ -135,6 +136,9 @@
<ProjectReference Include="..\..\libs\ubpf\user\ubpf_user.vcxproj">
<Project>{245f0ec7-1ebc-4d68-8b1f-f758ea9196ae}</Project>
</ProjectReference>
<ProjectReference Include="..\libs\common\common_tests.vcxproj">
<Project>{3617528a-cb85-418b-82c1-e9cfc16755f6}</Project>
</ProjectReference>
<ProjectReference Include="..\sample\sample.vcxproj">
<Project>{b4ad72e3-754e-40ca-9cea-d3f2c9170e51}</Project>
</ProjectReference>

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

@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
// Common test functions used by end to end and component tests.
#include "catch2\catch.hpp"
#include "common_tests.h"
void
ebpf_test_pinned_map_enum()
{
uint32_t return_value;
ebpf_result_t result;
ebpf_handle_t map_handle;
const int pinned_map_count = 10;
std::string pin_path_prefix = "\\ebpf\\map\\";
uint16_t map_count = 0;
ebpf_map_information_t* map_info = nullptr;
REQUIRE(
(result = ebpf_api_create_map(EBPF_MAP_TYPE_ARRAY, sizeof(uint32_t), sizeof(uint64_t), 1024, 0, &map_handle)) ==
EBPF_SUCCESS);
if (result != EBPF_SUCCESS)
goto Exit;
for (int i = 0; i < pinned_map_count; i++) {
std::string pin_path = pin_path_prefix + std::to_string(i);
REQUIRE(
(return_value = ebpf_api_pin_object(
map_handle,
reinterpret_cast<const uint8_t*>(pin_path.c_str()),
static_cast<uint32_t>(pin_path.size()))) == EBPF_SUCCESS);
if (return_value != ERROR_SUCCESS)
goto Exit;
}
REQUIRE((result = ebpf_api_get_pinned_map_info(&map_count, &map_info)) == EBPF_SUCCESS);
if (result != EBPF_SUCCESS)
goto Exit;
REQUIRE(map_count == pinned_map_count);
for (int i = 0; i < pinned_map_count; i++) {
bool matched = false;
std::string pin_path = pin_path_prefix + std::to_string(i);
REQUIRE((
matched =
(static_cast<uint16_t>(pin_path.size()) == strnlen_s(map_info[i].pin_path, EBPF_MAX_PIN_PATH_LENGTH))));
std::string temp(map_info[i].pin_path);
REQUIRE((matched = (temp == pin_path)));
if (!matched)
goto Exit;
// Unpin the object.
REQUIRE(
(return_value = ebpf_api_unpin_object(
reinterpret_cast<const uint8_t*>(pin_path.c_str()), static_cast<uint16_t>(pin_path.size()))) ==
ERROR_SUCCESS);
}
Exit:
ebpf_api_close_handle(map_handle);
ebpf_api_map_info_free(map_count, map_info);
map_count = 0;
map_info = nullptr;
}

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

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
// Common test functions used by end to end and component tests.
#pragma once
#include <windows.h>
#include "ebpf_api.h"
#include "ebpf_result.h"
void
ebpf_test_pinned_map_enum();

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

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: MIT
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props" Condition="Exists('..\..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{3617528a-cb85-418b-82c1-e9cfc16755f6}</ProjectGuid>
<RootNamespace>common_tests</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)tests\util;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)tests\util;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="common_tests.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\packages\boost.1.75.0.0\build\boost.targets" Condition="Exists('..\..\..\packages\boost.1.75.0.0\build\boost.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\boost.1.75.0.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\boost.1.75.0.0\build\boost.targets'))" />
<Error Condition="!Exists('..\..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props'))" />
</Target>
</Project>

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

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

@ -37,19 +37,19 @@ QueryService:
// Install the service
service_handle = CreateService(
scm_handle, // SCM database
service_name.c_str(), // name of service
service_name.c_str(), // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
file_path, // path to service's binary
nullptr, // no load ordering group
nullptr, // no tag identifier
nullptr, // no dependencies
nullptr, // LocalSystem account
nullptr); // no password
scm_handle, // SCM database
service_name.c_str(), // name of service
service_name.c_str(), // service name to display
SERVICE_ALL_ACCESS, // desired access
service_type, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
file_path, // path to service's binary
nullptr, // no load ordering group
nullptr, // no tag identifier
nullptr, // no dependencies
nullptr, // LocalSystem account
nullptr); // no password
if (service_handle == nullptr) {
error = GetLastError();

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

@ -7,9 +7,9 @@
class service_install_helper
{
public:
service_install_helper(std::wstring _service_name, std::wstring _binary_name)
: service_name(_service_name), binary_name(_binary_name), service_handle(nullptr), scm_handle(nullptr),
already_installed(false), initialized(false)
service_install_helper(std::wstring _service_name, std::wstring _binary_name, DWORD _service_type)
: service_name(_service_name), binary_name(_binary_name), service_type(_service_type), service_handle(nullptr),
scm_handle(nullptr), already_installed(false), initialized(false)
{
initialize();
}
@ -32,6 +32,8 @@ class service_install_helper
std::wstring binary_name;
SC_HANDLE service_handle;
SC_HANDLE scm_handle;
DWORD service_type;
bool already_installed;
bool initialized;
};


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

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: MIT
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="service_helper.cpp" />
<ClInclude Include="service_helper.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{d6725f19-b9bf-435f-80f2-c5f3ef0f4b8f}</ProjectGuid>
<RootNamespace>testutil</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libs\execution_context;$(SolutionDir)include;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>