Fix ActiveNBLCount management in TunDispatchWrite()
The ActiveNBLCount must be bumped _before_ adapter state is checked. Otherwise, there is a window of code that may allow adapter transition from pausing to paused state, followed by a NdisMIndicateReceiveNetBufferLists() call. Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
999cfaabcc
commit
2e35974a24
7
wintun.c
7
wintun.c
@ -459,6 +459,8 @@ static NTSTATUS TunDispatchWrite(DEVICE_OBJECT *DeviceObject, IRP *Irp)
|
|||||||
b += p_size;
|
b += p_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InterlockedAdd64(&ctx->ActiveNBLCount, nbl_count);
|
||||||
|
|
||||||
BOOLEAN update_statistics = TRUE;
|
BOOLEAN update_statistics = TRUE;
|
||||||
if ((status = STATUS_NDIS_PAUSED, InterlockedGet((LONG *)&ctx->State) != TUN_STATE_RUNNING) ||
|
if ((status = STATUS_NDIS_PAUSED, InterlockedGet((LONG *)&ctx->State) != TUN_STATE_RUNNING) ||
|
||||||
(status = STATUS_NDIS_LOW_POWER_STATE, ctx->PowerState >= NdisDeviceStateD1)) {
|
(status = STATUS_NDIS_LOW_POWER_STATE, ctx->PowerState >= NdisDeviceStateD1)) {
|
||||||
@ -501,10 +503,7 @@ static NTSTATUS TunDispatchWrite(DEVICE_OBJECT *DeviceObject, IRP *Irp)
|
|||||||
* to make it work correctly. (2) seems like an acceptable stopgap solution until we're smart enough to reason about
|
* to make it work correctly. (2) seems like an acceptable stopgap solution until we're smart enough to reason about
|
||||||
* (1). So, let's implement (2) now, and we'll let more knowledgeable people advise us on (1) later.
|
* (1). So, let's implement (2) now, and we'll let more knowledgeable people advise us on (1) later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
InterlockedAdd64(&ctx->ActiveNBLCount, nbl_count);
|
|
||||||
NdisMIndicateReceiveNetBufferLists(ctx->MiniportAdapterHandle, nbl_head, NDIS_DEFAULT_PORT_NUMBER, nbl_count, NDIS_RECEIVE_FLAGS_RESOURCES);
|
NdisMIndicateReceiveNetBufferLists(ctx->MiniportAdapterHandle, nbl_head, NDIS_DEFAULT_PORT_NUMBER, nbl_count, NDIS_RECEIVE_FLAGS_RESOURCES);
|
||||||
TunCompletePausing(ctx, nbl_count);
|
|
||||||
|
|
||||||
cleanup_nbl_head:
|
cleanup_nbl_head:
|
||||||
for (NET_BUFFER_LIST *nbl = nbl_head, *nbl_next; nbl; nbl = nbl_next) {
|
for (NET_BUFFER_LIST *nbl = nbl_head, *nbl_next; nbl; nbl = nbl_next) {
|
||||||
@ -525,6 +524,8 @@ cleanup_nbl_head:
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup_statistics:
|
cleanup_statistics:
|
||||||
|
TunCompletePausing(ctx, nbl_count);
|
||||||
|
|
||||||
InterlockedAdd64((LONG64 *)&ctx->Statistics.ifHCInOctets, stat_size);
|
InterlockedAdd64((LONG64 *)&ctx->Statistics.ifHCInOctets, stat_size);
|
||||||
InterlockedAdd64((LONG64 *)&ctx->Statistics.ifHCInUcastOctets, stat_size);
|
InterlockedAdd64((LONG64 *)&ctx->Statistics.ifHCInUcastOctets, stat_size);
|
||||||
InterlockedAdd64((LONG64 *)&ctx->Statistics.ifHCInUcastPkts, stat_p_ok);
|
InterlockedAdd64((LONG64 *)&ctx->Statistics.ifHCInUcastPkts, stat_p_ok);
|
||||||
|
Loading…
Reference in New Issue
Block a user