First string functions for ebpf general helpers. (#3780)

* Initial progress on function implementations.

* Moved code.

* Updated kernel project.

* Working on parallel user and kernel mode versions.

* Work in Progress.

* Added tests, added a lot.

* Cleaned up test code some, still doesn't build.

* Re-enabled some tests.

* Got a working set of tests, now to figure out what to do with this in the interim.

* Removing as-yet-unimplemented functions for now.

* Fixed a name.

* Doxygen fixes. Also removed a function header that'll be needed another time.

* Got down to one source file, got a build working in user mode.

* Renamed string_opts to ebpf_strings

* Corrected build issues, removed other extraneous comments.

* Fixed the test selection name, and suppressed an analysis error in a Windows header.

---------

Co-authored-by: Ben Lewis (REDMOND) <Ben.Lewis@microsoft.com>
This commit is contained in:
Ben Lewis 2024-08-27 13:55:55 -07:00 коммит произвёл GitHub
Родитель 8c838d1ab5
Коммит 71759c0abc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
12 изменённых файлов: 282 добавлений и 15 удалений

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

@ -419,6 +419,52 @@ EBPF_HELPER(int64_t, bpf_get_socket_cookie, (const void* ctx));
#define bpf_get_socket_cookie ((bpf_get_socket_cookie_t)BPF_FUNC_get_socket_cookie)
#endif
/**
* @brief Copy a string into a buffer, of a fixed size.
*
* @param[in] dest Destination buffer.
* @param[in] dest_size Size of the destination buffer.
* @param[in] src Source string.
* @param[in] count Upper limit on bytes to copy.
*
* @retval 0 The operation was successful.
* @retval -ERANGE The destination buffer isn't large enough for the string being copied.
*/
EBPF_HELPER(int, bpf_strncpy_s, (char* dest, size_t dest_size, const char* src, size_t count));
#ifndef __doxygen
#define bpf_strncpy_s ((bpf_strncpy_s_t)BPF_FUNC_strncpy_s)
#endif
/**
* @brief Concatenate a string to an existing buffer, up to a certain number of characters.
*
* @param[in,out] dest Destination buffer.
* @param[in] dest_size Size of the destination buffer.
* @param[in] src String to append to the contents of dest.
* @param[in] count Upper limit on the characters to append to dest.
*
* @retval 0 Concatenation was successful.
* @retval <0 Error code on failure, depending on the error.
*/
EBPF_HELPER(int, bpf_strncat_s, (char* dest, size_t dest_size, const char* src, size_t count));
#ifndef __doxygen
#define bpf_strncat_s ((bpf_strncat_s_t)BPF_FUNC_strncat_s)
#endif
/**
* @brief Find the length of a string, up to a certain number of characters.
*
* @param[in] str Buffer containing one or more null-terminated strings.
* @param[in] str_size Buffer length.
*
* @returns The length of the first string encountered in the str buffer. If str[0] is the null terminator, or str
* itself is null, returns 0. If there is no null terminator in the first str_size bytes, returns str_size.
*/
EBPF_HELPER(size_t, bpf_strnlen_s, (const char* str, size_t str_size));
#ifndef __doxygen
#define bpf_strnlen_s ((bpf_strnlen_s_t)BPF_FUNC_strnlen_s)
#endif
#if __clang__
#define memcpy(dest, src, dest_size) bpf_memcpy(dest, dest_size, src, dest_size)
#define memcmp(mem1, mem2, mem1_size) bpf_memcmp(mem1, mem1_size, mem2, mem1_size)

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

@ -161,6 +161,9 @@ typedef enum
BPF_FUNC_memset = 24, ///< \ref bpf_memset
BPF_FUNC_memmove = 25, ///< \ref bpf_memmove
BPF_FUNC_get_socket_cookie = 26, ///< \ref bpf_get_socket_cookie
BPF_FUNC_strncpy_s = 27, ///< \ref bpf_strncpy_s
BPF_FUNC_strncat_s = 28, ///< \ref bpf_strncat_s
BPF_FUNC_strnlen_s = 29, ///< \ref bpf_strnlen_s
} ebpf_helper_id_t;
// Cross-platform BPF program types.

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

