Commit Graph

175 Commits

Author SHA1 Message Date
Jason A. Donenfeld
b71f64ae1c Use only multi-line comments
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
1d96af3b98 Account for device removal before initialization
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
248d4268df Use synchronize_rcu()-like semantics for exclusive transition lock
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
33cac1114c Fix up comment about replacement for ->Reserved
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
ae6e72a39e Simplify IRP processing after mapping
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
d82a68f830 Allow buffer mapping to happen concurrently
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
88bde5b28e Correct and simplify page locking
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
3d84bddcc0 Separate out MJ_CLOSE
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
de481cdb12 Manually clean up ugly corners 2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
5ec565c7e8 Improve designated initializers
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
5bbff1026f Add NDIS team's clang-format conventions
This needs clang-format 9. This reveals a lot of other things we should
clean up.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Link: https://community.osr.com/discussion/291376/clang-format-and-driver-code
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
007ea09d1b Map user buffer only once
This avoids needless page table modifications and also lets us enforce
having writable pages.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
d50cab5732 Consider receive NBLs to be immutable
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
be8d2cb071 Avoid allocating second MDL
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-07-03 08:50:30 +00:00
Simon Rozman
ca120aa1c0 Declare NDIS 6.83 compliant
After confirming with Microsoft Documentation that Wintun is already
NDIS 6.83 compliant, we declare it so.

In order to build NDIS 6.83 miniport driver, WDK for Windows 10, version
1903 is required: documentation updated.

https://docs.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-ndis-6-81
https://docs.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-ndis-6-82
https://docs.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-ndis-6-83

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-07-03 08:50:30 +00:00
Simon Rozman
de2c48db84 Make NDIS 6.80 compliant
Implement support for synchronous OID requests and declare the Wintun as
NDIS 6.80 compliant.

https://docs.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-ndis-6-80

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-07-03 08:50:30 +00:00
Simon Rozman
c394368e88 Declare NDIS 6.70 compliant
After confirming with Microsoft Documentation that Wintun is already
NDIS 6.70 compliant, we declare it so.

Furthermore, determine NDIS version bounds from NDISxxx_MINIPORT
automatically.

https://docs.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-ndis-6-40
https://docs.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-ndis-6-50
https://docs.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-ndis-6-60
https://docs.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-ndis-6-70

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-07-03 08:50:30 +00:00
Jason A. Donenfeld
e4831b2011 Use ULONG instead of ptrdiff_t for length measurement
Even though we're comparing this with a ptrdiff_t in one place and
adding it to a void* in another place, it's still a length and as such
should be a size_t, which I guess in our weird universe here is a ULONG.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-21 12:20:33 +02:00
Jason A. Donenfeld
dea5bfa2d2 Synchronize accesses to MiniportAdapterHandle
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-20 15:17:36 +00:00
Simon Rozman
17572da83e Adopt "Tun" namespace at global AdapterCount variable
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 13:42:35 +02:00
Simon Rozman
faf810e8cb Fix NdisQueryMdl() NULL-buffer check
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 12:00:21 +02:00
Simon Rozman
9514ef37b3 Save some valuable lessons learned on Windows internals
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:58 +02:00
Simon Rozman
da3caadf48 Accept IRP_MJ_WRITE when paused but silently drop the packets
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:58 +02:00
Simon Rozman
7004db43a7 Support surprise removal
WHLK 1903 CHAOS tests are reporting lots of issues regarding surprise
removal misbehavior:

WDTF_PNP: INFO  : Result: TestSurpriseRemove operation timed out waiting
   for IRP_MN_REMOVE_DEVICE..
WDTF_PNP: ERROR : Result: Failed to receive IRP_MN_REMOVE_DEVICE after
   receiving IRP_MN_SURPRISE_REMOVAL. Ensure that there are no open
   handles or references to the test device (in user mode or in kernel
   mode) preventing IRP_MN_REMOVE_DEVICE from being sent. You may need
   to terminate any processes or services that may have open user mode
   handles to this device.  ( 80004005 ).

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:58 +02:00
Simon Rozman
85b4a769cf Replace PnP notifications with IRP_MJ_PNP dispatch handler
By replacing the NDIS' IRP_MJ_PNP dispatch handler we get the first
chance to clear the NBL queue to make NDIS proceed to TunPause() on
device removal.

This method is simpler than PnP notifications and we are chasing
surprise removal issues in WHLK tests. If this works, I'll hopefully
come back and update this commit message.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:58 +02:00
Simon Rozman
6b0293b18b Distinguish NDIS_STATUS and NTSTATUS
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:58 +02:00
Simon Rozman
b07c268e0c Implement proper PnP notification re-registration on canceled removal
The Microsoft Documentation is clear:

"The PnP manager can still call the driver's notification callback
routine, but in such calls the file object in the NotificationStructure
is not valid."[1]

Therefore, we must not touch the notification->FileObject in
GUID_TARGET_DEVICE_REMOVE_CANCELLED.

"Because the driver closed the previous registration handle in response
to the query-remove notification, the driver must open a new handle. The
driver must:

1. Remove the old registration with IoUnregisterPlugPlayNotification.
2. Open a new handle to the device.
3. Reregister for notification on the new handle with
   IoRegisterPlugPlayNotification."

Therefore, let's do it. Unfortunately, in order to implement this, we
must save the driver object and device symbolic name.

