Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[netebpfext] Add deleted filter contexts to zombie list for debugging purposes #4003

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion netebpfext/net_ebpf_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ static bool _net_ebpf_xdp_providers_registered = false;
static bool _net_ebpf_bind_providers_registered = false;
static bool _net_ebpf_sock_addr_providers_registered = false;
static bool _net_ebpf_sock_ops_providers_registered = false;
#ifdef _DEBUG
// Global objects used to store filter contexts that are being cleaned up. This is currently only used in debug
// contexts.
EX_SPIN_LOCK _net_ebpf_filter_zombie_list_lock = {0};
static LIST_ENTRY _net_ebpf_filter_zombie_list = {0};
#endif // _DEBUG

static net_ebpf_ext_sublayer_info_t _net_ebpf_ext_sublayers[] = {
{&EBPF_DEFAULT_SUBLAYER, L"EBPF Sub-Layer", L"Sub-Layer for use by eBPF callouts", 0, SUBLAYER_WEIGHT_MAXIMUM},
Expand Down Expand Up @@ -902,6 +908,10 @@ net_ebpf_ext_register_providers()
}
_net_ebpf_sock_ops_providers_registered = true;

#ifdef _DEBUG
InitializeListHead(&_net_ebpf_filter_zombie_list);
#endif // _DEBUG

Exit:
if (!NT_SUCCESS(status)) {
net_ebpf_ext_unregister_providers();
Expand Down Expand Up @@ -996,4 +1006,24 @@ net_ebpf_ext_remove_client_context(
}

ExReleaseSpinLockExclusive(&filter_context->lock, old_irql);
}
}

#ifdef _DEBUG
void
net_ebpf_ext_add_filter_context_to_zombie_list(_Inout_ net_ebpf_extension_wfp_filter_context_t* filter_context)
{
KIRQL old_irql = ExAcquireSpinLockExclusive(&_net_ebpf_filter_zombie_list_lock);
InsertHeadList(&_net_ebpf_filter_zombie_list, &filter_context->link);
ExReleaseSpinLockExclusive(&_net_ebpf_filter_zombie_list_lock, old_irql);
}

void
net_ebpf_ext_remove_filter_context_from_zombie_list(_Inout_ net_ebpf_extension_wfp_filter_context_t* filter_context)
{
if (!IsListEmpty(&filter_context->link)) {
KIRQL old_irql = ExAcquireSpinLockExclusive(&_net_ebpf_filter_zombie_list_lock);
RemoveEntryList(&filter_context->link);
ExReleaseSpinLockExclusive(&_net_ebpf_filter_zombie_list_lock, old_irql);
}
}
#endif // _DEBUG
37 changes: 36 additions & 1 deletion netebpfext/net_ebpf_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,22 @@ typedef struct _net_ebpf_extension_wfp_filter_context
HANDLE wfp_engine_handle; ///< WFP engine handle.
} net_ebpf_extension_wfp_filter_context_t;

#ifdef _DEBUG
#define CLEAN_UP_FILTER_CONTEXT(filter_context) \
if ((filter_context) != NULL) { \
if ((filter_context)->filter_ids != NULL) { \
ExFreePool((filter_context)->filter_ids); \
} \
if ((filter_context)->client_contexts != NULL) { \
ExFreePool((filter_context)->client_contexts); \
} \
if ((filter_context)->wfp_engine_handle != NULL) { \
FwpmEngineClose((filter_context)->wfp_engine_handle); \
} \
net_ebpf_ext_remove_filter_context_from_zombie_list((filter_context)); \
ExFreePool((filter_context)); \
matthewige marked this conversation as resolved.
Show resolved Hide resolved
}
#else
#define CLEAN_UP_FILTER_CONTEXT(filter_context) \
if ((filter_context) != NULL) { \
if ((filter_context)->filter_ids != NULL) { \
Expand All @@ -156,6 +172,7 @@ typedef struct _net_ebpf_extension_wfp_filter_context
} \
ExFreePool((filter_context)); \
}
#endif

#define REFERENCE_FILTER_CONTEXT(filter_context) \
if ((filter_context) != NULL) { \
Expand Down Expand Up @@ -379,4 +396,22 @@ net_ebpf_ext_remove_client_context(
ebpf_result_t
net_ebpf_ext_add_client_context(
_Inout_ net_ebpf_extension_wfp_filter_context_t* filter_context,
_In_ const struct _net_ebpf_extension_hook_client* hook_client);
_In_ const struct _net_ebpf_extension_hook_client* hook_client);

#ifdef _DEBUG
/**
* @brief Add the filter context to the zombie list.
*
* @param filter_context Filter context to add to the zombie list.
*/
void
net_ebpf_ext_add_filter_context_to_zombie_list(_Inout_ net_ebpf_extension_wfp_filter_context_t* filter_context);

/**
* @brief Remove the filter context from the zombie list.
*
* @param filter_context Filter context to remove from the zombie list.
*/
void
net_ebpf_ext_remove_filter_context_from_zombie_list(_Inout_ net_ebpf_extension_wfp_filter_context_t* filter_context);
#endif // _DEBUG
6 changes: 6 additions & 0 deletions netebpfext/net_ebpf_ext_hook_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,8 +610,14 @@ _Requires_exclusive_lock_held_(provider_context->lock) static void _net_ebpf_ext
{
NET_EBPF_EXT_LOG_ENTRY();

// Remove the list entry from the provider's list of filter contexts.
RemoveEntryList(&filter_context->link);

#ifdef _DEBUG
// Add the entry to the zombie list (for debugging purposes)
net_ebpf_ext_add_filter_context_to_zombie_list(filter_context);
#endif // _DEBUG

// Release the filter context.
provider_context->dispatch.delete_filter_context(filter_context);

Expand Down
Loading