Delay initializing RPC binding handle (#2679)

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>
Co-authored-by: Alan Jowett <alan.jowett@microsoft.com>
This commit is contained in:
Alan Jowett 2023-07-20 11:50:56 -07:00 коммит произвёл GitHub
Родитель 1b63f75d89
Коммит 10ad6d205e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 29 добавлений и 19 удалений

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

@ -14,6 +14,7 @@
#include <windows.h>
#include <ctype.h>
#include <iostream>
#include <mutex>
#include <sddl.h>
#include <stdio.h>
#include <stdlib.h>
@ -23,6 +24,11 @@
static const wchar_t* _protocol_sequence = L"ncalrpc";
static bool _binding_initialized = false;
static std::mutex _rpc_binding_handle_mutex;
static RPC_STATUS
_initialize_rpc_binding();
_Must_inspect_result_ ebpf_result_t
ebpf_rpc_load_program(
_In_ const ebpf_program_load_info* info,
@ -31,6 +37,10 @@ ebpf_rpc_load_program(
{
ebpf_result_t result;
if (_initialize_rpc_binding() != RPC_S_OK) {
return EBPF_NO_MEMORY;
}
RpcTryExcept
{
result = ebpf_client_verify_and_load_program(
@ -50,9 +60,22 @@ ebpf_rpc_load_program(
return result;
}
RPC_STATUS
initialize_rpc_binding()
/**
* @brief Initialize the RPC binding handle. This is expensive and should be
* done once when required. This function is idempotent and thread safe.
*
* @retval RPC_S_OK The binding handle was initialized successfully.
* @retval RPC_S_* The binding handle could not be initialized.
*/
static RPC_STATUS
_initialize_rpc_binding()
{
std::unique_lock lock(_rpc_binding_handle_mutex);
if (_binding_initialized) {
return RPC_S_OK;
}
RPC_WSTR string_binding = nullptr;
RPC_SECURITY_QOS_V5 rpc_security_qos{
RPC_C_SECURITY_QOS_VERSION_5,
@ -121,10 +144,13 @@ Exit:
RPC_STATUS
clean_up_rpc_binding()
{
std::unique_lock lock(_rpc_binding_handle_mutex);
if (!_binding_initialized) {
return RPC_S_OK;
}
return RpcBindingFree(&ebpf_service_interface_handle);
RPC_STATUS status = RpcBindingFree(&ebpf_service_interface_handle);
_binding_initialized = false;
return status;
}
// The _In_ on size is necessary to avoid inconsistent annotation warnings.

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

@ -204,16 +204,6 @@ ebpf_api_initiate() noexcept
// it will be re-attempted before an IOCTL call is made.
(void)initialize_device_handle();
#if !defined(CONFIG_BPF_JIT_DISABLED) || !defined(CONFIG_BPF_INTERPRETER_DISABLED)
RPC_STATUS status = initialize_rpc_binding();
if (status != RPC_S_OK) {
clean_up_device_handle();
clean_up_rpc_binding();
EBPF_RETURN_RESULT(win32_error_code_to_ebpf_result(status));
}
#endif
// Load provider data from ebpf store. This is best effort
// as there may be no data present in the store.
(void)load_ebpf_provider_data();

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

@ -7,9 +7,6 @@
#include <rpc.h>
RPC_STATUS
initialize_rpc_binding(void);
RPC_STATUS
clean_up_rpc_binding(void);

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

@ -189,9 +189,6 @@ _stop_service(SC_HANDLE service_handle)
#if !defined(CONFIG_BPF_JIT_DISABLED) || !defined(CONFIG_BPF_INTERPRETER_DISABLED)
// RPC related mock functions.
RPC_STATUS
initialize_rpc_binding() { return RPC_S_OK; }
RPC_STATUS
clean_up_rpc_binding() { return RPC_S_OK; }