@ -16,9 +16,11 @@
#include "ebpf_random.h"
#include "ebpf_serialize.h"
#include "ebpf_state.h"
#include "ebpf_strings.h"
#include "ebpf_tracelog.h"
#include <errno.h>
#include <stdlib.h>
const NPI_MODULEID ebpf_general_helper_function_module_id = {
sizeof(ebpf_general_helper_function_module_id),
@ -139,6 +141,9 @@ static const void* _ebpf_general_helpers[] = {
(void*)&_ebpf_core_memmove,
// No default implementation of bpf_get_socket_cookie
(void*)NULL, // bpf_get_socket_cookie
(void*)&_ebpf_core_strncpy_s,
(void*)&_ebpf_core_strncat_s,
(void*)&_ebpf_core_strlen_s,
};
static const ebpf_helper_function_addresses_t _ebpf_global_helper_function_dispatch_table = {

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

@ -169,6 +169,34 @@ ebpf_helper_function_prototype_t ebpf_core_helper_function_prototype_array[] = {
"bpf_get_socket_cookie",
EBPF_RETURN_TYPE_INTEGER,
{EBPF_ARGUMENT_TYPE_PTR_TO_CTX}},
{EBPF_HELPER_FUNCTION_PROTOTYPE_HEADER,
BPF_FUNC_strncpy_s,
"bpf_strncpy_s",
EBPF_RETURN_TYPE_INTEGER,
{
EBPF_ARGUMENT_TYPE_PTR_TO_WRITABLE_MEM,
EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO,
EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM,
EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO,
}},
{EBPF_HELPER_FUNCTION_PROTOTYPE_HEADER,
BPF_FUNC_strncat_s,
"bpf_strncat_s",
EBPF_RETURN_TYPE_INTEGER,
{
EBPF_ARGUMENT_TYPE_PTR_TO_WRITABLE_MEM,
EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO,
EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM,
EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO,
}},
{EBPF_HELPER_FUNCTION_PROTOTYPE_HEADER,
BPF_FUNC_strnlen_s,
"bpf_strnlen_s",
EBPF_RETURN_TYPE_INTEGER,
{
EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM,
EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO,
}},
};
#ifdef __cplusplus

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

@ -0,0 +1,43 @@
// Copyright (c) eBPF for Windows contributors
// SPDX-License-Identifier: MIT
#include <ebpf_strings.h>
#include <ntstatus.h>
#pragma warning(push)
#pragma warning(disable : 28196) // There's a bad annotation in ntstrsafe.h that fails to validate
#include <ntstrsafe.h>
#pragma warning(pop)
errno_t
_ebpf_core_strncpy_s(
_Out_writes_(dest_size) char* dest, size_t dest_size, _In_reads_(count) const char* src, size_t count)
{
return RtlStringCbCopyNExA(dest, dest_size, src, count, NULL, NULL, STRSAFE_FILL_BEHIND_NULL | 0);
}
errno_t
_ebpf_core_strncat_s(
_Out_writes_(dest_size) char* dest, size_t dest_size, _In_reads_(count) const char* src, size_t count)
{
return RtlStringCbCatNExA(dest, dest_size, src, count, NULL, NULL, STRSAFE_FILL_BEHIND_NULL | 0);
}
size_t
_ebpf_core_strlen_s(_In_reads_(str_size) const char* str, size_t str_size)
{
size_t length = 0;
NTSTATUS Status = RtlStringCbLengthA(str, str_size, &length);
if (NT_ERROR(Status)) {
if (str == NULL) {
// Null pointer: return 0.
return 0;
}
// no null found; match the behavior of strlen_s and return the buffer length.
return str_size;
}
return length;
}

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

@ -0,0 +1,17 @@
// Copyright (c) eBPF for Windows contributors
// SPDX-License-Identifier: MIT
#pragma once
#include <errno.h>
#include <stdint.h>
errno_t
_ebpf_core_strncpy_s(
_Out_writes_(dest_size) char* dest, size_t dest_size, _In_reads_(count) const char* src, size_t count);
errno_t
_ebpf_core_strncat_s(
_Out_writes_(dest_size) char* dest, size_t dest_size, _In_reads_(count) const char* src, size_t count);
size_t
_ebpf_core_strlen_s(_In_reads_(str_size) const char* str, size_t str_size);

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

@ -73,6 +73,7 @@
<ClCompile Include="..\ebpf_maps.c" />
<ClCompile Include="..\ebpf_native.c" />
<ClCompile Include="..\ebpf_program.c" />
<ClCompile Include="..\ebpf_strings.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\ebpf_core.h" />
@ -81,6 +82,7 @@
<ClInclude Include="..\ebpf_native.h" />
<ClInclude Include="..\ebpf_program.h" />
<ClInclude Include="..\ebpf_protocol.h" />
<ClInclude Include="..\ebpf_strings.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
@ -153,21 +155,21 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions);_NO_CRT_STDIO_INLINE=1</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4201;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NativeOnlyDebug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions);_NO_CRT_STDIO_INLINE=1</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4201;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='FuzzerDebug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions);_NO_CRT_STDIO_INLINE=1</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4201;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Lib>
@ -177,14 +179,14 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions);_NO_CRT_STDIO_INLINE=1;NDEBUG;</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4201;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NativeOnlyRelease|x64'">
<ClCompile>
<PreprocessorDefinitions>WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP;WINAPI_PARTITION_DESKTOP=1;WINAPI_PARTITION_SYSTEM=1;WINAPI_PARTITION_APP=1;WINAPI_PARTITION_PC_APP=1;%(PreprocessorDefinitions);_NO_CRT_STDIO_INLINE=1;NDEBUG;</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\kernel;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\kernel;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)external\usersim\cxplat\inc\winkernel;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4201;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>

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

