aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* version: bumpHEAD1.0masterJason A. Donenfeld5 hours1-2/+2
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: use /DECLSPEC_ALIGN(n) instead of __declspec(align(n))Jason A. Donenfeld5 hours6-15/+15
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: enable /std:clatest and use typeofJason A. Donenfeld32 hours17-74/+71
| | | | | | | | | | | | | | Use C23 typeof to eliminate redundant type parameters from the RCU macros. Also, drop mention of hoping to use alignas in TODO.md. It only goes on members of structs, not the struct type itself, which I find syntactically annoying, and it doesn't really confer any additional real benefits. Moving to C23 means that we must use __VA_OPT__. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: nsi: filter \Device\Nsi instead of polling in threadJason A. Donenfeld32 hours7-156/+433
| | | | | | | | | | | | | | | | | This restores 217922a ("driver: device: hack around broken IP notifier by hijacking \Device\Nsi"), but does it right, hopefully. Since we're attaching to \Device\Nsi as a filter, we increment the refcount of the driver, which means Unload doesn't get called until we detach filtering. So we attach and detach on first and last device creation and destruction. A limitation of the old commit is that it missed notifications from netsh, because netsh sets the subinterface mtu, not the interface mtu. I've now updated the code to catch both updates. For WireGuard, they are effectively the same. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: containers: tiny SAL nitJason A. Donenfeld32 hours1-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: crypto: zero state on MDL failureJason A. Donenfeld32 hours1-5/+6
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: socket: allow retrying WskInit if it fails for the first userJason A. Donenfeld32 hours1-1/+0
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: timers: set pending false before executing callbackJason A. Donenfeld32 hours1-1/+1
| | | | | | This makes the re-arm logic work better. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: memory: fix bad parens in NT_SUCCESSJason A. Donenfeld32 hours1-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: device: check ndis version firstJason A. Donenfeld32 hours1-6/+6
| | | | | | This avoids having to cleanup if the version is wrong. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: receive: don't increment both discards and errorsJason A. Donenfeld32 hours2-9/+9
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: receive: require exact header lengthsJason A. Donenfeld32 hours1-6/+7
| | | | | | | | | This matches the behavior on Linux and other operating systems. Before, you could append a bunch of cruft, which would then not get copied to the header, while the MAC checker would still look at the end of the NBL, hashing garbage. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: socket: use FIELD_SIZE instead of RTL_FIELD_SIZEJason A. Donenfeld32 hours1-4/+4
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: socket: reset event object before reuseJason A. Donenfeld32 hours1-0/+2
| | | | | | | | | | | | | Bad flow: - new event, Done - first op finishes sync, so STATUS_SUCCESS, which isn't pending, Done isn't consumed. - next op finishes async, so STATUS_PENDING, so we wait on it, but it's already consumed from before, so it doesn't wait. Fix this the easy way by always resetting the event always. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: socket: free table if mem allocation failsJason A. Donenfeld32 hours1-1/+3
| | | | | | Otherwise we leak table. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: socket: reset v4 port when retrying on conflictJason A. Donenfeld32 hours1-0/+1
| | | | | | | | If port 0 is passed, for a random port, it gets assigned on v4 allocation, and then can fail on v6 allocation it's already in use. In that case, set the port back to 0 so that it can try a new random port. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: do not leak socket owner processJason A. Donenfeld33 hours1-0/+7
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: set allowedips flags to 0Jason A. Donenfeld33 hours1-0/+1
| | | | | | This is better than returning garbage, in case we extend this later. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: mark the unsafe allowedip pointer as volatileJason A. Donenfeld33 hours1-2/+2
| | | | | | That's what we do for the others, so why not this one? Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: try using NdisWdfGetAdapterContextFromAdapterHandle againJason A. Donenfeld33 hours4-25/+20
| | | | | | | | | | | | The issue faced by 4309390 ("driver: ioctl: restore usage of FunctionalDeviceObject->Reserved") wasn't that Windows 10 RTM didn't have NdisWdfGetAdapterContextFromAdapterHandle(), but rather that DispatchPnp was being called very early with a different device object. We can fix this by simply testing to see if we have the right type of device. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: settle on using DeviceObject->ReservedJason A. Donenfeld33 hours3-16/+2
| | | | | | | | | | Further experiments with NdisWdfGetAdapterContextFromAdapterHandle indicate it's probably less reliable than using ->Reserved, because it means dereferencing DeviceExension. Also get rid of the awkward IoctlHalt. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: fix whitespace errorJason A. Donenfeld33 hours1-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: adapter: don't set DriverRequired on stub deviceJason A. Donenfeld33 hours1-2/+1
| | | | | | | | | The stub device only exists momentarily to create the software registry key for SuggestedInstanceId. Setting SWDeviceCapabilitiesDriverRequired with empty hardware IDs violates the SwDeviceCreate API contract and causes PnP to needlessly search for a driver for this transient device. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: adapter: capture LastError from failed allocationJason A. Donenfeld33 hours1-0/+6
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: adapter: take into account QueueUserWorkItem failingJason A. Donenfeld33 hours1-1/+4
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: driver: skip restore when snapshot failedJason A. Donenfeld33 hours1-8/+11
| | | | | | | | If SnapshotConfigurationAndState fails, Configuration is left NULL, but RestoreConfigurationAndState was called unconditionally, passing the NULL pointer to DeviceIoControl. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: driver: don't log potentially uninitialized temp dirJason A. Donenfeld33 hours1-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: logger: retry waiting for logger to stopJason A. Donenfeld33 hours1-2/+3
| | | | | | | The return code before was wrong, because WaitForSingleObject returns WAIT_OBJECT_0 on success, not TRUE. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: rundll32: do not close invalid handle valueJason A. Donenfeld33 hours1-4/+8
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* version: bump0.11Jason A. Donenfeld5 days1-2/+2
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* build: call signtool manuallyJason A. Donenfeld5 days3-0/+9
| | | | | | | | This eliminates the need for a cross signing certificate, which is no longer needed in the kernel and was never useful in userspace. And it does the timestamp server correctly. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: restore usage of FunctionalDeviceObject->ReservedJason A. Donenfeld6 days5-12/+39
| | | | | | | | | | | | | | | | | | | | | | | | Otherwise, on Windows 10 RTM, nt!KeBugCheckEx nt!KiBugCheckDispatch+0x69 nt!KiPageFault+0x248 nt!KiTryUnwaitThread+0x35 nt!KeSetEvent+0x188 wireguard!DispatchPnp+0x50 [driver\ioctl.c @ 677] nt!PnpAsynchronousCall+0xe5 nt!PiIrpQueryRemoveDevice+0x8c nt!PnpQueryRemoveLockedDeviceNode+0x69 nt!PnpDeleteLockedDeviceNode+0x84 nt!PnpDeleteLockedDeviceNodes+0xb1 nt!PnpProcessQueryRemoveAndEject+0x3d1 nt!PnpProcessTargetDeviceEvent+0xd9 nt!PnpDeviceEventWorker+0x33c nt!ExpWorkerThread+0xe9 nt!PspSystemThreadStartup+0x58 nt!KiStartSystemThread+0x16 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: remove code analysisJason A. Donenfeld2026-03-2714-58/+0
| | | | | | Microsoft is getting rid of it! Yikes. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: suppress invalid codeql warningsJason A. Donenfeld2026-03-274-1/+15
| | | | | | These are kind of bogus and use a variation of styles. Bah! Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: socket: suppress memory leak warningJason A. Donenfeld2026-03-271-0/+1
| | | | | | | We're allocating the IRP on the stack, so this shouldn't be a real issue. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: don't use paged dispatchers when not necessaryJason A. Donenfeld2026-03-271-2/+2
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* build: remove SDVJason A. Donenfeld2026-03-273-17/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* README: bump visual studio versionJason A. Donenfeld2026-03-271-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: apply clang-formatJason A. Donenfeld2026-03-273-6/+6
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* clang-format: remove duplicate lineJason A. Donenfeld2026-03-271-1/+0
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: compare enum values as DWORDsJason A. Donenfeld2026-03-271-14/+14
| | | | | | | api\configuration.c(45,39): error C2220: the following warning is treated as an error [api\api.vcxproj] api\configuration.c(45,39): warning C5287: operands are different enum types 'WG_IOCTL_INTERFACE_FLAG' and 'WIREGUARD_INTERFACE_FLAG'; use an explicit cast to silence this warning [api\api.vcxproj] Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* api: remove irregular parens in enumJason A. Donenfeld2026-03-271-4/+4
| | | | | | The other enums aren't using these. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ioctl: removed unused halt eventJason A. Donenfeld2026-03-274-15/+0
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: port to windows 10Jason A. Donenfeld2026-03-2724-763/+37
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: bump copyrightJason A. Donenfeld2026-03-2475-78/+78
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: allowedips: remove Seq linuxismJason A. Donenfeld2026-03-242-8/+0
| | | | | | | This was used in the Linux implementation for resuming iterations over netlink, but wound up finding no use case on NT. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: allowedips: add WG_IOCTL_ALLOWED_IP_REMOVE flagJason A. Donenfeld2026-03-248-42/+210
| | | | | | | | | This allows removing individual allowed IPs without having to clear them all out and dropping packets or relying on a dummy peer to have move semantics. Suggested-by: Jordan Rife <jordan@jrife.io> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: crypto: call streaming API objects "_CTX" instead of "_STATE"Jason A. Donenfeld2026-03-245-142/+142
| | | | | | This aligns with conventions in other projects, like Linux and OpenSSL. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: crypto: blake2s: reorder single-shot functionJason A. Donenfeld2026-03-244-8/+8
| | | | | | | This follows Linux's unification of conventions and is indeed more clear. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* driver: ipc: send staged packets when setting initial private keyJason A. Donenfeld2026-03-241-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Packets bound for peers can queue up prior to the device private key being set. For example, if persistent keepalive is set, a packet is queued up to be sent as soon as the device comes up. However, if the private key hasn't been set yet, the handshake message never sends, and no timer is armed to retry, since that would be pointless. But, if a user later sets a private key, the expectation is that those queued packets, such as a persistent keepalive, are actually sent. So adjust the configuration logic to account for this edge case, and add a test case to make sure this works. Maxim noticed this with a wg-quick(8) config to the tune of: [Interface] PostUp = wg set %i private-key somefile [Peer] PublicKey = ... Endpoint = ... PersistentKeepalive = 25 Here, the private key gets set after the device comes up using a PostUp script, triggering the bug. Reported-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Link: https://lore.kernel.org/wireguard/87fs7xtqrv.fsf@gmail.com/ Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>