diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/Datadog.Trace.ClrProfiler.Native.vcxproj b/shared/src/Datadog.Trace.ClrProfiler.Native/Datadog.Trace.ClrProfiler.Native.vcxproj index d8c5387e915c..f62beeba0d52 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/Datadog.Trace.ClrProfiler.Native.vcxproj +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/Datadog.Trace.ClrProfiler.Native.vcxproj @@ -158,11 +158,11 @@ Level3 true - WIN32;X86;BIT86;_DEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions) + BUILD_WITH_WORKLOAD_SELECTION;WIN32;X86;BIT86;_DEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions) true MultiThreadedDebug stdcpp20 - $(LIB_INCLUDES);$(SHARED-LIB-INCLUDES);%(AdditionalIncludeDirectories) + $(LIB_INCLUDES);$(SHARED-LIB-INCLUDES);$(SHARED-LIB-PATH)\libpolicies\x86\libpolicies\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) $(ENABLE_MULTIPROCESSOR_COMPILATION) true @@ -172,7 +172,7 @@ true .\Datadog.Trace.ClrProfiler.Native.def false - Rpcrt4.lib;%(AdditionalDependencies) + Rpcrt4.lib;$(SHARED-LIB-PATH)\libpolicies\x86\libpolicies\lib\policies.lib;%(AdditionalDependencies) @@ -187,11 +187,11 @@ true Speed true - WIN32;X86;BIT86;NDEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions) + BUILD_WITH_WORKLOAD_SELECTION;WIN32;X86;BIT86;NDEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions) true stdcpp20 NotUsing - $(LIB_INCLUDES);$(SHARED-LIB-INCLUDES);%(AdditionalIncludeDirectories) + $(LIB_INCLUDES);$(SHARED-LIB-INCLUDES);$(SHARED-LIB-PATH)\libpolicies\x86\libpolicies\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) $(ENABLE_MULTIPROCESSOR_COMPILATION) true @@ -203,7 +203,7 @@ true .\Datadog.Trace.ClrProfiler.Native.def false - Rpcrt4.lib;%(AdditionalDependencies) + Rpcrt4.lib;$(SHARED-LIB-PATH)\libpolicies\x86\libpolicies\lib\policies.lib;%(AdditionalDependencies) @@ -215,8 +215,8 @@ true stdcpp20 true - BIT64;AMD64;_DEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions) - $(SHARED-LIB-INCLUDES);$(LIB_INCLUDES);%(AdditionalIncludeDirectories) + BUILD_WITH_WORKLOAD_SELECTION;BIT64;AMD64;_DEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions) + $(SHARED-LIB-INCLUDES);$(LIB_INCLUDES);$(SHARED-LIB-PATH)\libpolicies\x64\libpolicies\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) $(ENABLE_MULTIPROCESSOR_COMPILATION) true @@ -226,7 +226,7 @@ true .\Datadog.Trace.ClrProfiler.Native.def false - Rpcrt4.lib;%(AdditionalDependencies) + Rpcrt4.lib;$(SHARED-LIB-PATH)\libpolicies\x64\libpolicies\lib\policies.lib;%(AdditionalDependencies) @@ -243,10 +243,10 @@ stdcpp20 $(ENABLE_MULTIPROCESSOR_COMPILATION) true - $(LIB_INCLUDES);$(SHARED-LIB-INCLUDES);%(AdditionalIncludeDirectories) + $(LIB_INCLUDES);$(SHARED-LIB-INCLUDES);$(SHARED-LIB-PATH)\libpolicies\x64\libpolicies\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) true - BIT64;AMD64;NDEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions) + BUILD_WITH_WORKLOAD_SELECTION;BIT64;AMD64;NDEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions) Windows @@ -255,7 +255,7 @@ true .\Datadog.Trace.ClrProfiler.Native.def false - Rpcrt4.lib;%(AdditionalDependencies) + Rpcrt4.lib;$(SHARED-LIB-PATH)\libpolicies\x64\libpolicies\lib\policies.lib;%(AdditionalDependencies) @@ -337,6 +337,9 @@ + + + @@ -350,6 +353,7 @@ + @@ -376,4 +380,4 @@ - \ No newline at end of file + diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp index e77e5375082d..f6cab2528f2b 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp @@ -5,6 +5,7 @@ #include "../../../shared/src/native-src/pal.h" #include "environment.h" #include "single_step_guard_rails.h" +#include "workload_selection.h" #include "instrumented_assembly_generator/instrumented_assembly_generator_cor_profiler_function_control.h" #include "instrumented_assembly_generator/instrumented_assembly_generator_cor_profiler_info.h" #include "instrumented_assembly_generator/instrumented_assembly_generator_helper.h" @@ -316,6 +317,25 @@ namespace datadog::shared::nativeloader return E_FAIL; } + if (IsSingleStepInstrumentation()) + { + Log::Info("CorProfiler::Initialize: Evaluating workload selection."); + + if (auto policies = readPolicies(); policies) + { + WSTRING application_pool; + if (auto maybe_application_pool = GetApplicationPool()) + { + application_pool = std::move(*maybe_application_pool); + } + + if (isWorkloadAllowed(process_name, tokenized_command_line, application_pool, *policies, IsRunningOnIIS()) == false) + { + return CORPROF_E_PROFILER_CANCEL_ACTIVATION; + } + } + } + // Guard rails have all passed, so we enable (and flush) logs if necessary Log::EnableAutoFlush(); @@ -1325,4 +1345,4 @@ namespace datadog::shared::nativeloader return m_this->m_runtimeIdStore.Get(appDomain).c_str(); } -} // namespace datadog::shared::nativeloader \ No newline at end of file +} // namespace datadog::shared::nativeloader diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/util.h b/shared/src/Datadog.Trace.ClrProfiler.Native/util.h index d8af9ae90d0b..ae120af393fa 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/util.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/util.h @@ -3,12 +3,15 @@ #ifdef _WIN32 #include EXTERN_C IMAGE_DOS_HEADER __ImageBase; -#define HINST_THISCOMPONENT ((HINSTANCE) &__ImageBase) +#define HINST_THISCOMPONENT ((HINSTANCE) & __ImageBase) #else #define _GNU_SOURCE #include #endif +#include +#include + #include "../../../shared/src/native-src/dd_filesystem.hpp" // namespace fs is an alias defined in "dd_filesystem.hpp" #include "../../../shared/src/native-src/pal.h" @@ -26,13 +29,26 @@ static fs::path GetCurrentModuleFolderPath() } #else Dl_info info; - if (dladdr((void*)GetCurrentModuleFolderPath, &info)) + if (dladdr((void*) GetCurrentModuleFolderPath, &info)) { return fs::path(info.dli_fname).remove_filename(); } #endif return {}; } +#ifdef _WIN32 +static fs::path GetPoliciesPath() +{ + fs::path program_data_path = shared::GetEnvironmentValue(WStr("PROGRAMDATA")); + + if (program_data_path.empty()) + { + program_data_path = WStr(R"(C:\ProgramData)"); + } + + return program_data_path / "Datadog" / "user-wls-policy.bin"; +} +#endif static ::shared::WSTRING GetDatadogLogsDirectoryPath() { @@ -78,12 +94,44 @@ static fs::path GetConfigurationFilePath() return GetCurrentModuleFolderPath() / conf_filename; } +inline bool IsSingleStepInstrumentation() +{ + const auto isSingleStepVariable = ::shared::GetEnvironmentValue(environment::single_step_instrumentation_enabled); + return !isSingleStepVariable.empty(); +} + inline bool IsRunningOnIIS() { const auto& process_name = ::shared::GetCurrentProcessName(); return process_name == WStr("w3wp.exe") || process_name == WStr("iisexpress.exe"); } +inline std::optional<::shared::WSTRING> GetApplicationPool() +{ + if (const auto& app_pool_id = ::shared::GetEnvironmentValue(environment::azure_app_services_app_pool_id); + !app_pool_id.empty()) + { + return app_pool_id; + } + + // Try to infer the Application Pool from the command line. w3wp.exe (IIS Worker Process) + // can be started with an Application Pool by using `-ap` argument. + const auto [_, argv] = ::shared::GetCurrentProcessCommandLine(); + auto it = std::find(argv.cbegin(), argv.cend(), WStr("-ap")); + if (it == argv.cend()) + { + return std::nullopt; + } + + it = std::next(it); + if (it == argv.cend() || it->empty()) + { + return std::nullopt; + } + + return *it; +} + inline std::string GetCurrentOsArch(bool isRunningOnAlpine) { #if AMD64 @@ -137,4 +185,4 @@ inline std::string GetCurrentOsArch(bool isRunningOnAlpine) #else #error "currentOsArch not defined." #endif -} \ No newline at end of file +} diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection.h b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection.h new file mode 100644 index 000000000000..ce736466fccd --- /dev/null +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection.h @@ -0,0 +1,6 @@ +#pragma once +#ifdef BUILD_WITH_WORKLOAD_SELECTION +#include "workload_selection_impl.h" +#else +#include "workload_selection_noop.h" +#endif diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp new file mode 100644 index 000000000000..7914c10b4535 --- /dev/null +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp @@ -0,0 +1,144 @@ +#include "workload_selection_impl.h" + +#include "log.h" +#include "util.h" + +extern "C" +{ +#include
+#include + void _except_handler4_common(void) + { + } +} + +namespace datadog::shared::nativeloader +{ +namespace +{ + enum class InjectionStatus : uint8_t + { + ALLOW, + DENY, + UNKNOWN + }; + + InjectionStatus injection_status; + + plcs_errors onInjectionAllow(plcs_evaluation_result eval_result, char**, size_t, const char* policy, int) + { + if (injection_status != InjectionStatus::UNKNOWN) return PLCS_ESUCCESS; + + injection_status = (eval_result == PLCS_EVAL_RESULT_TRUE) ? InjectionStatus::ALLOW : InjectionStatus::UNKNOWN; + + return PLCS_ESUCCESS; + } + + plcs_errors onInjectionDeny(plcs_evaluation_result eval_result, char**, size_t, const char* policy, int) + { + if (injection_status != InjectionStatus::UNKNOWN) return PLCS_ESUCCESS; + + injection_status = (eval_result == PLCS_EVAL_RESULT_TRUE) ? InjectionStatus::DENY : InjectionStatus::UNKNOWN; + + return PLCS_ESUCCESS; + } + + std::string GetDotnetDll(const std::vector<::shared::WSTRING>& argv) + { + if (argv.size() < 2) + { + return ""; + } + + if (argv[0] != L"dotnet" && argv[0] != L"dotnet.exe") + { + return ""; + } + + auto dll_arg = argv[1]; + if (argv[1] == L"exec") + { + if (argv.size() <= 2) + { + return ""; + } + dll_arg = argv[2]; + } + + if (dll_arg.empty() || !dll_arg.ends_with(L".dll")) + { + return ""; + } + + auto dll_path = fs::path(::shared::ToString(dll_arg)); + return dll_path.filename().string(); + } + +} // namespace + +std::optional> readPolicies() +{ + const auto policies_file = GetPoliciesPath(); + + FILE* file = NULL; + fopen_s(&file, policies_file.string().c_str(), "rb"); + if (!file) + { + return std::nullopt; + } + + fseek(file, 0, SEEK_END); + const auto file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + std::vector buffer(file_size); + + const auto read_size = fread(buffer.data(), 1, file_size, file); + fclose(file); + + if (read_size != file_size) + { + return std::nullopt; + } + + return buffer; +} + +bool isWorkloadAllowed(const ::shared::WSTRING& process_name, const std::vector<::shared::WSTRING>& argv, + const ::shared::WSTRING& application_pool, const std::vector& policies, + const bool is_iis) +{ + const auto process_name_str = ::shared::ToString(process_name); + const auto application_pool_str = ::shared::ToString(application_pool); + + const auto dotnet_dll = GetDotnetDll(argv); + + plcs_eval_ctx_init(); + plcs_eval_ctx_set_str_eval_param(PLCS_STR_EVAL_RUNTIME_LANGUAGE, "dotnet"); + plcs_eval_ctx_set_str_eval_param(PLCS_STR_EVAL_PROCESS_EXE, process_name_str.c_str()); + plcs_eval_ctx_set_str_eval_param(PLCS_STR_EVAL_IIS_APPLICATION_POOL, application_pool_str.c_str()); + plcs_eval_ctx_set_str_eval_param(PLCS_STR_EVAL_RUNTIME_ENTRY_POINT_FILE, dotnet_dll.c_str()); + + plcs_eval_ctx_register_action(onInjectionDeny, PLCS_ACTION_INJECT_DENY); + plcs_eval_ctx_register_action(onInjectionAllow, PLCS_ACTION_INJECT_ALLOW); + + injection_status = InjectionStatus::UNKNOWN; + + if (auto res = plcs_evaluate_buffer(policies.data(), policies.size()); res != PLCS_ESUCCESS) + { + Log::Error(__func__, ": An error occured while evaluating workload selection policies (errno: ", res, ")"); + return true; + } + + // We enable or disable instrumentation depending on the context: + // - Windows IIS: instrumentation is ENABLED by default, only need to consider DENY rules. + // - .NET: instrumentation is DISABLED by default, only consider ALLOW rules. + if (is_iis) + { + return injection_status == InjectionStatus::DENY ? false : true; + } + + return injection_status == InjectionStatus::ALLOW; +} + +} // namespace datadog::shared::nativeloader diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h new file mode 100644 index 000000000000..3af28335f000 --- /dev/null +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h @@ -0,0 +1,53 @@ +#pragma once +#include "../../../shared/src/native-src/string.h" +#include +#include + +extern "C" +{ +#include
+#include
+} + +namespace datadog::shared::nativeloader +{ + +/// Reads the policy configuration from the system or a local source. +/// +/// This function attempts to load serialized policy data that controls +/// workload authorization or configuration rules. The policy data is +/// typically stored as a FlatBuffer or another binary format. +/// +/// @return +/// - A `std::optional>` containing the binary +/// policy data if available. +/// - `std::nullopt` if no valid policy data could be loaded. +std::optional> readPolicies(); + +/// Determines whether the specified workload is allowed to run under the current policies. +/// +/// This function evaluates the provided process information, arguments, +/// application pool, and policy data to decide if the workload should +/// be permitted to execute. The logic typically involves comparing +/// the workload metadata against preloaded security or configuration +/// policies. +/// +/// @param process_name The name of the process attempting to run (e.g., executable name). +/// +/// @param argv The command-line arguments associated with the process. +/// +/// @param application_pool The application pool or logical hosting environment associated with the workload (for +/// example, in IIS). +/// +/// @param policies A vector of bytes representing serialized policy data, typically loaded from `readPolicies()`. +/// +/// @param is_iis A boolean flag indicating whether the workload is running under IIS. +/// +/// @return +/// `true` if the workload is allowed according to the policies; +/// `false` otherwise. +bool isWorkloadAllowed(const ::shared::WSTRING& process_name, const std::vector<::shared::WSTRING>& argv, + const ::shared::WSTRING& application_pool, const std::vector& policies, + const bool is_iis); + +} // namespace datadog::shared::nativeloader diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h new file mode 100644 index 000000000000..a20d8f02cf2d --- /dev/null +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h @@ -0,0 +1,20 @@ +#pragma once +#include "../../../shared/src/native-src/string.h" +#include +#include + +namespace datadog::shared::nativeloader +{ + +inline std::optional> readPolicies() +{ + return std::nullopt; +} + +inline bool isWorkloadAllowed(const ::shared::WSTRING&, const std::vector<::shared::WSTRING>&, const ::shared::WSTRING&, + const std::vector&, const bool) +{ + return true; +} + +} // namespace datadog::shared::nativeloader diff --git a/shared/test/Datadog.Trace.ClrProfiler.Native.Tests/Datadog.Trace.ClrProfiler.Native.Tests.vcxproj b/shared/test/Datadog.Trace.ClrProfiler.Native.Tests/Datadog.Trace.ClrProfiler.Native.Tests.vcxproj index 9b6ee45a06d3..9ac182a698a9 100644 --- a/shared/test/Datadog.Trace.ClrProfiler.Native.Tests/Datadog.Trace.ClrProfiler.Native.Tests.vcxproj +++ b/shared/test/Datadog.Trace.ClrProfiler.Native.Tests/Datadog.Trace.ClrProfiler.Native.Tests.vcxproj @@ -145,16 +145,16 @@ Level3 true - WIN32;X86;BIT86;_DEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_CONSOLE;%(PreprocessorDefinitions) + BUILD_WITH_WORKLOAD_SELECTION;WIN32;X86;BIT86;_DEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug stdcpp20 - $(LIB_INCLUDES);%(AdditionalIncludeDirectories) + $(LIB_INCLUDES);$(SHARED-LIB-PATH)\libpolicies\x86\libpolicies\include;%(AdditionalIncludeDirectories) Console true - Rpcrt4.lib;..\..\src\Datadog.Trace.ClrProfiler.Native\obj\Debug\x86\*.obj;%(AdditionalDependencies) + Rpcrt4.lib;$(SHARED-LIB-PATH)\libpolicies\x86\libpolicies\lib\policies.lib;..\..\src\Datadog.Trace.ClrProfiler.Native\obj\Debug\x86\*.obj;%(AdditionalDependencies) @@ -163,34 +163,34 @@ true true true - WIN32;X86;BIT86;NDEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_CONSOLE;%(PreprocessorDefinitions) + BUILD_WITH_WORKLOAD_SELECTION;WIN32;X86;BIT86;NDEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreaded - $(LIB_INCLUDES);%(AdditionalIncludeDirectories) + $(LIB_INCLUDES);$(SHARED-LIB-PATH)\libpolicies\x86\libpolicies\include;%(AdditionalIncludeDirectories) Console true true true - Rpcrt4.lib;..\..\src\Datadog.Trace.ClrProfiler.Native\obj\Release\x86\*.obj;%(AdditionalDependencies) + Rpcrt4.lib;$(SHARED-LIB-PATH)\libpolicies\x86\libpolicies\lib\policies.lib;..\..\src\Datadog.Trace.ClrProfiler.Native\obj\Release\x86\*.obj;%(AdditionalDependencies) Level3 true - BIT64;AMD64;_DEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_CONSOLE;%(PreprocessorDefinitions) + BUILD_WITH_WORKLOAD_SELECTION;BIT64;AMD64;_DEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreadedDebug - $(LIB_INCLUDES);%(AdditionalIncludeDirectories) + $(LIB_INCLUDES);$(SHARED-LIB-PATH)\libpolicies\x64\libpolicies\include;%(AdditionalIncludeDirectories) Console true - Rpcrt4.lib;..\..\src\Datadog.Trace.ClrProfiler.Native\obj\Debug\x64\*.obj;%(AdditionalDependencies) + Rpcrt4.lib;$(SHARED-LIB-PATH)\libpolicies\x64\libpolicies\lib\policies.lib;..\..\src\Datadog.Trace.ClrProfiler.Native\obj\Debug\x64\*.obj;%(AdditionalDependencies) @@ -199,18 +199,18 @@ true true true - BIT64;AMD64;NDEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_CONSOLE;%(PreprocessorDefinitions) + BUILD_WITH_WORKLOAD_SELECTION;BIT64;AMD64;NDEBUG;DATADOGNATIVELOADER_EXPORTS;_WINDOWS;_USRDLL;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreaded - $(LIB_INCLUDES);%(AdditionalIncludeDirectories) + $(LIB_INCLUDES);$(SHARED-LIB-PATH)\libpolicies\x64\libpolicies\include;%(AdditionalIncludeDirectories) Console true true true - Rpcrt4.lib;..\..\src\Datadog.Trace.ClrProfiler.Native\obj\Release\x64\*.obj;%(AdditionalDependencies) + Rpcrt4.lib;$(SHARED-LIB-PATH)\libpolicies\x64\libpolicies\lib\policies.lib;..\..\src\Datadog.Trace.ClrProfiler.Native\obj\Release\x64\*.obj;%(AdditionalDependencies) @@ -256,6 +256,7 @@ + @@ -283,4 +284,4 @@ - \ No newline at end of file + diff --git a/shared/test/Datadog.Trace.ClrProfiler.Native.Tests/workload_selection_test.cpp b/shared/test/Datadog.Trace.ClrProfiler.Native.Tests/workload_selection_test.cpp new file mode 100644 index 000000000000..9ecbcdf2f876 --- /dev/null +++ b/shared/test/Datadog.Trace.ClrProfiler.Native.Tests/workload_selection_test.cpp @@ -0,0 +1,187 @@ +// #ifdef BUILD_WITH_WORKLOAD_SELECTION +#include "gtest/gtest.h" + +#include + +#include "../../src/Datadog.Trace.ClrProfiler.Native/workload_selection.h" + +using namespace datadog::shared::nativeloader; + +const std::vector<::shared::WSTRING> noarg{}; + +/* + [allow-only-java] + instrument = true + description = "Only instrument java runtime" + expression = "runtime.language:java" +*/ +const std::vector only_instrument_java = { + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0C, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x6C, 0x79, + 0x20, 0x69, 0x6E, 0x73, 0x74, 0x72, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x6A, 0x61, 0x76, 0x61, 0x20, 0x72, + 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x2D, 0x6F, 0x6E, 0x6C, 0x79, 0x2D, 0x6A, + 0x61, 0x76, 0x61, 0x00, 0xBC, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, + 0x00, 0x00, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x2D, 0x6F, 0x6E, 0x6C, 0x79, 0x2D, 0x6A, 0x61, 0x76, 0x61, 0x00, + 0x08, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x08, 0x00, 0x0F, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, 0x00, 0x43, 0x68, + 0x65, 0x63, 0x6B, 0x20, 0x72, 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6A, 0x61, 0x76, + 0x61, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x6A, 0x61, 0x76, 0x61, 0x00, 0x00, 0x00, 0x00}; + +/* + [allow-only-my-app-exe] + instrument = true + description = "Only instrument java runtime" + expression = "process.executable:my-app.exe OR dotnet.dll:my-app.dll" +*/ +const std::vector instrument_my_app = { + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x08, 0x00, + 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x6C, 0x79, 0x20, 0x69, 0x6E, 0x73, + 0x74, 0x72, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x6A, 0x61, 0x76, 0x61, 0x20, 0x72, 0x75, 0x6E, 0x74, 0x69, 0x6D, + 0x65, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x61, + 0x6C, 0x6C, 0x6F, 0x77, 0x2D, 0x6F, 0x6E, 0x6C, 0x79, 0x2D, 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2D, 0x65, 0x78, + 0x65, 0x00, 0x00, 0x00, 0x28, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0xBE, 0xFF, 0xFF, + 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x2D, 0x6F, 0x6E, 0x6C, 0x79, 0x2D, 0x6D, 0x79, + 0x2D, 0x61, 0x70, 0x70, 0x2D, 0x65, 0x78, 0x65, 0x00, 0x00, 0x00, 0x68, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x74, 0x00, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x9A, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00, 0x43, 0x68, 0x65, 0x63, 0x6B, 0x20, 0x70, 0x72, 0x6F, 0x63, 0x65, + 0x73, 0x73, 0x20, 0x44, 0x4C, 0x4C, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2E, 0x64, 0x6C, + 0x6C, 0x00, 0x92, 0xFF, 0xFF, 0xFF, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x6D, + 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x08, + 0x00, 0x0F, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x1B, 0x00, 0x00, 0x00, 0x43, 0x68, 0x65, 0x63, 0x6B, 0x20, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, + 0x20, 0x69, 0x73, 0x20, 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2E, 0x65, 0x78, 0x65, 0x00, 0x00, 0x00, 0x0A, 0x00, + 0x0C, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x04, 0x0A, 0x00, 0x00, 0x00, 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2E, 0x65, 0x78, 0x65, 0x00, 0x00}; + +TEST(WorkloadSelectionTest, EnableWhenPoliciesIsEmpty) +{ + EXPECT_TRUE(isWorkloadAllowed(L"foo.exe", noarg, L"", {}, false)); +} + +TEST(WorkloadSelectionTest, EnableWhenLibPoliciesReturnAnError) +{ + const bool is_iis = false; + const std::vector ill_formatted_policies{0, 1, 3, 4}; + EXPECT_TRUE(isWorkloadAllowed(L"bar.exe", noarg, L"", ill_formatted_policies, is_iis)); +} + +TEST(WorkloadSelectionTest, DenyWhenNoPoliciesMatch) +{ + const bool is_iis = false; + EXPECT_FALSE(isWorkloadAllowed(L"my-app.exe", noarg, L"", only_instrument_java, is_iis)); +} + +TEST(WorkloadSelectionTest, AllowWhenPoliciesMatch) +{ + const bool is_iis = false; + + // executable + EXPECT_TRUE(isWorkloadAllowed(L"my-app.exe", noarg, L"", instrument_my_app, is_iis)); + + // dotnet dll + EXPECT_TRUE( + isWorkloadAllowed(L"dotnet.exe", {L"dotnet.exe", L"/foo/bar/my-app.dll"}, L"", instrument_my_app, is_iis)); + EXPECT_TRUE( + isWorkloadAllowed(L"dotnet.exe", {L"dotnet.exe", L"exec", L"my-app.dll"}, L"", instrument_my_app, is_iis)); +} + +TEST(WorkloadSelectionTest, DenyWhenPoliciesMatchWithInstrumentationDisabled) +{ + /* + [disable-only-my-app-exe] + instrument = false + description = "Only instrument java runtime" + expression = "process.executable:my-app.exe OR dotnet.dll:my-app.dll" + */ + std::vector disable_instrumentation_on_my_app = { + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0C, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x6C, 0x79, + 0x20, 0x69, 0x6E, 0x73, 0x74, 0x72, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x6A, 0x61, 0x76, 0x61, 0x20, 0x72, + 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x2D, 0x6F, 0x6E, 0x6C, 0x79, 0x2D, 0x6D, + 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2D, 0x65, 0x78, 0x65, 0x00, 0x00, 0x00, 0x28, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0xBE, 0xFF, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x61, 0x6C, + 0x6C, 0x6F, 0x77, 0x2D, 0x6F, 0x6E, 0x6C, 0x79, 0x2D, 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2D, 0x65, 0x78, + 0x65, 0x00, 0x00, 0x00, 0x68, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, + 0x04, 0x00, 0x00, 0x00, 0x9A, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00, 0x43, 0x68, 0x65, 0x63, 0x6B, 0x20, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, + 0x73, 0x20, 0x44, 0x4C, 0x4C, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2E, 0x64, 0x6C, + 0x6C, 0x00, 0x92, 0xFF, 0xFF, 0xFF, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x0A, 0x00, 0x00, 0x00, + 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00, 0x07, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, + 0x10, 0x00, 0x08, 0x00, 0x0F, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0x00, 0x00, 0x00, 0x43, 0x68, 0x65, 0x63, 0x6B, 0x20, 0x70, 0x72, + 0x6F, 0x63, 0x65, 0x73, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, 0x2E, 0x65, 0x78, + 0x65, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x6D, 0x79, 0x2D, 0x61, 0x70, 0x70, + 0x2E, 0x65, 0x78, 0x65, 0x00, 0x00}; + + const bool is_iis = false; + EXPECT_FALSE(isWorkloadAllowed(L"my-app.exe", noarg, L"", disable_instrumentation_on_my_app, is_iis)); +} + +TEST(WorkloadSelectionTest, IIS_AllowWhenNoPoliciesMatch) +{ + const bool is_iis = true; + EXPECT_TRUE(isWorkloadAllowed(L"my-app.exe", noarg, L"", only_instrument_java, is_iis)); +} + +TEST(WorkloadSelectionTest, IIS_AllowWhenPoliciesMatchWithInstrumentationEnabled) +{ + const bool is_iis = true; + EXPECT_TRUE(isWorkloadAllowed(L"my-app.exe", noarg, L"", instrument_my_app, is_iis)); +} + +TEST(WorkloadSelectionTest, IIS_DenyWhenPoliciesMatchWithInstrumentationDisabled) +{ + std::vector disable_staging_app_pool = { + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0C, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x44, 0x69, 0x73, 0x61, + 0x62, 0x6C, 0x65, 0x20, 0x73, 0x74, 0x61, 0x67, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x70, 0x6F, 0x6F, 0x6C, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0F, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x2D, + 0x73, 0x74, 0x61, 0x67, 0x69, 0x6E, 0x67, 0x2D, 0x61, 0x70, 0x70, 0x2D, 0x70, 0x6F, 0x6F, 0x6C, 0x00, 0x00, + 0x00, 0x00, 0xB0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, + 0x10, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x2D, 0x73, 0x74, 0x61, 0x67, 0x69, 0x6E, 0x67, 0x2D, 0x61, 0x70, + 0x70, 0x2D, 0x70, 0x6F, 0x6F, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x0F, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x00, 0x43, 0x68, 0x65, 0x63, 0x6B, 0x20, 0x49, 0x49, 0x53, 0x20, + 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x70, 0x6F, 0x6F, 0x6C, 0x20, 0x69, + 0x73, 0x20, 0x73, 0x74, 0x61, 0x67, 0x69, 0x6E, 0x67, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x0B, 0x00, + 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x04, 0x07, 0x00, 0x00, 0x00, + 0x73, 0x74, 0x61, 0x67, 0x69, 0x6E, 0x67, 0x00}; + + const bool is_iis = true; + EXPECT_FALSE(isWorkloadAllowed(L"w3p.exe", noarg, L"staging", disable_staging_app_pool, is_iis)); +} + +// #endif diff --git a/tracer/build/_build/Build.Shared.Steps.cs b/tracer/build/_build/Build.Shared.Steps.cs index 5fab89e0495e..11aee28bb984 100644 --- a/tracer/build/_build/Build.Shared.Steps.cs +++ b/tracer/build/_build/Build.Shared.Steps.cs @@ -4,6 +4,7 @@ using Nuke.Common.IO; using System.Linq; using System.IO; +using System.Threading.Tasks; using DiffMatchPatch; using NativeValidation; using Nuke.Common.Tooling; @@ -32,8 +33,10 @@ partial class Build Target CompileNativeLoaderWindows => _ => _ .Unlisted() .OnlyWhenStatic(() => IsWin) - .Executes(() => + .Executes(async () => { + await DownloadLibPolicies(); + // If we're building for x64, build for x86 too var platforms = ArchitecturesForPlatformForTracer; @@ -49,6 +52,44 @@ partial class Build .SetTargetPlatform(platform))); }); + async Task DownloadLibPolicies() + { + var output = RootDirectory / "shared" / "src" / "native-lib" / "libpolicies"; + + if (Directory.Exists(output)) + { + DeleteDirectory(output); + } + + var version = "0.1.0"; + + var artifacts = new[] + { + (Arch: "x64", Hash: "EA3BC62B34FC834AC5EF42783D982EE00C49FEAA476A8803B79A191113230A8C"), + (Arch: "x86", Hash: "7BCA123BA9F463FA92A7F1FB7B4A3F22EF417696F27E3DFFFBCA8761E9662CE6"), + }; + + foreach (var artifact in artifacts) + { + var outputArch = output / artifact.Arch; + var url = $"https://github.com/DataDog/dd-policy-engine/releases/download/v{version}/libpolicies-win-{artifact.Arch}.zip"; + + var tempFile = await DownloadFile(url); + var actualHash = GetSha256Hash(tempFile); + if (!string.Equals(artifact.Hash, actualHash, StringComparison.Ordinal)) + { + throw new Exception($"Downloaded file did not have expected hash. Expected hash {artifact.Hash}, actual hash {actualHash}"); + } + + Logger.Information("Hash verified: '{Hash}'", actualHash); + + // Unzip to expected location + EnsureExistingDirectory(output); + + CompressionTasks.UncompressZip(tempFile, outputArch); + } + } + Target CompileNativeLoaderTestsWindows => _ => _ .Unlisted() .OnlyWhenStatic(() => IsWin) diff --git a/tracer/build/_build/Build.Utilities.cs b/tracer/build/_build/Build.Utilities.cs index e7182f52fd7c..9e0fcef4d596 100644 --- a/tracer/build/_build/Build.Utilities.cs +++ b/tracer/build/_build/Build.Utilities.cs @@ -686,6 +686,15 @@ private static async Task DownloadFile(string url) throw new Exception("Failed to download telemetry forwarder"); } + static string GetSha256Hash(string filePath) + { + using var sha256 = SHA256.Create(); + using var stream = File.OpenRead(filePath); + + var hashBytes = sha256.ComputeHash(stream); + return Convert.ToHexString(hashBytes); + } + static string GetSha512Hash(string filePath) { using var sha512 = SHA512.Create();