@ -15,4 +15,8 @@
// add headers that you want to pre-compile here
#include "framework.h"
#include <Ntstrsafe.h>
#define StringCbCopyNExA RtlStringCbCopyNExA
#endif // PCH_H

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

@ -33,6 +33,7 @@
<ClCompile Include="..\ebpf_maps.c" />
<ClCompile Include="..\ebpf_native.c" />
<ClCompile Include="..\ebpf_program.c" />
<ClCompile Include="..\ebpf_strings.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\ebpf_core.h" />
@ -41,6 +42,7 @@
<ClInclude Include="..\ebpf_native.h" />
<ClInclude Include="..\ebpf_program.h" />
<ClInclude Include="..\ebpf_protocol.h" />
<ClInclude Include="..\ebpf_strings.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
@ -119,11 +121,11 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_LIB;_AMD64_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>
@ -133,11 +135,11 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NativeOnlyDebug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_LIB;_AMD64_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>
@ -147,11 +149,11 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='FuzzerDebug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_LIB;_AMD64_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>
@ -164,11 +166,11 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_LIB;_AMD64_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>
@ -180,11 +182,11 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NativeOnlyRelease|x64'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_LIB;_AMD64_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\runtime\user;$(SolutionDir)libs\runtime;$(SolutionDir)libs\shared\user;$(SolutionDir)libs\shared;$(SolutionDir)external\usersim\inc;$(SolutionDir)external\usersim\cxplat\inc\winuser;$(SolutionDir)external\usersim\cxplat\inc;$(SolutionDir)\external\ubpf\vm\inc;$(SolutionDir)\external\ubpf\vm;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)\external\ubpf\build\vm;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>

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

@ -5,3 +5,5 @@
// add headers that you want to pre-compile here
#include "framework.h"
#include <strsafe.h>

73
tests/sample/strings.c Normal file
Просмотреть файл

