Driver: Fix blocking existing flows for reauth.

Workaround for FwpsFlowAssociateContext0(), which doesn't work after FWP_CONDITION_FLAG_IS_REAUTHORIZE.
This commit is contained in:
Nodir Temirkhodjaev 2018-12-26 19:47:13 +05:00
parent 407c1cf85c
commit 4cf021d1c5
2 changed files with 21 additions and 9 deletions

View File

@ -35,7 +35,6 @@ typedef struct fort_conf_ref {
typedef struct fort_device { typedef struct fort_device {
UINT32 prov_boot : 1; UINT32 prov_boot : 1;
UINT32 is_opened : 1; UINT32 is_opened : 1;
UINT32 was_conf : 1;
UINT32 power_off : 1; UINT32 power_off : 1;
UINT32 connect4_id; UINT32 connect4_id;
@ -133,7 +132,6 @@ fort_conf_ref_set (PFORT_CONF_REF conf_ref)
const PFORT_CONF_FLAGS conf_flags = &conf_ref->conf.flags; const PFORT_CONF_FLAGS conf_flags = &conf_ref->conf.flags;
g_device->prov_boot = conf_flags->prov_boot; g_device->prov_boot = conf_flags->prov_boot;
g_device->was_conf = TRUE;
g_device->conf_flags = *conf_flags; g_device->conf_flags = *conf_flags;
} else { } else {
@ -289,8 +287,7 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
conf_ref = fort_conf_ref_take(); conf_ref = fort_conf_ref_take();
if (conf_ref == NULL) { if (conf_ref == NULL) {
if (g_device->prov_boot || ((flags & FWP_CONDITION_FLAG_IS_REAUTHORIZE) if (g_device->prov_boot) {
&& !g_device->was_conf)) { /* Block existing flows after driver installation to use flow-contexts */
fort_callout_classify_block(classifyOut); fort_callout_classify_block(classifyOut);
} else { } else {
fort_callout_classify_continue(classifyOut); fort_callout_classify_continue(classifyOut);
@ -322,13 +319,17 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
const UINT64 flowId = inMetaValues->flowHandle; const UINT64 flowId = inMetaValues->flowHandle;
const UCHAR group_index = fort_conf_app_group_index( const UCHAR group_index = fort_conf_app_group_index(
&conf_ref->conf, app_index); &conf_ref->conf, app_index);
const BOOL is_reauth = (flags & FWP_CONDITION_FLAG_IS_REAUTHORIZE);
BOOL is_new_proc = FALSE; BOOL is_new_proc = FALSE;
NTSTATUS status; NTSTATUS status;
status = fort_stat_flow_associate(&g_device->stat, status = fort_stat_flow_associate(&g_device->stat,
flowId, process_id, group_index, &is_new_proc); flowId, process_id, group_index, is_reauth, &is_new_proc);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
if (status == FORT_STATUS_FLOW_BLOCK)
goto block;
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: Classify v4: Flow assoc. error: %x\n", status); "FORT: Classify v4: Flow assoc. error: %x\n", status);
} else if (is_new_proc) { } else if (is_new_proc) {

View File

@ -5,6 +5,8 @@
#define FORT_PROC_BAD_INDEX ((UINT16) -1) #define FORT_PROC_BAD_INDEX ((UINT16) -1)
#define FORT_PROC_COUNT_MAX 0x7FFF #define FORT_PROC_COUNT_MAX 0x7FFF
#define FORT_STATUS_FLOW_BLOCK STATUS_NOT_SAME_DEVICE
typedef struct fort_stat_traf { typedef struct fort_stat_traf {
union { union {
struct { struct {
@ -300,13 +302,17 @@ fort_stat_flow_free (PFORT_STAT stat, PFORT_STAT_FLOW flow)
static NTSTATUS static NTSTATUS
fort_stat_flow_add (PFORT_STAT stat, UINT64 flow_id, fort_stat_flow_add (PFORT_STAT stat, UINT64 flow_id,
UCHAR group_index, UINT16 proc_index, UCHAR group_index, UINT16 proc_index,
BOOL speed_limit) BOOL speed_limit, BOOL is_reauth)
{ {
const tommy_key_t flow_hash = fort_stat_flow_hash(flow_id); const tommy_key_t flow_hash = fort_stat_flow_hash(flow_id);
PFORT_STAT_FLOW flow = fort_stat_flow_get(stat, flow_id, flow_hash); PFORT_STAT_FLOW flow = fort_stat_flow_get(stat, flow_id, flow_hash);
BOOL is_new_flow = FALSE; BOOL is_new_flow = FALSE;
if (flow == NULL) { if (flow == NULL) {
if (is_reauth) {
return FORT_STATUS_FLOW_BLOCK; /* Block existing flow after reauth. to be able to use flow-context */
}
if (stat->flow_free != NULL) { if (stat->flow_free != NULL) {
flow = stat->flow_free; flow = stat->flow_free;
stat->flow_free = flow->next; stat->flow_free = flow->next;
@ -421,7 +427,7 @@ fort_stat_update_limits (PFORT_STAT stat, PFORT_CONF_IO conf_io)
static NTSTATUS static NTSTATUS
fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id, fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
UINT32 process_id, UCHAR group_index, UINT32 process_id, UCHAR group_index,
BOOL *is_new_proc) BOOL is_reauth, BOOL *is_new_proc)
{ {
const tommy_key_t proc_hash = fort_stat_proc_hash(process_id); const tommy_key_t proc_hash = fort_stat_proc_hash(process_id);
KLOCK_QUEUE_HANDLE lock_queue; KLOCK_QUEUE_HANDLE lock_queue;
@ -432,13 +438,18 @@ fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue); KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
if (!stat->log_stat) { if (!stat->log_stat) {
status = STATUS_RESOURCE_REQUIREMENTS_CHANGED; status = STATUS_DEVICE_DATA_ERROR;
goto end; goto end;
} }
proc = fort_stat_proc_get(stat, process_id, proc_hash); proc = fort_stat_proc_get(stat, process_id, proc_hash);
if (proc == NULL) { if (proc == NULL) {
if (is_reauth) {
status = FORT_STATUS_FLOW_BLOCK; /* Block existing flow after reauth. to be able to use flow-context */
goto end;
}
proc = fort_stat_proc_add(stat, process_id); proc = fort_stat_proc_add(stat, process_id);
if (proc == NULL) { if (proc == NULL) {
@ -452,7 +463,7 @@ fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
speed_limit = fort_stat_group_speed_limit(stat, group_index) != 0; speed_limit = fort_stat_group_speed_limit(stat, group_index) != 0;
status = fort_stat_flow_add(stat, flow_id, status = fort_stat_flow_add(stat, flow_id,
group_index, proc->proc_index, speed_limit); group_index, proc->proc_index, speed_limit, is_reauth);
if (!NT_SUCCESS(status) && *is_new_proc) { if (!NT_SUCCESS(status) && *is_new_proc) {
fort_stat_proc_free(stat, proc); fort_stat_proc_free(stat, proc);