From 462b8e3cab2390eb55aec81134c13ff87eb54bf0 Mon Sep 17 00:00:00 2001
From: Anurag Saxena <43585259+saxena-anurag@users.noreply.github.com>
Date: Fri, 20 Sep 2024 16:13:36 -0700
Subject: [PATCH] Update store APIs to also update HKLM (#3660) (#3853)
---
include/ebpf_store_helper.h | 3 +-
installer/Product.wxs | 27 ++--
libs/api_common/store_helper_internal.cpp | 43 ++++-
libs/store_helper/ebpf_store_helper.c | 147 ++++++++++++++++--
.../user/ebpf_registry_helper.cpp | 3 +-
5 files changed, 190 insertions(+), 33 deletions(-)
diff --git a/include/ebpf_store_helper.h b/include/ebpf_store_helper.h
index 51139be2e3..b56e1021c4 100644
--- a/include/ebpf_store_helper.h
+++ b/include/ebpf_store_helper.h
@@ -16,7 +16,8 @@ extern "C"
typedef HKEY ebpf_store_key_t;
- extern ebpf_store_key_t ebpf_store_root_key;
+ extern ebpf_store_key_t ebpf_store_hkcu_root_key;
+ extern ebpf_store_key_t ebpf_store_hklm_root_key;
extern const wchar_t* ebpf_store_root_sub_key;
/**
diff --git a/installer/Product.wxs b/installer/Product.wxs
index f11c2cf1c3..52c9bf213c 100644
--- a/installer/Product.wxs
+++ b/installer/Product.wxs
@@ -57,15 +57,17 @@ SPDX-License-Identifier: MIT
NOT Installed
- NOT Installed
- NOT Installed
+ NOT Installed
+ NOT Installed
+ NOT Installed
+ NOT Installed
- NOT Installed
+ NOT Installed
- NOT Installed
+ NOT Installed
NOT Installed
- NOT Installed
+ NOT Installed
NOT Installed
@@ -77,7 +79,8 @@ SPDX-License-Identifier: MIT
REMOVE="ALL"
REMOVE="ALL"
- REMOVE="ALL"
+ REMOVE="ALL"
+ REMOVE="ALL"
REMOVE="ALL"
@@ -192,10 +195,14 @@ SPDX-License-Identifier: MIT
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/libs/api_common/store_helper_internal.cpp b/libs/api_common/store_helper_internal.cpp
index 474301353d..745aecda05 100644
--- a/libs/api_common/store_helper_internal.cpp
+++ b/libs/api_common/store_helper_internal.cpp
@@ -12,6 +12,7 @@
#include "utilities.hpp"
ebpf_store_key_t root_registry_key_current_user = HKEY_CURRENT_USER;
+ebpf_store_key_t root_registry_key_local_machine = HKEY_LOCAL_MACHINE;
static ebpf_result_t
_open_ebpf_store_key(_Out_ ebpf_store_key_t* store_key)
@@ -21,9 +22,18 @@ _open_ebpf_store_key(_Out_ ebpf_store_key_t* store_key)
// Open root registry path.
*store_key = nullptr;
- // Open the HKCU registry key.
+ // First try to open the HKCU registry key.
ebpf_result_t result =
ebpf_open_registry_key(root_registry_key_current_user, EBPF_STORE_REGISTRY_PATH, KEY_READ, store_key);
+ if (result != ERROR_SUCCESS) {
+ // Failed to open ebpf store path in HKCU. Fall back to HKLM.
+ EBPF_LOG_MESSAGE_UINT64(
+ EBPF_TRACELOG_LEVEL_WARNING,
+ EBPF_TRACELOG_KEYWORD_BASE,
+ "_open_ebpf_store_key: Failed to open HKCU registry key. Falling back to HKLM. Error:",
+ result);
+ result = ebpf_open_registry_key(root_registry_key_local_machine, EBPF_STORE_REGISTRY_PATH, KEY_READ, store_key);
+ }
EBPF_RETURN_RESULT(result);
}
@@ -886,8 +896,9 @@ ebpf_store_clear(_In_ const ebpf_store_key_t root_key_path)
EBPF_RETURN_RESULT(result);
}
-ebpf_result_t
-ebpf_store_delete_global_helper_information(_In_ ebpf_helper_function_prototype_t* helper_info)
+static ebpf_result_t
+_ebpf_store_delete_global_helper_information(
+ ebpf_store_key_t root_store_key, _In_ ebpf_helper_function_prototype_t* helper_info)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_store_key_t root_key = NULL;
@@ -903,7 +914,7 @@ ebpf_store_delete_global_helper_information(_In_ ebpf_helper_function_prototype_
}
// Open root registry key.
- result = ebpf_open_registry_key(ebpf_store_root_key, EBPF_ROOT_RELATIVE_PATH, REG_CREATE_FLAGS, &root_key);
+ result = ebpf_open_registry_key(root_store_key, EBPF_ROOT_RELATIVE_PATH, REG_CREATE_FLAGS, &root_key);
if (result != EBPF_SUCCESS) {
if (result == EBPF_FILE_NOT_FOUND) {
result = EBPF_SUCCESS;
@@ -941,3 +952,27 @@ ebpf_store_delete_global_helper_information(_In_ ebpf_helper_function_prototype_
EBPF_RETURN_RESULT(result);
}
+
+ebpf_result_t
+ebpf_store_delete_global_helper_information(_In_ ebpf_helper_function_prototype_t* helper_info)
+{
+ ebpf_result_t result = EBPF_SUCCESS;
+
+ EBPF_LOG_ENTRY();
+
+ // First delete from HKCU root key.
+ result = _ebpf_store_delete_global_helper_information(root_registry_key_current_user, helper_info);
+ if (result != EBPF_SUCCESS) {
+ goto Exit;
+ }
+
+ // Next delete from HKLM root key. It possible that the user does not have permission to the HKLM root key.
+ // Suppress error in that case.
+ result = _ebpf_store_delete_global_helper_information(root_registry_key_local_machine, helper_info);
+ if (result == EBPF_ACCESS_DENIED) {
+ result = EBPF_SUCCESS;
+ }
+
+Exit:
+ EBPF_RETURN_RESULT(result);
+}
diff --git a/libs/store_helper/ebpf_store_helper.c b/libs/store_helper/ebpf_store_helper.c
index ec9fc52adc..a61f0afa1a 100644
--- a/libs/store_helper/ebpf_store_helper.c
+++ b/libs/store_helper/ebpf_store_helper.c
@@ -22,14 +22,14 @@ _ebpf_store_update_extension_header_information(ebpf_store_key_t key, _In_ const
}
static ebpf_result_t
-_ebpf_store_open_or_create_provider_registry_key(_Out_ ebpf_store_key_t* provider_key)
+_ebpf_store_open_or_create_provider_registry_key(ebpf_store_key_t root_store_key, _Out_ ebpf_store_key_t* provider_key)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_store_key_t root_key = NULL;
*provider_key = NULL;
// Open (or create) root eBPF registry path.
- result = ebpf_create_registry_key(ebpf_store_root_key, ebpf_store_root_sub_key, REG_CREATE_FLAGS, &root_key);
+ result = ebpf_create_registry_key(root_store_key, ebpf_store_root_sub_key, REG_CREATE_FLAGS, &root_key);
if (!IS_SUCCESS(result)) {
goto Exit;
@@ -106,9 +106,11 @@ _ebpf_store_update_helper_prototype(
return result;
}
-ebpf_result_t
-ebpf_store_update_global_helper_information(
- _In_reads_(helper_info_count) ebpf_helper_function_prototype_t* helper_info, uint32_t helper_info_count)
+static ebpf_result_t
+_ebpf_store_update_global_helper_information(
+ ebpf_store_key_t root_key,
+ _In_reads_(helper_info_count) ebpf_helper_function_prototype_t* helper_info,
+ uint32_t helper_info_count)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_store_key_t provider_key = NULL;
@@ -124,7 +126,7 @@ ebpf_store_update_global_helper_information(
}
// Open (or create) provider registry path.
- result = _ebpf_store_open_or_create_provider_registry_key(&provider_key);
+ result = _ebpf_store_open_or_create_provider_registry_key(root_key, &provider_key);
if (!IS_SUCCESS(result)) {
goto Exit;
}
@@ -151,8 +153,31 @@ ebpf_store_update_global_helper_information(
}
ebpf_result_t
-ebpf_store_update_section_information(
- _In_reads_(section_info_count) const ebpf_program_section_info_t* section_info, uint32_t section_info_count)
+ebpf_store_update_global_helper_information(
+ _In_reads_(helper_info_count) ebpf_helper_function_prototype_t* helper_info, uint32_t helper_info_count)
+{
+ // First update the HKCU root key.
+ ebpf_result_t result =
+ _ebpf_store_update_global_helper_information(ebpf_store_hkcu_root_key, helper_info, helper_info_count);
+ if (!IS_SUCCESS(result)) {
+ return result;
+ }
+
+ // Next update the HKLM root key. It possible that the user does not have permission to update the HKLM root key.
+ // Suppress error in that case.
+ result = _ebpf_store_update_global_helper_information(ebpf_store_hklm_root_key, helper_info, helper_info_count);
+ if (result == EBPF_ACCESS_DENIED) {
+ result = EBPF_SUCCESS;
+ }
+
+ return result;
+}
+
+static ebpf_result_t
+_ebpf_store_update_section_information(
+ ebpf_store_key_t root_key,
+ _In_reads_(section_info_count) const ebpf_program_section_info_t* section_info,
+ uint32_t section_info_count)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_store_key_t provider_key = NULL;
@@ -163,7 +188,7 @@ ebpf_store_update_section_information(
}
// Open (or create) provider registry path.
- result = _ebpf_store_open_or_create_provider_registry_key(&provider_key);
+ result = _ebpf_store_open_or_create_provider_registry_key(root_key, &provider_key);
if (!IS_SUCCESS(result)) {
goto Exit;
}
@@ -240,6 +265,28 @@ ebpf_store_update_section_information(
return result;
}
+ebpf_result_t
+ebpf_store_update_section_information(
+ _In_reads_(section_info_count) const ebpf_program_section_info_t* section_info, uint32_t section_info_count)
+{
+ ebpf_result_t result = EBPF_SUCCESS;
+
+ // First update the HKCU root key.
+ result = _ebpf_store_update_section_information(ebpf_store_hkcu_root_key, section_info, section_info_count);
+ if (!IS_SUCCESS(result)) {
+ return result;
+ }
+
+ // Next update the HKLM root key. It possible that the user does not have permission to update the HKLM root key.
+ // Suppress error in that case.
+ result = _ebpf_store_update_section_information(ebpf_store_hklm_root_key, section_info, section_info_count);
+ if (result == EBPF_ACCESS_DENIED) {
+ result = EBPF_SUCCESS;
+ }
+
+ return result;
+}
+
static ebpf_result_t
_ebpf_store_update_program_descriptor(
ebpf_store_key_t descriptor_key, _In_ const ebpf_program_type_descriptor_t* program_type_descriptor)
@@ -351,9 +398,11 @@ _ebpf_store_update_program_info(ebpf_store_key_t program_key, _In_ const ebpf_pr
return result;
}
-ebpf_result_t
-ebpf_store_update_program_information_array(
- _In_reads_(program_info_count) const ebpf_program_info_t* program_info, uint32_t program_info_count)
+static ebpf_result_t
+_ebpf_store_update_program_information_array(
+ ebpf_store_key_t root_key,
+ _In_reads_(program_info_count) const ebpf_program_info_t* program_info,
+ uint32_t program_info_count)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_store_key_t provider_key = NULL;
@@ -365,7 +414,7 @@ ebpf_store_update_program_information_array(
}
// Open (or create) provider registry path.
- result = _ebpf_store_open_or_create_provider_registry_key(&provider_key);
+ result = _ebpf_store_open_or_create_provider_registry_key(root_key, &provider_key);
if (!IS_SUCCESS(result)) {
goto Exit;
}
@@ -428,14 +477,36 @@ ebpf_store_update_program_information_array(
}
ebpf_result_t
-ebpf_store_delete_program_information(_In_ const ebpf_program_info_t* program_info)
+ebpf_store_update_program_information_array(
+ _In_reads_(program_info_count) const ebpf_program_info_t* program_info, uint32_t program_info_count)
+{
+ ebpf_result_t result = EBPF_SUCCESS;
+
+ // First update the HKCU root key.
+ result = _ebpf_store_update_program_information_array(ebpf_store_hkcu_root_key, program_info, program_info_count);
+ if (!IS_SUCCESS(result)) {
+ return result;
+ }
+
+ // Next update the HKLM root key. It possible that the user does not have permission to update the HKLM root key.
+ // Suppress error in that case.
+ result = _ebpf_store_update_program_information_array(ebpf_store_hklm_root_key, program_info, program_info_count);
+ if (result == EBPF_ACCESS_DENIED) {
+ result = EBPF_SUCCESS;
+ }
+
+ return result;
+}
+
+static ebpf_result_t
+_ebpf_store_delete_program_information(ebpf_store_key_t root_key, _In_ const ebpf_program_info_t* program_info)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_store_key_t provider_key = NULL;
ebpf_store_key_t program_info_key = NULL;
// Open (or create) provider registry path.
- result = _ebpf_store_open_or_create_provider_registry_key(&provider_key);
+ result = _ebpf_store_open_or_create_provider_registry_key(root_key, &provider_key);
if (!IS_SUCCESS(result)) {
goto Exit;
}
@@ -467,14 +538,35 @@ ebpf_store_delete_program_information(_In_ const ebpf_program_info_t* program_in
}
ebpf_result_t
-ebpf_store_delete_section_information(_In_ const ebpf_program_section_info_t* section_info)
+ebpf_store_delete_program_information(_In_ const ebpf_program_info_t* program_info)
+{
+ ebpf_result_t result = EBPF_SUCCESS;
+
+ // First delete from HKCU root key.
+ result = _ebpf_store_delete_program_information(ebpf_store_hkcu_root_key, program_info);
+ if (!IS_SUCCESS(result)) {
+ return result;
+ }
+
+ // Next delete from HKLM root key. It possible that the user does not have permission to delete from the HKLM root
+ // key. Suppress error in that case.
+ result = _ebpf_store_delete_program_information(ebpf_store_hklm_root_key, program_info);
+ if (result == EBPF_ACCESS_DENIED) {
+ result = EBPF_SUCCESS;
+ }
+
+ return result;
+}
+
+static ebpf_result_t
+_ebpf_store_delete_section_information(ebpf_store_key_t root_key, _In_ const ebpf_program_section_info_t* section_info)
{
ebpf_result_t result = EBPF_SUCCESS;
ebpf_store_key_t provider_key = NULL;
ebpf_store_key_t section_info_key = NULL;
// Open (or create) provider registry path.
- result = _ebpf_store_open_or_create_provider_registry_key(&provider_key);
+ result = _ebpf_store_open_or_create_provider_registry_key(root_key, &provider_key);
if (!IS_SUCCESS(result)) {
goto Exit;
}
@@ -496,3 +588,24 @@ ebpf_store_delete_section_information(_In_ const ebpf_program_section_info_t* se
return result;
}
+
+ebpf_result_t
+ebpf_store_delete_section_information(_In_ const ebpf_program_section_info_t* section_info)
+{
+ ebpf_result_t result = EBPF_SUCCESS;
+
+ // First delete from HKCU root key.
+ result = _ebpf_store_delete_section_information(ebpf_store_hkcu_root_key, section_info);
+ if (!IS_SUCCESS(result)) {
+ return result;
+ }
+
+ // Next delete from HKLM root key. It possible that the user does not have permission to delete from the HKLM root
+ // key. Suppress error in that case.
+ result = _ebpf_store_delete_section_information(ebpf_store_hklm_root_key, section_info);
+ if (result == EBPF_ACCESS_DENIED) {
+ result = EBPF_SUCCESS;
+ }
+
+ return result;
+}
diff --git a/libs/store_helper/user/ebpf_registry_helper.cpp b/libs/store_helper/user/ebpf_registry_helper.cpp
index 47d542d8a4..04e708bada 100644
--- a/libs/store_helper/user/ebpf_registry_helper.cpp
+++ b/libs/store_helper/user/ebpf_registry_helper.cpp
@@ -16,7 +16,8 @@
#define GUID_STRING_LENGTH 38 // not including the null terminator.
#define _EBPF_RESULT(x) win32_error_code_to_ebpf_result(x)
-ebpf_store_key_t ebpf_store_root_key = HKEY_CURRENT_USER; // TODO: Issue #1231 Change to using HKEY_LOCAL_MACHINE
+ebpf_store_key_t ebpf_store_hkcu_root_key = HKEY_CURRENT_USER;
+ebpf_store_key_t ebpf_store_hklm_root_key = HKEY_LOCAL_MACHINE;
const wchar_t* ebpf_store_root_sub_key = EBPF_ROOT_RELATIVE_PATH;
wchar_t*