@ -0,0 +1,73 @@
// Copyright (c) eBPF for Windows contributors
// SPDX-License-Identifier: MIT
// Whenever this sample program changes, bpf2c_tests will fail unless the
// expected files in tests\bpf2c_tests\expected are updated. The following
// script can be used to regenerate the expected files:
// generate_expected_bpf2c_output.ps1
//
// Usage:
// .\scripts\generate_expected_bpf2c_output.ps1 <build_output_path>
// Example:
// .\scripts\generate_expected_bpf2c_output.ps1 .\x64\Debug\
#include "bpf_helpers.h"
#include "ebpf_nethooks.h"
// The following line is optional, but is used to verify
// that the BindMonitor prototype is correct or the compiler
// would complain when the function is actually defined below.
bind_hook_t StringOpsTest;
SEC("bind")
bind_action_t
StringOpsTest(bind_md_t* ctx)
{
char buffer[20] = {};
char test_str_1[6] = "alpha";
char test_str_2[5] = "alfa";
char test_buffer[] = {'a', 'l', 'p', 'h', 'a', 0, 'b', 'r', 'a', 'v', 'o', 0};
char null_str = 0;
if (bpf_strnlen_s(&null_str, 0) != 0) {
return 1;
}
if (bpf_strnlen_s(buffer, 20) != 0) {
return 2;
}
if (bpf_strnlen_s(test_str_1, 6) != 5) {
return 3;
}
if (bpf_strnlen_s(test_buffer, sizeof(test_buffer)) != 5) {
return 4;
}
if (bpf_strncpy_s(buffer, 20, test_str_1, 6) != 0) {
return 5;
}
// Test that the first 6 bytes of buffer match the whole 6 bytes of test_str_1, including the
// null terminators.
if (bpf_memcmp(buffer, 6, test_str_1, 6) != 0) {
return 6;
}
if (bpf_strncat_s(buffer, 20, test_str_2, 5) != 0) {
return 7;
}
// length: 10
char concat_buffer_state[] = "alphaalfa";
// Test that the first 10 bytes of buffer match the expected state of concatenating those two
// strings, including a null terminator in position 10.
if (bpf_memcmp(buffer, 10, concat_buffer_state, 10) != 0) {
return 8;
}
return 0;
}

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

@ -3767,7 +3767,49 @@ _utility_test(ebpf_execution_type_t execution_type)
result = bpf_link__destroy(link.release());
REQUIRE(result == 0);
bpf_object__close(process_object);
}
DECLARE_ALL_TEST_CASES("utility_test", "[libbf]", _utility_test);
static void
_strings_test(ebpf_execution_type_t execution_type)
{
_test_helper_end_to_end test_helper;
const char dll_name[] = "strings_um.dll";
const char obj_name[] = "strings.o";
test_helper.initialize();
single_instance_hook_t hook(EBPF_PROGRAM_TYPE_BIND, EBPF_ATTACH_TYPE_BIND);
REQUIRE(hook.initialize() == EBPF_SUCCESS);
program_info_provider_t sample_program_info;
REQUIRE(sample_program_info.initialize(EBPF_PROGRAM_TYPE_BIND) == EBPF_SUCCESS);
const char* file_name = (execution_type == EBPF_EXECUTION_NATIVE ? dll_name : obj_name);
struct bpf_object* process_object = bpf_object__open(file_name);
REQUIRE(process_object != nullptr);
// Load the program(s).
REQUIRE(bpf_object__load(process_object) == 0);
struct bpf_program* string_caller = bpf_object__find_program_by_name(process_object, "StringOpsTest");
REQUIRE(string_caller != nullptr);
bpf_link_ptr string_link(bpf_program__attach(string_caller));
REQUIRE(string_link != nullptr);
// Now run the ebpf program.
INITIALIZE_BIND_CONTEXT
ctx->operation = BIND_OPERATION_BIND;
uint32_t result{};
REQUIRE(hook.fire(ctx, &result) == EBPF_SUCCESS);
REQUIRE(result == 0);
result = bpf_link__destroy(string_link.release());
REQUIRE(result == 0);
bpf_object__close(process_object);
}
DECLARE_ALL_TEST_CASES("strings_test", "[libbpf]", _strings_test);