2024-05-04 22:55:56 +03:00
|
|
|
// Copyright (c) eBPF for Windows contributors
|
2021-09-14 00:46:43 +03:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
/**
|
2023-02-07 21:32:19 +03:00
|
|
|
* @file
|
|
|
|
* @brief This file implements the BIND program type hook on eBPF for Windows.
|
2021-09-14 00:46:43 +03:00
|
|
|
*/
|
|
|
|
|
2023-12-08 00:10:19 +03:00
|
|
|
#include "ebpf_shared_framework.h"
|
2022-03-15 01:16:11 +03:00
|
|
|
#include "net_ebpf_ext_bind.h"
|
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
typedef struct _bind_context_header
|
|
|
|
{
|
|
|
|
EBPF_CONTEXT_HEADER;
|
|
|
|
bind_md_t context;
|
|
|
|
} bind_context_header_t;
|
|
|
|
|
2022-03-15 01:16:11 +03:00
|
|
|
//
|
2022-04-06 02:37:34 +03:00
|
|
|
// WFP filter related globals for bind hook.
|
2022-03-15 01:16:11 +03:00
|
|
|
//
|
|
|
|
|
|
|
|
const net_ebpf_extension_wfp_filter_parameters_t _net_ebpf_extension_bind_wfp_filter_parameters[] = {
|
|
|
|
{&FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V4,
|
2022-11-29 23:49:42 +03:00
|
|
|
NULL, // Default sublayer.
|
2022-03-15 01:16:11 +03:00
|
|
|
&EBPF_HOOK_ALE_RESOURCE_ALLOC_V4_CALLOUT,
|
|
|
|
L"net eBPF bind hook",
|
|
|
|
L"net eBPF bind hook WFP filter"},
|
|
|
|
{&FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V6,
|
2022-11-29 23:49:42 +03:00
|
|
|
NULL, // Default sublayer.
|
2022-03-15 01:16:11 +03:00
|
|
|
&EBPF_HOOK_ALE_RESOURCE_ALLOC_V6_CALLOUT,
|
|
|
|
L"net eBPF bind hook",
|
|
|
|
L"net eBPF bind hook WFP filter"},
|
|
|
|
{&FWPM_LAYER_ALE_RESOURCE_RELEASE_V4,
|
2022-11-29 23:49:42 +03:00
|
|
|
NULL, // Default sublayer.
|
2022-03-15 01:16:11 +03:00
|
|
|
&EBPF_HOOK_ALE_RESOURCE_RELEASE_V4_CALLOUT,
|
|
|
|
L"net eBPF bind hook",
|
|
|
|
L"net eBPF bind hook WFP filter"},
|
|
|
|
{&FWPM_LAYER_ALE_RESOURCE_RELEASE_V6,
|
2022-11-29 23:49:42 +03:00
|
|
|
NULL, // Default sublayer.
|
2022-03-15 01:16:11 +03:00
|
|
|
&EBPF_HOOK_ALE_RESOURCE_RELEASE_V6_CALLOUT,
|
|
|
|
L"net eBPF bind hook",
|
|
|
|
L"net eBPF bind hook WFP filter"}};
|
|
|
|
|
|
|
|
#define NET_EBPF_BIND_FILTER_COUNT EBPF_COUNT_OF(_net_ebpf_extension_bind_wfp_filter_parameters)
|
|
|
|
|
2023-01-10 22:22:20 +03:00
|
|
|
static ebpf_result_t
|
|
|
|
_ebpf_bind_context_create(
|
|
|
|
_In_reads_bytes_opt_(data_size_in) const uint8_t* data_in,
|
|
|
|
size_t data_size_in,
|
|
|
|
_In_reads_bytes_opt_(context_size_in) const uint8_t* context_in,
|
|
|
|
size_t context_size_in,
|
|
|
|
_Outptr_ void** context);
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ebpf_bind_context_destroy(
|
|
|
|
_In_opt_ void* context,
|
|
|
|
_Out_writes_bytes_to_(*data_size_out, *data_size_out) uint8_t* data_out,
|
|
|
|
_Inout_ size_t* data_size_out,
|
|
|
|
_Out_writes_bytes_to_(*context_size_out, *context_size_out) uint8_t* context_out,
|
|
|
|
_Inout_ size_t* context_size_out);
|
|
|
|
|
2022-02-26 04:53:12 +03:00
|
|
|
//
|
|
|
|
// Bind Program Information NPI Provider.
|
|
|
|
//
|
2023-01-10 22:22:20 +03:00
|
|
|
static ebpf_program_data_t _ebpf_bind_program_data = {
|
2024-05-24 04:05:36 +03:00
|
|
|
.header = EBPF_PROGRAM_DATA_HEADER,
|
2023-01-10 22:22:20 +03:00
|
|
|
.program_info = &_ebpf_bind_program_info,
|
|
|
|
.context_create = _ebpf_bind_context_create,
|
|
|
|
.context_destroy = _ebpf_bind_context_destroy,
|
|
|
|
.required_irql = PASSIVE_LEVEL,
|
2024-07-15 19:23:51 +03:00
|
|
|
.capabilities = {.supports_context_header = true},
|
2023-01-10 22:22:20 +03:00
|
|
|
};
|
2021-09-14 00:46:43 +03:00
|
|
|
|
2024-03-30 20:27:09 +03:00
|
|
|
// Set the program type as the provider module id.
|
|
|
|
NPI_MODULEID DECLSPEC_SELECTANY _ebpf_bind_program_info_provider_moduleid = {
|
|
|
|
sizeof(NPI_MODULEID), MIT_GUID, EBPF_PROGRAM_TYPE_BIND_GUID};
|
2022-02-26 04:53:12 +03:00
|
|
|
|
|
|
|
static net_ebpf_extension_program_info_provider_t* _ebpf_bind_program_info_provider_context = NULL;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Bind Hook NPI Provider.
|
|
|
|
//
|
2024-03-30 20:27:09 +03:00
|
|
|
ebpf_attach_provider_data_t _net_ebpf_bind_hook_provider_data = {
|
2024-05-24 04:05:36 +03:00
|
|
|
EBPF_ATTACH_PROVIDER_DATA_HEADER, EBPF_PROGRAM_TYPE_BIND_GUID, BPF_ATTACH_TYPE_BIND, BPF_LINK_TYPE_PLAIN};
|
2022-02-26 04:53:12 +03:00
|
|
|
|
2024-03-30 20:27:09 +03:00
|
|
|
NPI_MODULEID DECLSPEC_SELECTANY _ebpf_bind_hook_provider_moduleid = {
|
|
|
|
sizeof(NPI_MODULEID), MIT_GUID, EBPF_ATTACH_TYPE_BIND_GUID};
|
2022-02-26 04:53:12 +03:00
|
|
|
|
|
|
|
static net_ebpf_extension_hook_provider_t* _ebpf_bind_hook_provider_context = NULL;
|
|
|
|
|
2022-03-15 01:16:11 +03:00
|
|
|
//
|
|
|
|
// Client attach/detach handler routines.
|
|
|
|
//
|
|
|
|
|
|
|
|
static ebpf_result_t
|
2024-09-05 03:32:40 +03:00
|
|
|
_net_ebpf_ext_bind_validate_client_data(_In_ const ebpf_extension_data_t* client_data, _Out_ bool* is_wildcard)
|
|
|
|
{
|
|
|
|
// Bind hook does not require any client data.
|
|
|
|
UNREFERENCED_PARAMETER(client_data);
|
|
|
|
*is_wildcard = FALSE;
|
|
|
|
return EBPF_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ebpf_result_t
|
|
|
|
_net_ebpf_ext_bind_create_filter_context(
|
2022-04-06 02:37:34 +03:00
|
|
|
_In_ const net_ebpf_extension_hook_client_t* attaching_client,
|
2024-09-05 03:32:40 +03:00
|
|
|
_In_ const net_ebpf_extension_hook_provider_t* provider_context,
|
|
|
|
_Outptr_ net_ebpf_extension_wfp_filter_context_t** filter_context)
|
2022-03-15 01:16:11 +03:00
|
|
|
{
|
|
|
|
ebpf_result_t result = EBPF_SUCCESS;
|
2024-09-05 03:32:40 +03:00
|
|
|
net_ebpf_extension_wfp_filter_context_t* local_filter_context = NULL;
|
2022-03-15 01:16:11 +03:00
|
|
|
|
2022-07-01 01:08:02 +03:00
|
|
|
NET_EBPF_EXT_LOG_ENTRY();
|
|
|
|
|
2022-04-21 02:48:20 +03:00
|
|
|
result = net_ebpf_extension_wfp_filter_context_create(
|
2024-09-05 03:32:40 +03:00
|
|
|
sizeof(net_ebpf_extension_wfp_filter_context_t), attaching_client, provider_context, &local_filter_context);
|
2022-11-29 23:49:42 +03:00
|
|
|
if (result != EBPF_SUCCESS) {
|
2022-04-21 02:48:20 +03:00
|
|
|
goto Exit;
|
2022-11-29 23:49:42 +03:00
|
|
|
}
|
2024-09-05 03:32:40 +03:00
|
|
|
local_filter_context->filter_ids_count = NET_EBPF_BIND_FILTER_COUNT;
|
2022-04-21 02:48:20 +03:00
|
|
|
|
2022-03-15 01:16:11 +03:00
|
|
|
// Add WFP filters at appropriate layers and set the hook NPI client as the filter's raw context.
|
|
|
|
result = net_ebpf_extension_add_wfp_filters(
|
2024-10-10 07:17:31 +03:00
|
|
|
local_filter_context->wfp_engine_handle,
|
2022-03-15 01:16:11 +03:00
|
|
|
EBPF_COUNT_OF(_net_ebpf_extension_bind_wfp_filter_parameters),
|
|
|
|
_net_ebpf_extension_bind_wfp_filter_parameters,
|
|
|
|
0,
|
|
|
|
NULL,
|
2024-09-05 03:32:40 +03:00
|
|
|
local_filter_context,
|
|
|
|
&local_filter_context->filter_ids);
|
2023-03-27 18:01:21 +03:00
|
|
|
if (result != EBPF_SUCCESS) {
|
2022-03-15 01:16:11 +03:00
|
|
|
goto Exit;
|
2023-03-27 18:01:21 +03:00
|
|
|
}
|
2022-03-15 01:16:11 +03:00
|
|
|
|
2024-09-05 03:32:40 +03:00
|
|
|
*filter_context = (net_ebpf_extension_wfp_filter_context_t*)local_filter_context;
|
|
|
|
local_filter_context = NULL;
|
2022-04-21 02:48:20 +03:00
|
|
|
|
2022-03-15 01:16:11 +03:00
|
|
|
Exit:
|
2024-09-05 03:32:40 +03:00
|
|
|
CLEAN_UP_FILTER_CONTEXT(local_filter_context);
|
|
|
|
|
2022-07-01 01:08:02 +03:00
|
|
|
NET_EBPF_EXT_RETURN_RESULT(result);
|
2022-03-15 01:16:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2024-09-05 03:32:40 +03:00
|
|
|
_net_ebpf_ext_bind_delete_filter_context(
|
|
|
|
_In_opt_ _Frees_ptr_opt_ net_ebpf_extension_wfp_filter_context_t* filter_context)
|
2022-03-15 01:16:11 +03:00
|
|
|
{
|
2024-09-05 03:32:40 +03:00
|
|
|
NET_EBPF_EXT_LOG_ENTRY();
|
|
|
|
|
|
|
|
if (filter_context == NULL) {
|
|
|
|
goto Exit;
|
|
|
|
}
|
2022-03-15 01:16:11 +03:00
|
|
|
|
|
|
|
// Delete the WFP filters.
|
2024-10-10 07:17:31 +03:00
|
|
|
net_ebpf_extension_delete_wfp_filters(
|
|
|
|
filter_context->wfp_engine_handle, filter_context->filter_ids_count, filter_context->filter_ids);
|
2022-04-21 02:48:20 +03:00
|
|
|
net_ebpf_extension_wfp_filter_context_cleanup((net_ebpf_extension_wfp_filter_context_t*)filter_context);
|
2024-09-05 03:32:40 +03:00
|
|
|
|
|
|
|
Exit:
|
|
|
|
NET_EBPF_EXT_LOG_EXIT();
|
2022-03-15 01:16:11 +03:00
|
|
|
}
|
|
|
|
|
2022-02-26 04:53:12 +03:00
|
|
|
//
|
|
|
|
// NMR Registration Helper Routines.
|
|
|
|
//
|
2021-09-14 00:46:43 +03:00
|
|
|
|
2022-02-26 04:53:12 +03:00
|
|
|
NTSTATUS
|
|
|
|
net_ebpf_ext_bind_register_providers()
|
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2022-07-01 02:53:03 +03:00
|
|
|
|
2023-08-29 22:26:03 +03:00
|
|
|
NET_EBPF_EXT_LOG_ENTRY();
|
2022-07-01 02:53:03 +03:00
|
|
|
|
2022-03-15 01:16:11 +03:00
|
|
|
const net_ebpf_extension_program_info_provider_parameters_t program_info_provider_parameters = {
|
2024-03-30 20:27:09 +03:00
|
|
|
&_ebpf_bind_program_info_provider_moduleid, &_ebpf_bind_program_data};
|
2022-03-15 01:16:11 +03:00
|
|
|
const net_ebpf_extension_hook_provider_parameters_t hook_provider_parameters = {
|
2024-03-30 20:27:09 +03:00
|
|
|
&_ebpf_bind_hook_provider_moduleid, &_net_ebpf_bind_hook_provider_data};
|
2024-09-05 03:32:40 +03:00
|
|
|
const net_ebpf_extension_hook_provider_dispatch_table_t dispatch_table = {
|
|
|
|
.create_filter_context = _net_ebpf_ext_bind_create_filter_context,
|
|
|
|
.delete_filter_context = _net_ebpf_ext_bind_delete_filter_context,
|
|
|
|
.validate_client_data = _net_ebpf_ext_bind_validate_client_data};
|
2022-02-26 04:53:12 +03:00
|
|
|
|
|
|
|
status = net_ebpf_extension_program_info_provider_register(
|
2023-02-22 23:43:23 +03:00
|
|
|
&program_info_provider_parameters, &_ebpf_bind_program_info_provider_context);
|
2023-03-13 21:38:41 +03:00
|
|
|
if (!NT_SUCCESS(status)) {
|
2023-08-29 22:26:03 +03:00
|
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(
|
|
|
|
NET_EBPF_EXT_TRACELOG_LEVEL_ERROR,
|
|
|
|
NET_EBPF_EXT_TRACELOG_KEYWORD_BIND,
|
|
|
|
"net_ebpf_extension_program_info_provider_register",
|
|
|
|
status);
|
2022-02-26 04:53:12 +03:00
|
|
|
goto Exit;
|
2023-03-13 21:38:41 +03:00
|
|
|
}
|
2022-02-26 04:53:12 +03:00
|
|
|
|
|
|
|
status = net_ebpf_extension_hook_provider_register(
|
2022-03-15 01:16:11 +03:00
|
|
|
&hook_provider_parameters,
|
2024-09-05 03:32:40 +03:00
|
|
|
&dispatch_table,
|
|
|
|
ATTACH_CAPABILITY_SINGLE_ATTACH,
|
2022-04-06 02:37:34 +03:00
|
|
|
NULL,
|
2022-03-15 01:16:11 +03:00
|
|
|
&_ebpf_bind_hook_provider_context);
|
2022-02-26 04:53:12 +03:00
|
|
|
if (status != EBPF_SUCCESS) {
|
2023-08-29 22:26:03 +03:00
|
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(
|
|
|
|
NET_EBPF_EXT_TRACELOG_LEVEL_ERROR,
|
|
|
|
NET_EBPF_EXT_TRACELOG_KEYWORD_BIND,
|
|
|
|
"net_ebpf_extension_hook_provider_register",
|
|
|
|
status);
|
2022-02-26 04:53:12 +03:00
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
Exit:
|
2023-03-13 21:38:41 +03:00
|
|
|
if (!NT_SUCCESS(status)) {
|
|
|
|
net_ebpf_ext_bind_unregister_providers();
|
|
|
|
}
|
2022-07-01 01:08:02 +03:00
|
|
|
NET_EBPF_EXT_RETURN_NTSTATUS(status);
|
2022-02-26 04:53:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
net_ebpf_ext_bind_unregister_providers()
|
|
|
|
{
|
2024-10-10 07:17:31 +03:00
|
|
|
if (_ebpf_bind_hook_provider_context != NULL) {
|
2023-03-13 21:38:41 +03:00
|
|
|
net_ebpf_extension_hook_provider_unregister(_ebpf_bind_hook_provider_context);
|
|
|
|
_ebpf_bind_hook_provider_context = NULL;
|
|
|
|
}
|
2024-10-10 07:17:31 +03:00
|
|
|
if (_ebpf_bind_program_info_provider_context != NULL) {
|
2023-03-13 21:38:41 +03:00
|
|
|
net_ebpf_extension_program_info_provider_unregister(_ebpf_bind_program_info_provider_context);
|
|
|
|
_ebpf_bind_program_info_provider_context = NULL;
|
|
|
|
}
|
2022-02-26 04:53:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// WFP Classify Callbacks.
|
|
|
|
//
|
2021-09-14 00:46:43 +03:00
|
|
|
|
|
|
|
static void
|
|
|
|
_net_ebpf_ext_resource_truncate_appid(bind_md_t* ctx)
|
|
|
|
{
|
|
|
|
wchar_t* last_separator = (wchar_t*)ctx->app_id_start;
|
|
|
|
for (wchar_t* position = (wchar_t*)ctx->app_id_start; position < (wchar_t*)ctx->app_id_end; position++) {
|
|
|
|
if (*position == '\\') {
|
|
|
|
last_separator = position;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (*last_separator == '\\') {
|
|
|
|
last_separator++;
|
|
|
|
}
|
|
|
|
ctx->app_id_start = (uint8_t*)last_separator;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
net_ebpf_ext_resource_allocation_classify(
|
|
|
|
_In_ const FWPS_INCOMING_VALUES* incoming_fixed_values,
|
|
|
|
_In_ const FWPS_INCOMING_METADATA_VALUES* incoming_metadata_values,
|
|
|
|
_Inout_opt_ void* layer_data,
|
|
|
|
_In_opt_ const void* classify_context,
|
|
|
|
_In_ const FWPS_FILTER* filter,
|
|
|
|
uint64_t flow_context,
|
|
|
|
_Inout_ FWPS_CLASSIFY_OUT* classify_output)
|
|
|
|
{
|
|
|
|
SOCKADDR_IN addr = {AF_INET};
|
|
|
|
uint32_t result;
|
2024-09-05 03:32:40 +03:00
|
|
|
ebpf_result_t program_result;
|
2024-07-15 19:23:51 +03:00
|
|
|
bind_context_header_t context_header = {0};
|
|
|
|
bind_md_t* ctx = &context_header.context;
|
2022-04-21 02:48:20 +03:00
|
|
|
net_ebpf_extension_wfp_filter_context_t* filter_context = NULL;
|
2021-09-14 00:46:43 +03:00
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(layer_data);
|
|
|
|
UNREFERENCED_PARAMETER(classify_context);
|
|
|
|
UNREFERENCED_PARAMETER(flow_context);
|
|
|
|
|
2022-04-12 21:37:44 +03:00
|
|
|
classify_output->actionType = FWP_ACTION_PERMIT;
|
|
|
|
|
2022-04-21 02:48:20 +03:00
|
|
|
filter_context = (net_ebpf_extension_wfp_filter_context_t*)filter->context;
|
|
|
|
ASSERT(filter_context != NULL);
|
2023-03-27 18:01:21 +03:00
|
|
|
if (filter_context == NULL) {
|
2022-04-21 02:48:20 +03:00
|
|
|
goto Exit;
|
2023-03-27 18:01:21 +03:00
|
|
|
}
|
2022-04-21 02:48:20 +03:00
|
|
|
|
2024-09-05 03:32:40 +03:00
|
|
|
// Note: This is intentionally not guarded by a lock as this is opportunistically checking if all the clients have
|
|
|
|
// detached and the filter context is being deleted.
|
|
|
|
if (filter_context->context_deleting) {
|
2024-01-09 08:53:21 +03:00
|
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(
|
|
|
|
NET_EBPF_EXT_TRACELOG_LEVEL_VERBOSE,
|
|
|
|
NET_EBPF_EXT_TRACELOG_KEYWORD_BIND,
|
2024-09-05 03:32:40 +03:00
|
|
|
"net_ebpf_ext_resource_allocation_classify - Filter context deleting.",
|
2024-01-09 08:53:21 +03:00
|
|
|
STATUS_INVALID_PARAMETER);
|
|
|
|
goto Exit;
|
|
|
|
}
|
2021-09-14 00:46:43 +03:00
|
|
|
|
|
|
|
addr.sin_port =
|
|
|
|
incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_PORT].value.uint16;
|
|
|
|
addr.sin_addr.S_un.S_addr =
|
|
|
|
incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_ADDRESS].value.uint32;
|
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
ctx->process_id = incoming_metadata_values->processId;
|
|
|
|
memcpy(&ctx->socket_address, &addr, sizeof(addr));
|
|
|
|
ctx->socket_address_length = sizeof(addr);
|
|
|
|
ctx->operation = BIND_OPERATION_BIND;
|
|
|
|
ctx->protocol = incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_PROTOCOL].value.uint8;
|
2021-09-14 00:46:43 +03:00
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
ctx->app_id_start =
|
2021-09-14 00:46:43 +03:00
|
|
|
incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_ALE_APP_ID].value.byteBlob->data;
|
2024-07-15 19:23:51 +03:00
|
|
|
ctx->app_id_end =
|
|
|
|
ctx->app_id_start +
|
2021-09-14 00:46:43 +03:00
|
|
|
incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_ALE_APP_ID].value.byteBlob->size;
|
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
_net_ebpf_ext_resource_truncate_appid(ctx);
|
2024-09-05 03:32:40 +03:00
|
|
|
|
|
|
|
program_result = net_ebpf_extension_hook_invoke_programs(ctx, filter_context, &result);
|
|
|
|
if (program_result == EBPF_OBJECT_NOT_FOUND) {
|
|
|
|
// No program found.
|
|
|
|
NET_EBPF_EXT_LOG_MESSAGE(
|
|
|
|
NET_EBPF_EXT_TRACELOG_LEVEL_ERROR,
|
|
|
|
NET_EBPF_EXT_TRACELOG_KEYWORD_BIND,
|
|
|
|
"net_ebpf_ext_resource_allocation_classify - No programs found.");
|
|
|
|
goto Exit;
|
|
|
|
} else if (program_result != EBPF_SUCCESS) {
|
|
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(
|
|
|
|
NET_EBPF_EXT_TRACELOG_LEVEL_ERROR,
|
|
|
|
NET_EBPF_EXT_TRACELOG_KEYWORD_BIND,
|
|
|
|
"net_ebpf_ext_resource_allocation_classify - net_ebpf_extension_hook_invoke_programs failed.",
|
|
|
|
program_result);
|
|
|
|
goto Exit;
|
|
|
|
} else {
|
2021-09-14 00:46:43 +03:00
|
|
|
switch (result) {
|
|
|
|
case BIND_PERMIT:
|
|
|
|
case BIND_REDIRECT:
|
|
|
|
classify_output->actionType = FWP_ACTION_PERMIT;
|
|
|
|
break;
|
|
|
|
case BIND_DENY:
|
|
|
|
classify_output->actionType = FWP_ACTION_BLOCK;
|
2022-04-12 21:37:44 +03:00
|
|
|
classify_output->rights &= ~FWPS_RIGHT_ACTION_WRITE;
|
|
|
|
break;
|
2023-09-20 22:31:54 +03:00
|
|
|
// If the program returns any other value, we will block the bind.
|
|
|
|
default:
|
|
|
|
classify_output->actionType = FWP_ACTION_BLOCK;
|
|
|
|
classify_output->rights &= ~FWPS_RIGHT_ACTION_WRITE;
|
|
|
|
break;
|
2021-09-14 00:46:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
net_ebpf_ext_resource_release_classify(
|
|
|
|
_In_ const FWPS_INCOMING_VALUES* incoming_fixed_values,
|
|
|
|
_In_ const FWPS_INCOMING_METADATA_VALUES* incoming_metadata_values,
|
|
|
|
_Inout_opt_ void* layer_data,
|
|
|
|
_In_opt_ const void* classify_context,
|
|
|
|
_In_ const FWPS_FILTER* filter,
|
|
|
|
uint64_t flow_context,
|
|
|
|
_Inout_ FWPS_CLASSIFY_OUT* classify_output)
|
|
|
|
{
|
|
|
|
SOCKADDR_IN addr = {AF_INET};
|
|
|
|
uint32_t result;
|
2024-07-15 19:23:51 +03:00
|
|
|
bind_context_header_t context_header = {0};
|
|
|
|
bind_md_t* ctx = &context_header.context;
|
2022-04-21 02:48:20 +03:00
|
|
|
net_ebpf_extension_wfp_filter_context_t* filter_context = NULL;
|
2021-09-14 00:46:43 +03:00
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(layer_data);
|
|
|
|
UNREFERENCED_PARAMETER(classify_context);
|
|
|
|
UNREFERENCED_PARAMETER(flow_context);
|
|
|
|
|
2022-06-29 03:52:54 +03:00
|
|
|
classify_output->actionType = FWP_ACTION_PERMIT;
|
|
|
|
|
2022-04-21 02:48:20 +03:00
|
|
|
filter_context = (net_ebpf_extension_wfp_filter_context_t*)filter->context;
|
|
|
|
ASSERT(filter_context != NULL);
|
2023-03-27 18:01:21 +03:00
|
|
|
if (filter_context == NULL) {
|
2022-04-21 02:48:20 +03:00
|
|
|
goto Exit;
|
2023-03-27 18:01:21 +03:00
|
|
|
}
|
2022-04-21 02:48:20 +03:00
|
|
|
|
2024-09-05 03:32:40 +03:00
|
|
|
// Note: This is intentionally not guarded by a lock as this is opportunistically checking if all the clients have
|
|
|
|
// detached and the filter context is being deleted.
|
|
|
|
if (filter_context->context_deleting) {
|
2023-11-30 03:07:44 +03:00
|
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(
|
|
|
|
NET_EBPF_EXT_TRACELOG_LEVEL_VERBOSE,
|
|
|
|
NET_EBPF_EXT_TRACELOG_KEYWORD_BIND,
|
|
|
|
"net_ebpf_ext_resource_release_classify - Client detach detected.",
|
|
|
|
STATUS_INVALID_PARAMETER);
|
2022-02-26 04:53:12 +03:00
|
|
|
goto Exit;
|
2023-03-27 18:01:21 +03:00
|
|
|
}
|
2022-02-26 04:53:12 +03:00
|
|
|
|
2021-09-14 00:46:43 +03:00
|
|
|
addr.sin_port = incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_RELEASE_V4_IP_LOCAL_PORT].value.uint16;
|
|
|
|
addr.sin_addr.S_un.S_addr =
|
|
|
|
incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_RELEASE_V4_IP_LOCAL_ADDRESS].value.uint32;
|
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
ctx->process_id = incoming_metadata_values->processId;
|
|
|
|
memcpy(&ctx->socket_address, &addr, sizeof(addr));
|
|
|
|
ctx->socket_address_length = sizeof(addr);
|
|
|
|
ctx->operation = BIND_OPERATION_UNBIND;
|
|
|
|
ctx->protocol = incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_RELEASE_V4_IP_PROTOCOL].value.uint8;
|
2021-09-14 00:46:43 +03:00
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
ctx->app_id_start =
|
2021-09-14 00:46:43 +03:00
|
|
|
incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_RELEASE_V4_ALE_APP_ID].value.byteBlob->data;
|
2024-07-15 19:23:51 +03:00
|
|
|
ctx->app_id_end =
|
|
|
|
ctx->app_id_start +
|
2021-09-14 00:46:43 +03:00
|
|
|
incoming_fixed_values->incomingValue[FWPS_FIELD_ALE_RESOURCE_RELEASE_V4_ALE_APP_ID].value.byteBlob->size;
|
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
_net_ebpf_ext_resource_truncate_appid(ctx);
|
2021-09-14 00:46:43 +03:00
|
|
|
|
2022-11-19 00:36:24 +03:00
|
|
|
// Ignore the result of this call as we don't want to block the unbind.
|
2024-09-05 03:32:40 +03:00
|
|
|
(void)net_ebpf_extension_hook_invoke_programs(ctx, filter_context, &result);
|
2021-09-14 00:46:43 +03:00
|
|
|
|
|
|
|
classify_output->actionType = FWP_ACTION_PERMIT;
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
return;
|
2023-01-10 22:22:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static ebpf_result_t
|
|
|
|
_ebpf_bind_context_create(
|
|
|
|
_In_reads_bytes_opt_(data_size_in) const uint8_t* data_in,
|
|
|
|
size_t data_size_in,
|
|
|
|
_In_reads_bytes_opt_(context_size_in) const uint8_t* context_in,
|
|
|
|
size_t context_size_in,
|
|
|
|
_Outptr_ void** context)
|
|
|
|
{
|
|
|
|
NET_EBPF_EXT_LOG_ENTRY();
|
|
|
|
ebpf_result_t result;
|
2024-07-15 19:23:51 +03:00
|
|
|
bind_context_header_t* context_header = NULL;
|
2023-01-10 22:22:20 +03:00
|
|
|
bind_md_t* bind_context = NULL;
|
|
|
|
|
|
|
|
*context = NULL;
|
|
|
|
|
|
|
|
if (context_in == NULL || context_size_in < sizeof(bind_md_t)) {
|
|
|
|
NET_EBPF_EXT_LOG_MESSAGE(
|
2023-05-02 09:24:46 +03:00
|
|
|
NET_EBPF_EXT_TRACELOG_LEVEL_ERROR, NET_EBPF_EXT_TRACELOG_KEYWORD_BIND, "Context is required");
|
2023-01-10 22:22:20 +03:00
|
|
|
result = EBPF_INVALID_ARGUMENT;
|
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
context_header = (bind_context_header_t*)ExAllocatePoolUninitialized(
|
|
|
|
NonPagedPoolNx, sizeof(bind_context_header_t), NET_EBPF_EXTENSION_POOL_TAG);
|
|
|
|
NET_EBPF_EXT_BAIL_ON_ALLOC_FAILURE_RESULT(
|
|
|
|
NET_EBPF_EXT_TRACELOG_KEYWORD_BIND, context_header, "bind_context", result);
|
2023-01-10 22:22:20 +03:00
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
bind_context = &context_header->context;
|
2023-01-10 22:22:20 +03:00
|
|
|
// Copy the context from the caller.
|
|
|
|
memcpy(bind_context, context_in, sizeof(bind_md_t));
|
|
|
|
|
|
|
|
// Replace the app_id_start and app_id_end with pointers to data_in.
|
|
|
|
bind_context->app_id_start = (uint8_t*)data_in;
|
|
|
|
bind_context->app_id_end = (uint8_t*)data_in + data_size_in;
|
|
|
|
|
|
|
|
*context = bind_context;
|
2024-07-15 19:23:51 +03:00
|
|
|
context_header = NULL;
|
2023-01-10 22:22:20 +03:00
|
|
|
result = EBPF_SUCCESS;
|
2023-08-29 22:26:03 +03:00
|
|
|
|
2023-01-10 22:22:20 +03:00
|
|
|
Exit:
|
2024-07-15 19:23:51 +03:00
|
|
|
if (context_header) {
|
|
|
|
ExFreePool(context_header);
|
|
|
|
context_header = NULL;
|
2023-01-10 22:22:20 +03:00
|
|
|
}
|
|
|
|
NET_EBPF_EXT_RETURN_RESULT(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ebpf_bind_context_destroy(
|
|
|
|
_In_opt_ void* context,
|
|
|
|
_Out_writes_bytes_to_(*data_size_out, *data_size_out) uint8_t* data_out,
|
|
|
|
_Inout_ size_t* data_size_out,
|
|
|
|
_Out_writes_bytes_to_(*context_size_out, *context_size_out) uint8_t* context_out,
|
|
|
|
_Inout_ size_t* context_size_out)
|
|
|
|
{
|
|
|
|
NET_EBPF_EXT_LOG_ENTRY();
|
|
|
|
|
|
|
|
bind_md_t* bind_context = (bind_md_t*)context;
|
|
|
|
bind_md_t* bind_context_out = (bind_md_t*)context_out;
|
2024-07-15 19:23:51 +03:00
|
|
|
bind_context_header_t* header = NULL;
|
2023-01-10 22:22:20 +03:00
|
|
|
|
|
|
|
if (!bind_context) {
|
2023-08-29 22:26:03 +03:00
|
|
|
goto Exit;
|
2023-01-10 22:22:20 +03:00
|
|
|
}
|
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
header = CONTAINING_RECORD(bind_context, bind_context_header_t, context);
|
|
|
|
|
2023-01-10 22:22:20 +03:00
|
|
|
if (context_out != NULL && *context_size_out >= sizeof(bind_md_t)) {
|
|
|
|
// Copy the context to the caller.
|
|
|
|
memcpy(bind_context_out, bind_context, sizeof(bind_md_t));
|
|
|
|
|
|
|
|
// Zero out the app_id_start and app_id_end.
|
|
|
|
bind_context_out->app_id_start = 0;
|
|
|
|
bind_context_out->app_id_end = 0;
|
|
|
|
*context_size_out = sizeof(bind_md_t);
|
|
|
|
} else {
|
|
|
|
*context_size_out = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy the app_id to the data_out.
|
|
|
|
if (data_out != NULL && *data_size_out >= (size_t)(bind_context->app_id_end - bind_context->app_id_start)) {
|
|
|
|
memcpy(data_out, bind_context->app_id_start, bind_context->app_id_end - bind_context->app_id_start);
|
|
|
|
*data_size_out = bind_context->app_id_end - bind_context->app_id_start;
|
|
|
|
} else {
|
|
|
|
*data_size_out = 0;
|
|
|
|
}
|
|
|
|
|
2024-07-15 19:23:51 +03:00
|
|
|
ExFreePool(header);
|
2023-08-29 22:26:03 +03:00
|
|
|
|
|
|
|
Exit:
|
2023-05-02 09:24:46 +03:00
|
|
|
NET_EBPF_EXT_LOG_EXIT();
|
2023-01-10 22:22:20 +03:00
|
|
|
}
|