[1](https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/handling-a-guid-target-device-query-remove-event)
[2](https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/handling-a-guid-target-device-remove-cancelled-event)

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:58 +02:00
Simon Rozman
838251780e Rename ActiveTransactionCount to ActiveNBLCount
As ActiveTransacrionCount is all about counting NBLs in flight (or just
about to push some more NBLs), rename it to a more suitable name.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:58 +02:00
Simon Rozman
e3dfeeb2be Reuse Device.RefCount value to prevent duplicate status indications
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:57 +02:00
Simon Rozman
54ee02ae34 Fix the cleanup order in TunDispatchWrite()
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:57 +02:00
Simon Rozman
dc7a6fca11 Cleanup ref-counting overflow asserts
Asserting on 63-bit overflow seems a bit excessive.

While 31-bit overflow is more likely to happen, we should introduce a
real check if we are concerned about it. Rather than using an ASSERT in
Debug configuration run by probably nobody else but me.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:57 +02:00
Simon Rozman
70fcfdc85d Add missing state transition lock
When we are transitioning to a state that suspends some operations, we
must get an exclusive transition lock to wait for all operations that
have a shared transition lock. And TunHaltEx() is no exception.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:57 +02:00
Simon Rozman
60e103cad3 Revise adapter state checking
TunCheckForPause() was inlined and adjusted: it had two calls with two
potential new ones, but each call would have a slightly different
optimal variant: some with ActiveTransactionCount increment, others
without; some with Device.RefCount check, others without... No two
particular use cases were completely identical:

1. TunSendNetBufferLists:
   - requires ActiveTransactionCount increment
   - requires Device.RefCount > 0 check
   - reports NDIS_STATUS in case of rejection
2. IRP_MJ_READ:
   - no ActiveTransactionCount increment
   - no Device.RefCount > 0 check, as IRP_MJ_READ implies it
   - reports NTSTATUS in case of rejection
3. IRP_MJ_WRITE:
   - requires ActiveTransactionCount increment
   - no Device.RefCount > 0 check, as IRP_MJ_WRITE implies it
   - reports NTSTATUS in case of rejection
4. IRP_MJ_CREATE:
   - no ActiveTransactionCount increment
   - no Device.RefCount > 0 check to allow initial client connection
   - reports NTSTATUS in case of rejection, with slightly different
     status codes than IRP_MJ_READ and IRP_MJ_WRITE.

TUN_FLAGS_ENABLED was renamed to TUN_FLAGS_RUNNING: enabled/disabled
adapter means initialized&running/paused&halted in Windows world.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:57 +02:00
Simon Rozman
8162297c15 Count active transactions in NBLs rather than IRPs in receive direction
This makes ActiveTransactionCount a sum of:
- 1: initialized in TunRestart()
- count of NBLs in send queue
- count of NBLs in receive queue
- TunSendNetBufferLists() unfinished
- IRP_MJ_WRITE unfinished

Mind that we do not need to explicitly check for TUN_FLAGS_PRESENT early
in IRP_MJ_WRITE as it is implicitly checked by TunCheckForPause() along
with other flags required to run the packet flow. The later is actually
more correct by being shared-locked by the transition lock.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:57 +02:00
Simon Rozman
47cde0f340 Cleanup adapter power monitoring
Wintun adapter is always paused before transition to a low-power state.
Even on NDIS 6.30 we do not specify the NDIS_MINIPORT_ATTRIBUTES_NO_-
PAUSE_ON_SUSPEND flag. Since OID_PNP_SET_POWER does not do anything else
that TunPause() already takes care of it is redundant. The
TUN_FLAGS_ENABLED and TUN_FLAGS_POWERED were also mostly identical.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:56 +02:00
Simon Rozman
bce44d30e4 Use more appropriate status when rejecting NBLs with no client connected
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:56 +02:00
Simon Rozman
2392d173e7 Restore adapter on PnP remove-cancel and reuse notification file object
In case target device removal was canceled, the adapter is now restored
to present state. This is a part of research why Wintun adapters are
misbehaving in some WHLK tests.

PnP notifications already provide FILE_OBJECT of the device we are
monitoring. We don't need to store it in adapter context.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:56 +02:00
Simon Rozman
5c8dafcb3f Simplify state machine
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:54:56 +02:00
Sergei Mileshin
a530bb1b84 Set deny-all DACL instead of removing symlink on halting
Deleting symbolic link on device removal only still makes it possible to
open it from the real path.

Setting the deny-all DACL instead is a more reliable way of preventing
clients reopening the device when it is being removed.

Signed-off-by: Sergei Mileshin <msvsysproger@gmail.com>
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 11:53:08 +02:00
Simon Rozman
2e744ebde5 Revise buffer size calculation to work across 32/64-bit boundary
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-10 16:59:03 +02:00
Jason A. Donenfeld
c7fbe74d0e Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-08 09:04:47 +00:00
Jason A. Donenfeld
12e9f53fe2 Do not take handle reference with verifier enabled
This is actually very much wrong. In fact, it's bound to create all
sorts of nasty issues. But without it, we can't use the reference
function to check the validity of a potentially invalid handle while the
verifier is enabled.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-08 09:04:32 +00:00
Simon Rozman
c848006144 Clean TunWaitForReferencesToDropToZero()
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-08 08:14:07 +02:00
Simon Rozman
5c2a9a991e Refactor IRP_MJ_CLOSE TransitionLock unlocking
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-08 08:14:07 +02:00
Jason A. Donenfeld
9ee4310026 Document toolchain requirement
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2019-06-07 13:53:44 +02:00
Simon Rozman
ced1bcdd52 Reorder source code
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-07 13:05:57 +02:00
Simon Rozman
bbbe72ce84 Remove documentation files from project file
...they are part of solution now.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-07 13:05:57 +02:00
Simon Rozman
b6de71ffcd Add wintun.sln for convenience
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-07 13:05:57 +02:00
Simon Rozman
2a5da5c58f Revise constants requiring network-byte order
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-07 12:28:07 +02:00
Simon Rozman
9a815147f6 Annotate service control constants
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-07 12:28:07 +02:00