From 3c52fbe1009bed17791a65b77b5bbef5c3c844a6 Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Fri, 17 Oct 2025 11:08:06 +0200 Subject: [PATCH 01/10] feat(ssi): enable workload selection --- .../Datadog.Trace.ClrProfiler.Native.vcxproj | 30 ++-- .../cor_profiler.cpp | 12 +- .../Datadog.Trace.ClrProfiler.Native/util.h | 54 ++++++- .../workload_selection.h | 6 + .../workload_selection_impl.cpp | 146 ++++++++++++++++++ .../workload_selection_impl.h | 15 ++ .../workload_selection_noop.h | 11 ++ ...dog.Trace.ClrProfiler.Native.Tests.vcxproj | 18 +-- tracer/build/_build/Build.Shared.Steps.cs | 43 +++++- tracer/build/_build/Build.Utilities.cs | 9 ++ 10 files changed, 317 insertions(+), 27 deletions(-) create mode 100644 shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection.h create mode 100644 shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp create mode 100644 shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h create mode 100644 shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h 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..c292e69e8f3c 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,15 @@ namespace datadog::shared::nativeloader return E_FAIL; } + if (IsSingleStepInstrumentation()) + { + Log::Info("CorProfiler::Initialize: Evaluating workload selection."); + if (wls() == false) + { + return CORPROF_E_PROFILER_CANCEL_ACTIVATION; + } + } + // Guard rails have all passed, so we enable (and flush) logs if necessary Log::EnableAutoFlush(); @@ -1325,4 +1335,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..8b38284fdf10 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" / "protected" / "workload_selection.fb"; +} +#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..580bb04d06af --- /dev/null +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp @@ -0,0 +1,146 @@ +#include "workload_selection_impl.h" + +#include "../../../shared/src/native-src/string.h" +#include "log.h" +#include "util.h" + +#include +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; + + std::optional evaluatePolicies() + { + const auto policies_file = GetPoliciesPath(); + + FILE* file = NULL; + fopen_s(&file, policies_file.string().c_str(), "rb"); + if (!file) + { + return PLCS_ENO_DATA; + } + + 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 PLCS_ENO_DATA; + } + + auto res = plcs_evaluate_buffer(buffer.data(), buffer.size()); + if (res != PLCS_ESUCCESS) + { + return res; + } + + return std::nullopt; + } + + 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 auto [_, tokenized_command_line] = ::shared::GetCurrentProcessCommandLine(); + if (tokenized_command_line.size() < 2) + { + return ""; + } + + if (tokenized_command_line[0] != L"dotnet" && tokenized_command_line[0] != L"dotnet.exe") + { + return ""; + } + + if (tokenized_command_line[1].ends_with(L".dll")) + { + return ::shared::ToString(tokenized_command_line[1]); + } + + return ""; + } + +} // namespace + +bool wls() +{ + const auto process_name = ::shared::ToString(::shared::GetCurrentProcessName()); + + std::string application_pool = ""; + if (auto maybe_application_pool = GetApplicationPool()) + { + application_pool = std::move(::shared::ToString(*maybe_application_pool)); + } + + const auto dotnet_dll = GetDotnetDll(); + + 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.c_str()); + plcs_eval_ctx_set_str_eval_param(PLCS_STR_EVAL_IIS_APPLICATION_POOL, application_pool.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; + auto maybe_error = evaluatePolicies(); + if (maybe_error) + { + Log::Error(__func__, ": An error occured while evaluating workload selection policies (errno: ", *maybe_error, + ")"); + return false; + } + + // 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 (IsRunningOnIIS()) + { + 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..ee6974985660 --- /dev/null +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h @@ -0,0 +1,15 @@ +#pragma once + +extern "C" +{ +#include
+#include
+} + +namespace datadog::shared::nativeloader +{ + +/// TBD +bool wls(); + +} // 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..82a422fe6337 --- /dev/null +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h @@ -0,0 +1,11 @@ +#pragma once + +namespace datadog::shared::nativeloader +{ + +inline bool wls() +{ + 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..8801efd9f1c3 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 @@ -149,12 +149,12 @@ 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) @@ -167,14 +167,14 @@ 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) @@ -185,12 +185,12 @@ 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) @@ -203,14 +203,14 @@ 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) @@ -283,4 +283,4 @@ - \ No newline at end of file + 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(); From a3c2fdb6ad90e63fdd1e8c3f04034631352e86c3 Mon Sep 17 00:00:00 2001 From: Damien Mehala Date: Mon, 20 Oct 2025 11:16:52 -0400 Subject: [PATCH 02/10] fix: GetDotnetDll --- .../workload_selection_impl.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp index 580bb04d06af..90feab670114 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp @@ -92,12 +92,13 @@ namespace return ""; } - if (tokenized_command_line[1].ends_with(L".dll")) + if (tokenized_command_line[1].empty() || !tokenized_command_line[1].ends_with(L".dll")) { - return ::shared::ToString(tokenized_command_line[1]); + return "": } - return ""; + auto dll_path = fs::path(::shared::ToString(tokenized_command_line[1])); + return dll_path.filename().string(); } } // namespace From 2bc31af8905551bfaf68956f3ec6200e4d108152 Mon Sep 17 00:00:00 2001 From: Damien Mehala Date: Mon, 20 Oct 2025 13:27:05 -0400 Subject: [PATCH 03/10] fix: GetDotnetDll --- .../workload_selection_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp index 90feab670114..6496e92b4119 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp @@ -94,7 +94,7 @@ namespace if (tokenized_command_line[1].empty() || !tokenized_command_line[1].ends_with(L".dll")) { - return "": + return ""; } auto dll_path = fs::path(::shared::ToString(tokenized_command_line[1])); From 4f895fd81b7c5b78d2638e72bc2b72f7c090ea56 Mon Sep 17 00:00:00 2001 From: Damien Mehala Date: Tue, 21 Oct 2025 08:51:07 -0400 Subject: [PATCH 04/10] Apply suggestions from code review --- shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp | 2 +- .../workload_selection_impl.cpp | 4 ++-- .../workload_selection_impl.h | 2 +- .../workload_selection_noop.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp index c292e69e8f3c..efdcdc1607c2 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp @@ -320,7 +320,7 @@ namespace datadog::shared::nativeloader if (IsSingleStepInstrumentation()) { Log::Info("CorProfiler::Initialize: Evaluating workload selection."); - if (wls() == false) + if (is_workload_allowed() == false) { return CORPROF_E_PROFILER_CANCEL_ACTIVATION; } diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp index 6496e92b4119..4eaae27ebe45 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp @@ -103,7 +103,7 @@ namespace } // namespace -bool wls() +bool is_workload_allowed() { const auto process_name = ::shared::ToString(::shared::GetCurrentProcessName()); @@ -130,7 +130,7 @@ bool wls() { Log::Error(__func__, ": An error occured while evaluating workload selection policies (errno: ", *maybe_error, ")"); - return false; + return true; } // We enable or disable instrumentation depending on the context: diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h index ee6974985660..39bcf626d410 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h @@ -10,6 +10,6 @@ namespace datadog::shared::nativeloader { /// TBD -bool wls(); +bool is_workload_allowed(); } // 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 index 82a422fe6337..43cc6ac74a41 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h @@ -3,7 +3,7 @@ namespace datadog::shared::nativeloader { -inline bool wls() +inline bool is_workload_allowed() { return true; } From 813b52d67546743034aa3c60f731503d9a44291e Mon Sep 17 00:00:00 2001 From: Damien Mehala Date: Wed, 22 Oct 2025 13:58:05 -0400 Subject: [PATCH 05/10] address PR comments --- .../cor_profiler.cpp | 9 ++- .../workload_selection_impl.cpp | 66 ++++++++++--------- .../workload_selection_impl.h | 3 +- .../workload_selection_noop.h | 3 +- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp index efdcdc1607c2..3367d1d2bbb5 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp @@ -320,7 +320,14 @@ namespace datadog::shared::nativeloader if (IsSingleStepInstrumentation()) { Log::Info("CorProfiler::Initialize: Evaluating workload selection."); - if (is_workload_allowed() == false) + + WSTRING application_pool{L""}; + if (auto maybe_application_pool = GetApplicationPool()) + { + application_pool = std::move(*maybe_application_pool); + } + + if (is_workload_allowed(process_name, tokenized_command_line, application_pool) == false) { return CORPROF_E_PROFILER_CANCEL_ACTIVATION; } diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp index 4eaae27ebe45..cbfd1a32e471 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp @@ -27,7 +27,7 @@ namespace InjectionStatus injection_status; - std::optional evaluatePolicies() + std::optional> readPolicies() { const auto policies_file = GetPoliciesPath(); @@ -35,7 +35,7 @@ namespace fopen_s(&file, policies_file.string().c_str(), "rb"); if (!file) { - return PLCS_ENO_DATA; + return std::nullopt; } fseek(file, 0, SEEK_END); @@ -49,16 +49,10 @@ namespace if (read_size != file_size) { - return PLCS_ENO_DATA; + return std::nullopt; } - auto res = plcs_evaluate_buffer(buffer.data(), buffer.size()); - if (res != PLCS_ESUCCESS) - { - return res; - } - - return std::nullopt; + return buffer; } plcs_errors onInjectionAllow(plcs_evaluation_result eval_result, char**, size_t, const char* policy, int) @@ -79,57 +73,67 @@ namespace return PLCS_ESUCCESS; } - std::string GetDotnetDll() + std::string GetDotnetDll(const std::vector<::shared::WSTRING>& argv) { - const auto [_, tokenized_command_line] = ::shared::GetCurrentProcessCommandLine(); - if (tokenized_command_line.size() < 2) + if (argv.size() < 2) { return ""; } - if (tokenized_command_line[0] != L"dotnet" && tokenized_command_line[0] != L"dotnet.exe") + if (argv[0] != L"dotnet" && argv[0] != L"dotnet.exe") { return ""; } - if (tokenized_command_line[1].empty() || !tokenized_command_line[1].ends_with(L".dll")) + 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(tokenized_command_line[1])); + auto dll_path = fs::path(::shared::ToString(dll_arg)); return dll_path.filename().string(); } } // namespace -bool is_workload_allowed() +bool is_workload_allowed(const ::shared::WSTRING& process_name, const std::vector<::shared::WSTRING>& argv, + const ::shared::WSTRING& application_pool); { - const auto process_name = ::shared::ToString(::shared::GetCurrentProcessName()); - - std::string application_pool = ""; - if (auto maybe_application_pool = GetApplicationPool()) - { - application_pool = std::move(::shared::ToString(*maybe_application_pool)); - } + const auto process_name_str = ::shared::ToString(process_name); + const auto application_pool_str = ::shared::ToString(application_pool); - const auto dotnet_dll = GetDotnetDll(); + 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.c_str()); - plcs_eval_ctx_set_str_eval_param(PLCS_STR_EVAL_IIS_APPLICATION_POOL, application_pool.c_str()); + 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; - auto maybe_error = evaluatePolicies(); - if (maybe_error) + + auto buffer = readPolicies(); + if (!buffer) + { + return true; + } + + if (auto res = plcs_evaluate_buffer(*buffer.data(), *buffer.size()); res != PLCS_ESUCCESS) { - Log::Error(__func__, ": An error occured while evaluating workload selection policies (errno: ", *maybe_error, - ")"); + Log::Error(__func__, ": An error occured while evaluating workload selection policies (errno: ", res, ")"); return true; } diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h index 39bcf626d410..a14ed09b961a 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h @@ -10,6 +10,7 @@ namespace datadog::shared::nativeloader { /// TBD -bool is_workload_allowed(); +bool is_workload_allowed(const ::shared::WSTRING& process_name, const std::vector<::shared::WSTRING>& argv, + const ::shared::WSTRING& application_pool); } // 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 index 43cc6ac74a41..1e066fe12d62 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h @@ -1,9 +1,10 @@ #pragma once +#include "../../../shared/src/native-src/string.h" namespace datadog::shared::nativeloader { -inline bool is_workload_allowed() +inline bool is_workload_allowed(const ::shared::WSTRING&, const std::vector<::shared::WSTRING>&, const ::shared::WSTRING&) { return true; } From 8d12752706de094eef56f559228abbbf04acb22d Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Thu, 23 Oct 2025 22:25:29 +0200 Subject: [PATCH 06/10] add test and address comments feedback --- .../cor_profiler.cpp | 17 +++-- .../workload_selection_impl.cpp | 73 +++++++++---------- .../workload_selection_impl.h | 43 ++++++++++- .../workload_selection_noop.h | 10 ++- ...dog.Trace.ClrProfiler.Native.Tests.vcxproj | 9 ++- 5 files changed, 97 insertions(+), 55 deletions(-) diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp index 3367d1d2bbb5..426ac96002b0 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp @@ -321,15 +321,18 @@ namespace datadog::shared::nativeloader { Log::Info("CorProfiler::Initialize: Evaluating workload selection."); - WSTRING application_pool{L""}; - if (auto maybe_application_pool = GetApplicationPool()) + if (auto policies = readPolicies(); policies) { - application_pool = std::move(*maybe_application_pool); - } + WSTRING application_pool{L""}; + if (auto maybe_application_pool = GetApplicationPool()) + { + application_pool = std::move(*maybe_application_pool); + } - if (is_workload_allowed(process_name, tokenized_command_line, application_pool) == false) - { - return CORPROF_E_PROFILER_CANCEL_ACTIVATION; + if (isWorkloadAllowed(process_name, tokenized_command_line, application_pool, *policies, IsRunningOnIIS()) == false) + { + return CORPROF_E_PROFILER_CANCEL_ACTIVATION; + } } } diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp index cbfd1a32e471..7914c10b4535 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.cpp @@ -1,10 +1,8 @@ #include "workload_selection_impl.h" -#include "../../../shared/src/native-src/string.h" #include "log.h" #include "util.h" -#include extern "C" { #include
@@ -27,34 +25,6 @@ namespace InjectionStatus injection_status; - 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; - } - plcs_errors onInjectionAllow(plcs_evaluation_result eval_result, char**, size_t, const char* policy, int) { if (injection_status != InjectionStatus::UNKNOWN) return PLCS_ESUCCESS; @@ -106,8 +76,37 @@ namespace } // namespace -bool is_workload_allowed(const ::shared::WSTRING& process_name, const std::vector<::shared::WSTRING>& argv, - const ::shared::WSTRING& application_pool); +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); @@ -125,13 +124,7 @@ bool is_workload_allowed(const ::shared::WSTRING& process_name, const std::vecto injection_status = InjectionStatus::UNKNOWN; - auto buffer = readPolicies(); - if (!buffer) - { - return true; - } - - if (auto res = plcs_evaluate_buffer(*buffer.data(), *buffer.size()); res != PLCS_ESUCCESS) + 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; @@ -140,7 +133,7 @@ bool is_workload_allowed(const ::shared::WSTRING& process_name, const std::vecto // 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 (IsRunningOnIIS()) + if (is_iis) { return injection_status == InjectionStatus::DENY ? false : true; } diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h index a14ed09b961a..3af28335f000 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_impl.h @@ -1,4 +1,7 @@ #pragma once +#include "../../../shared/src/native-src/string.h" +#include +#include extern "C" { @@ -9,8 +12,42 @@ extern "C" namespace datadog::shared::nativeloader { -/// TBD -bool is_workload_allowed(const ::shared::WSTRING& process_name, const std::vector<::shared::WSTRING>& argv, - const ::shared::WSTRING& application_pool); +/// 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 index 1e066fe12d62..a20d8f02cf2d 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/workload_selection_noop.h @@ -1,10 +1,18 @@ #pragma once #include "../../../shared/src/native-src/string.h" +#include +#include namespace datadog::shared::nativeloader { -inline bool is_workload_allowed(const ::shared::WSTRING&, const std::vector<::shared::WSTRING>&, const ::shared::WSTRING&) +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; } 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 8801efd9f1c3..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,7 +145,7 @@ 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 @@ -163,7 +163,7 @@ 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 @@ -181,7 +181,7 @@ 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 @@ -199,7 +199,7 @@ 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 @@ -256,6 +256,7 @@ + From 785976d3e8fda9c4d3d8c2ba3ce7bad63c6e0bf5 Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Thu, 23 Oct 2025 22:50:38 +0200 Subject: [PATCH 07/10] add test file --- .../workload_selection_test.cpp | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 shared/test/Datadog.Trace.ClrProfiler.Native.Tests/workload_selection_test.cpp 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 From e1013507ef1c1e60b49d66748495cbec55ef2686 Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Fri, 24 Oct 2025 04:25:15 +0200 Subject: [PATCH 08/10] fix compilation --- shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp index 426ac96002b0..f6cab2528f2b 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp @@ -323,7 +323,7 @@ namespace datadog::shared::nativeloader if (auto policies = readPolicies(); policies) { - WSTRING application_pool{L""}; + WSTRING application_pool; if (auto maybe_application_pool = GetApplicationPool()) { application_pool = std::move(*maybe_application_pool); From 5526390c26ac041bca6ae1814a95e9af2b2cd268 Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Tue, 4 Nov 2025 14:53:38 -0400 Subject: [PATCH 09/10] change wls file expected location --- shared/src/Datadog.Trace.ClrProfiler.Native/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/util.h b/shared/src/Datadog.Trace.ClrProfiler.Native/util.h index 8b38284fdf10..02e770dd2b2f 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/util.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/util.h @@ -46,7 +46,7 @@ static fs::path GetPoliciesPath() program_data_path = WStr(R"(C:\ProgramData)"); } - return program_data_path / "Datadog" / "protected" / "workload_selection.fb"; + return program_data_path / "Datadog" / "workload_selection.fb"; } #endif From f8ad90b94b69519ee8e73011f16f574994c3166a Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Wed, 12 Nov 2025 14:43:23 -0400 Subject: [PATCH 10/10] fix flatbuffers location --- shared/src/Datadog.Trace.ClrProfiler.Native/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/util.h b/shared/src/Datadog.Trace.ClrProfiler.Native/util.h index 02e770dd2b2f..ae120af393fa 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/util.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/util.h @@ -46,7 +46,7 @@ static fs::path GetPoliciesPath() program_data_path = WStr(R"(C:\ProgramData)"); } - return program_data_path / "Datadog" / "workload_selection.fb"; + return program_data_path / "Datadog" / "user-wls-policy.bin"; } #endif