diff --git a/src/Source.def b/src/Source.def index 7d4d4ac..8de8b6d 100644 --- a/src/Source.def +++ b/src/Source.def @@ -6,12 +6,15 @@ LIBRARY EXPORTS FwpmCalloutAdd0 + FwpmCalloutDeleteByKey0 FwpmEngineClose0 FwpmEngineOpen0 FwpmFilterAdd0 FwpmFilterDeleteById0 FwpmProviderAdd0 + FwpmProviderDeleteByKey0 FwpmSubLayerAdd0 + FwpmSubLayerDeleteByKey0 FwpmTransactionAbort0 FwpmTransactionBegin0 FwpmTransactionCommit0 diff --git a/src/fwp_um.cpp b/src/fwp_um.cpp index 75e5154..ef80d3d 100644 --- a/src/fwp_um.cpp +++ b/src/fwp_um.cpp @@ -265,7 +265,7 @@ fwp_engine_t::test_cgroup_inet4_connect(_In_ fwp_classify_parameters_t* paramete action = test_callout( FWPS_LAYER_ALE_CONNECT_REDIRECT_V4, FWPM_LAYER_ALE_CONNECT_REDIRECT_V4, _default_sublayer, incoming_value); - CXPLAT_DEBUG_ASSERT(action == FWP_ACTION_PERMIT || action == FWP_ACTION_CONTINUE || fault_injection_enabled); + CXPLAT_DEBUG_ASSERT(action == FWP_ACTION_PERMIT || action == FWP_ACTION_CONTINUE || fault_injection_enabled); if (_fwp_um_connect_request != nullptr) { redirected = @@ -502,6 +502,20 @@ _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS FwpmCalloutAdd0( return STATUS_SUCCESS; } +_IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS FwpmCalloutDeleteByKey0(_In_ HANDLE engine_handle, _In_ const GUID* key) +{ + if (cxplat_fault_injection_inject_fault()) { + return STATUS_NO_MEMORY; + } + + auto& engine = *reinterpret_cast(engine_handle); + + if (!engine.remove_fwpm_callout(key)) { + return STATUS_NOT_FOUND; + } + return STATUS_SUCCESS; +} + _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS FwpmEngineOpen0( _In_opt_ const wchar_t* server_name, _In_ uint32_t authn_service, @@ -537,6 +551,22 @@ _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS return STATUS_SUCCESS; } +_IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS FwpmProviderDeleteByKey0(_In_ HANDLE engine_handle, _In_ const GUID* key) +{ + if (cxplat_fault_injection_inject_fault()) { + return STATUS_NO_MEMORY; + } + + auto& engine = *reinterpret_cast(engine_handle); + + engine.remove_fwpm_provider(key); + if (cxplat_fault_injection_inject_fault()) { + return STATUS_NOT_FOUND; + } + + return STATUS_SUCCESS; +} + _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS FwpmSubLayerAdd0(_In_ HANDLE engine_handle, _In_ const FWPM_SUBLAYER0* sub_layer, _In_opt_ PSECURITY_DESCRIPTOR sd) { @@ -552,6 +582,21 @@ _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS return STATUS_SUCCESS; } +_IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS + FwpmSubLayerDeleteByKey0(_In_ HANDLE engine_handle, _In_ const GUID* sub_layer_key) +{ + if (cxplat_fault_injection_inject_fault()) { + return STATUS_NO_MEMORY; + } + + auto& engine = *reinterpret_cast(engine_handle); + + if (!engine.remove_fwpm_sub_layer(sub_layer_key)) { + return STATUS_NOT_FOUND; + } + return STATUS_SUCCESS; +} + _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS FwpmEngineClose0(_Inout_ HANDLE engine_handle) { if (cxplat_fault_injection_inject_fault()) { diff --git a/src/fwp_um.h b/src/fwp_um.h index 30ade63..8b13857 100644 --- a/src/fwp_um.h +++ b/src/fwp_um.h @@ -41,6 +41,19 @@ typedef class fwp_engine_t return fwpm_callouts.erase(id) == 1; } + bool + remove_fwpm_callout(_In_ const GUID* key) + { + exclusive_lock_t l(lock); + for (auto& [first, callout] : fwpm_callouts) { + if (memcmp(&callout.calloutKey, key, sizeof(GUID)) == 0) { + return fwpm_callouts.erase(first) == 1; + } + } + + return false; + } + uint32_t register_fwps_callout(_In_ const FWPS_CALLOUT3* callout) { @@ -169,6 +182,12 @@ typedef class fwp_engine_t return; } + _Requires_lock_not_held_(this->lock) void remove_fwpm_provider(_In_ const GUID* key) + { + UNREFERENCED_PARAMETER(key); + return; + } + _Requires_lock_not_held_(this->lock) uint32_t add_fwpm_sub_layer(_In_ const FWPM_SUBLAYER0* sub_layer) { exclusive_lock_t l(lock); @@ -183,6 +202,18 @@ typedef class fwp_engine_t return fwpm_sub_layers.erase(id) == 1; } + _Requires_lock_not_held_(this->lock) bool remove_fwpm_sub_layer(_In_ const GUID* key) + { + exclusive_lock_t l(lock); + for (auto& [first, sub_layer] : fwpm_sub_layers) { + if (memcmp(&sub_layer.subLayerKey, key, sizeof(GUID)) == 0) { + return fwpm_sub_layers.erase(first) == 1; + } + } + + return false; + } + FWP_ACTION_TYPE classify_test_packet(_In_ const GUID* layer_guid, NET_IFINDEX if_index);