<feed xmlns='http://www.w3.org/2005/Atom'>
<title>wireguard-nt/driver, branch master</title>
<subtitle>WireGuard implementation for NT kernel</subtitle>
<id>https://git.zx2c4.com/wireguard-nt/atom/driver?h=master</id>
<link rel='self' href='https://git.zx2c4.com/wireguard-nt/atom/driver?h=master'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/'/>
<updated>2026-10-06T16:33:02Z</updated>
<entry>
<title>driver: noise: reject response consumption after intermediate initiation</title>
<updated>2026-10-06T16:33:02Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-10-06T16:29:47Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=90433bd1aa35ff082b7b2ceb89b6451a4fadd2af'/>
<id>urn:sha1:90433bd1aa35ff082b7b2ceb89b6451a4fadd2af</id>
<content type='text'>
Two threads begin processing the identical response message, received
twice. The first thread, A, runs. While it's running, the second one, B,
gets partway through, and during that slow calculation, or even while
blocking on MuAcquirePushLockExclusive(), A completes and then also a
handshake initiation that's already been queued up runs in thread C,
which itself takes that same MuAcquirePushLockExclusive(). The handshake
initiation creation succeeds, and sets the state back to
waiting-for-response, and calls MuReleasePushLockExclusive(), at which
point thread B resumes, because either its finished its calculations or
was finally allowed to acquire MuAcquirePushLockExclusive(). Thread B
then copies the state back to the peer, and begins a new session, using
that state, which is the same session as the one made in thread A.

Thread A                        Thread B                        Thread C

MuAcquirePushLockShared()
 sA = Handshake-&gt;State
 RtlCopyMemory(cA, Handshake-&gt;crypto)
MuReleasePushLockShared()
if (sA != 1)
 goto fail
SlowCrypto(cA)
                                MuAcquirePushLockShared()
                                 sB = Handshake-&gt;State
                                 RtlCopyMemory(cB, Handshake-&gt;crypto)
                                MuReleasePushLockShared()
                                if (sB != 1)
                                 goto fail
                                SlowCrypto(cB)
MuAcquirePushLockExclusive()
 if (sA != Handshake-&gt;State)
  goto fail
 RtlCopyMemory(Handshake-&gt;crypto, cA)
 Handshake-&gt;State = 2
MuReleasePushLockExclusive()
MuAcquirePushLockExclusive()
 if (Handshake-&gt;State != 2)
  goto fail
 DeriveSession(Handshake-&gt;crypto)
MuReleasePushLockExclusive()
                                                                MuAcquirePushLockExclusive()
                                                                 SlowCrypto(Handshake-&gt;crypto)
                                                                 Handshake-&gt;State = 1
                                                                MuReleasePushLockExclusive()
                                MuAcquirePushLockExclusive()
                                 if (sB != Handshake-&gt;State)
                                   goto fail
                                 RtlCopyMemory(Handshake-&gt;crypto, cB)
                                 Handshake-&gt;State = 2
                                MuReleasePushLockExclusive()
                                MuAcquirePushLockExclusive()
                                 if (Handshake-&gt;State != 2)
                                  goto fail
                                 DeriveSession(Handshake-&gt;crypto)
                                MuReleasePushLockExclusive()

This seems basically impossible to hit in a meaningful way in practice,
but ensure that it absolutely cannot happen by comparing the ephemeral
private key that's on the stack with the latest one that the peer's
handshake state has.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: ioctl: reset IsDeviceRemoving on cancel-remove</title>
<updated>2026-07-20T13:39:58Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-05-14T07:20:55Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=9ca153916cc4d6ed8c6728681c33148f0137b091'/>
<id>urn:sha1:9ca153916cc4d6ed8c6728681c33148f0137b091</id>
<content type='text'>
Otherwise a vetoed query-remove leaves the adapter permanently
inaccessible via ioctl, even though NDIS keeps the miniport alive and
operational.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: nsi: forward IRPs instead of failing</title>
<updated>2026-05-07T12:17:00Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-05-06T15:27:56Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=a24b243b7f188500d55eeabfbce128ec54d0668d'/>
<id>urn:sha1:a24b243b7f188500d55eeabfbce128ec54d0668d</id>
<content type='text'>
We always have a file reference to get the proper nsi device object, so
rather than failing, in most cases, we can properly service these
requests.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: nsi: compare FilterDevice pointers under rundown protection</title>
<updated>2026-05-07T12:17:00Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-05-06T15:03:07Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=9c4f8a2fb508dc31cf34357156073dc801b595e7'/>
<id>urn:sha1:9c4f8a2fb508dc31cf34357156073dc801b595e7</id>
<content type='text'>
And also gate the PriorDispatch on the presence of an extension, which
NDIS always has.

Reported-by: Brian Diff &lt;bdiff7311@gmail.com&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: nsi: re-initialize rundown protection atomically</title>
<updated>2026-05-07T12:17:00Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-05-06T14:07:51Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=0aaa86579140d5225f288cf557c78e18da5da44c'/>
<id>urn:sha1:0aaa86579140d5225f288cf557c78e18da5da44c</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: noise: remove unused StaticPrivate variable</title>
<updated>2026-04-29T01:01:39Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-04-29T01:00:03Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=7bb6cfc73ebfaa502b3016278e9ce0bb79548530'/>
<id>urn:sha1:7bb6cfc73ebfaa502b3016278e9ce0bb79548530</id>
<content type='text'>
The stack version of this is never used, because it's long-lived, and so
we always read it out of the peer struct.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: remove unused prefast suppressions</title>
<updated>2026-04-21T19:18:21Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-04-21T13:48:25Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=b403d9fb5bfaf2bfa85bc860d7af6af6032de425'/>
<id>urn:sha1:b403d9fb5bfaf2bfa85bc860d7af6af6032de425</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: remove fixed codeql suppressions</title>
<updated>2026-04-21T13:34:48Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-04-21T13:34:48Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=fa08ff2c668b025bfc11f4fff5ceef75ef2539ef'/>
<id>urn:sha1:fa08ff2c668b025bfc11f4fff5ceef75ef2539ef</id>
<content type='text'>
I fixed the CodeQL rules.

Link: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/pull/217
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: socket: note that stack Endpoint is safe in SocketSendBufferAsReplyToNbl</title>
<updated>2026-04-16T10:12:37Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-04-16T09:57:00Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=75a588965206994d2b7201e298fc9f82d343e239'/>
<id>urn:sha1:75a588965206994d2b7201e298fc9f82d343e239</id>
<content type='text'>
WSK's WskSendTo copies addresses and control messages synchronously
before returning STATUS_PENDING. Confirmed by reverse engineering
afd.sys!WskProIRPSendTo and tcpip.sys!UdpSendMessages, which consume
address and cmsg data in the transport dispatch call and store only the
completion callback and IRP in the NBL context.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>driver: allowedips: return STATUS_SUCCESS instead of 0</title>
<updated>2026-04-16T00:34:57Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-04-16T00:34:47Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-nt/commit/?id=813ea9ad3180bb197772d78af52209800efd767e'/>
<id>urn:sha1:813ea9ad3180bb197772d78af52209800efd767e</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
</feed>
