CVE-2026-54999 CVSS 8.8 July 14, 2026
← All reports

CVE-2026-54999: Use-After-Free in the Windows TCP/IP Wake-Pattern Port Acquire Path

Community check
      Suggest change

      Reports here are AI-generated and may be wrong. Edit the source directly on GitHub — saving opens a pull request. Add yourself to the report's editors: list in the same PR and your name will appear at the bottom once it's merged.

      ✎ Edit on GitHub (opens a PR)

      TL;DR

      tcpip.sys manages a per-address-family list of “wake pattern” port entries used to arm the interface for wake-on-LAN-style traffic. InetWakeAcquirePortAf allocates such an entry, links it into the address-family list, bumps a temporary refcount, then drops the spinlock to make the blocking InetSetInterfacePropertyAf call before reacquiring and decrementing. During that unlocked window, a concurrent InetWakeReleasePortAf can look up the same entry, drive the refcount to zero, unlink it, and ExFreePoolWithTag it — after which the acquire thread continues to operate on and re-unlink freed pool memory. The patch, gated behind Feature_3601311035 (on by default), replaces the fragile “who hits zero frees it” refcount protocol with an explicit pending flag at offset +0x14 recorded under the lock, routes all unlinks through a new idempotent helper InetWakeRemovePortEntryIfPresent, and makes the release path defer the free to the still-active acquirer, eliminating the UAF/double-free.

      Background

      Windows TCP/IP supports arming a network interface with “wake patterns” — configuration that lets the NIC wake the host when specific traffic arrives. Internally, tcpip.sys tracks the ports that participate in this mechanism through a per-address-family structure that owns a doubly linked list (a standard LIST_ENTRY-style pair of Flink/Blink pointers) and a spinlock guarding it. Each list node is a 0x30-byte pool allocation tagged 'InWP' (0x50576e49), allocated by ExAllocatePoolWithTag.

      The node layout that matters here:

      Two entry points share this list under the same spinlock: InetWakeAcquirePortAf, which creates or refs a port entry and pushes the corresponding interface property, and InetWakeReleasePortAf, which derefs and, on reaching zero, unlinks and frees. Both begin with KeAcquireSpinLockRaiseToDpc and call InetWakeLookupPort to find an existing entry for a given (family, interface) pair. The critical subtlety is that arming or disarming the interface — InetSetInterfacePropertyAf with property 0x12 (18, “add”) or 0x13 (19, “remove”) — is a blocking operation that cannot be performed while holding the spinlock at DISPATCH_LEVEL, so the acquire path must release the lock across it.

      This is reachable over an adjacent network because wake-pattern configuration is driven by received traffic / interface operations that an on-link attacker can influence, and the two operations can be made to race on the same port and address family.

      Root Cause

      Look at the pre-patch InetWakeAcquirePortAf. When a new entry is created (InetWakeLookupPort returned NULL), it allocates the node, initializes +0x10 to 1, links it into the list, and then — for a port outside the reserved range — bumps the refcount a second time and drops the lock:

      *((_DWORD *)v13 + 4) += v16;          // entry->refcount += 1  (now 2)
      KeReleaseSpinLock((PKSPIN_LOCK)a4, NewIrql);
      ...
      v6 = InetSetInterfacePropertyAf(a2, (_DWORD)a3, 0, 18, 0, (__int64)v28, 216);  // BLOCKS, lock dropped
      v17 = KeAcquireSpinLockRaiseToDpc((PKSPIN_LOCK)a4);
      v18 = (*((_DWORD *)v13 + 4))-- == 1;  // decrement; was it the last ref?
      

      The entire correctness argument rests on that += 1 extra reference keeping the node alive across the unlocked property-set call. But nothing about that reference is private to the acquire thread — it lives in the same shared +0x10 counter that InetWakeReleasePortAf decrements. Because the node is already linked into the list before the lock is dropped, a concurrent release can find it via InetWakeLookupPort:

      // pre-patch InetWakeReleasePortAf
      if ( (*(_DWORD *)(v10 + 16))-- == 1 ) {     // drops refcount to zero
          v13 = *(_QWORD *)v10;
          ...
          *v14 = v13;                              // unlink
          *(_QWORD *)(v13 + 8) = v14;
          KeReleaseSpinLock(a4, v9);
          ...
          ExFreePoolWithTag((PVOID)v11, 0);        // FREES the node
      }
      

      Consider the interleaving. Acquire creates the entry with refcount 1, bumps to 2, drops the lock, and enters InetSetInterfacePropertyAf. A release comes in, decrements 2 → 1 (not zero, so it just unlocks). A second release — or the paired release for the caller’s own acquire — decrements 1 → 0, unlinks the node, drops the lock, and calls ExFreePoolWithTag(v11). Now the acquire thread returns from the property-set call, reacquires the lock, and executes:

      v18 = (*((_DWORD *)v13 + 4))-- == 1;   // read/write of FREED pool at v13+0x10
      

      v13 points at freed pool. Every subsequent access is a use-after-free: the decrement itself is a write to reclaimed memory, and the failure paths then walk the (stale) Flink/Blink at *v13 / v13[1] and perform a second unlink plus a second ExFreePoolWithTag(v13) — a classic double-free. The linked-list consistency checks (if (*(_QWORD **)(*v13 + 8LL) == v13) before unlinking, else __fastfail(3)) provide no protection once the backing memory has been recycled; an attacker who reoccupies the freed 0x30 chunk controls exactly the pointer pair those checks read.

      The invariant the code assumed — “the extra refcount pins the entry until the acquirer decrements it” — is false whenever the shared counter can reach zero from another thread while the acquirer is unlocked. That is the entire bug.

      The Patch

      The fix (active under Feature_3601311035__private_IsEnabledDeviceUsage(), which returns true by default) stops using the shared refcount as the liveness token across the unlocked window and instead records the acquirer’s in-progress state in a dedicated pending flag at +0x14, set and cleared under the lock. It also funnels every list removal through a single idempotent helper so a node can never be unlinked twice.

      New field initialization. Right after zeroing the allocation and setting the refcount to 1, the patched acquire path clears the pending flag:

      if ( (unsigned int)Feature_3601311035__private_IsEnabledDeviceUsage() )
          *((_DWORD *)v13 + 5) = 0;   // entry->pending = 0  (offset +0x14)
      

      Marking pending instead of bumping the refcount. Where the old code did *((_DWORD *)v13 + 4) += v16 before dropping the lock, the new code sets the pending flag under the old (non-feature) behavior only as a fallback; under the feature it writes the flag rather than touching the shared counter:

      if ( (unsigned int)Feature_3601311035__private_IsEnabledDeviceUsage() )
          *((_DWORD *)v13 + 5) = 1;   // entry->pending = 1
      else
          ++*((_DWORD *)v13 + 4);     // legacy: bump refcount
      KeReleaseSpinLock(a4, NewIrql);
      v6 = InetSetInterfacePropertyAf(a2, (_DWORD)a3, 0, 18, 0, (__int64)v27, 216);
      

      The port entry’s own reference count stays at 1 across the property-set call, and the acquirer’s continued interest is expressed by pending = 1 — a value the release path now checks.

      Reacquire and clear. After the blocking call returns, the patched acquirer reacquires the lock and immediately clears its pending flag, then makes its free decision based on the current refcount rather than on a fragile decrement-and-test:

      v16 = KeAcquireSpinLockRaiseToDpc(a4);
      NewIrql = v16;
      if ( (unsigned int)Feature_3601311035__private_IsEnabledDeviceUsage() )
      {
          *((_DWORD *)v13 + 5) = 0;               // pending = 0
          if ( !*((_DWORD *)v13 + 4) )            // refcount already 0? release deferred to us
          {
              if ( v6 >= 0 ) { ... InetSetInterfacePropertyAf(...,19,...); goto LABEL_21; } // remove + free
              goto LABEL_23;                       // error path: remove + free
          }
          goto LABEL_22;                           // refcount still > 0: entry stays alive
      }
      

      The key is what the refcount now means. Because a concurrent release no longer has to keep the node alive by inference, the patch has the release path defer the actual free when it observes the pending flag. So when the acquirer sees refcount == 0, it knows the release already ran and handed ownership of the free back to it — and the node is guaranteed still valid because release did not free it. When it sees refcount != 0, no release completed the teardown and the node simply stays in the list.

      The idempotent unlink helper. The dangerous open-coded unlink-and-free in the acquirer’s cleanup paths is replaced with a call to the new helper before freeing:

      LABEL_23:
          v11 = 4;
          if ( (unsigned int)Feature_3601311035__private_IsEnabledDeviceUsage() )
          {
              InetWakeRemovePortEntryIfPresent(v13);
      LABEL_28:
              ExFreePoolWithTag(v13, 0);
              goto LABEL_31;
          }
          // legacy open-coded unlink + fastfail on inconsistency ...
      

      InetWakeRemovePortEntryIfPresent is the linchpin:

      _QWORD *__fastcall InetWakeRemovePortEntryIfPresent(_QWORD *a1)
      {
        result = (_QWORD *)*a1;
        if ( (_QWORD *)*a1 != a1 )              // Flink != self  ⇒ still linked
        {
          if ( (_QWORD *)result[1] != a1 || (v2 = (_QWORD *)a1[1], (_QWORD *)*v2 != a1) )
            __fastfail(3u);                     // consistency check
          *v2 = result;                         // standard LIST_ENTRY unlink
          result[1] = v2;
          a1[1] = a1;                           // reset linkage to self
          *a1 = a1;                             // ← makes a second call a no-op
        }
        return result;
      }
      

      By resetting Flink/Blink to point at the node itself after unlinking, the helper makes the “is this node still in a list?” test (*a1 != a1) definitively answerable, so calling it twice is harmless. This is what lets both the acquire and release paths attempt removal without either one double-unlinking a node the other already removed — the exact operation that, in the pre-patch code, corrupted the list and led to the double ExFreePoolWithTag.

      The release side. InetWakeReleasePortAf gets the mirror-image change. On dropping the refcount to zero it now removes via the helper and, critically, checks the acquirer’s pending flag and bails out of the free if it is set:

      if ( (*(_DWORD *)(v10 + 16))-- != 1 )
          goto LABEL_6;                          // not last ref: just unlock
      if ( (unsigned int)Feature_3601311035__private_IsEnabledDeviceUsage() )
      {
          InetWakeRemovePortEntryIfPresent((_QWORD *)v11);
          if ( *(_DWORD *)(v11 + 20) )           // pending flag set (offset +0x14)?
              goto LABEL_6;                      // acquire still owns the entry: DO NOT free
      }
      else { /* legacy open-coded unlink + fastfail */ }
      KeReleaseSpinLock(a4, v9);
      if ( !IsPortWithinRange(a1, a4 + 4) ) { ... InetSetInterfacePropertyAf(...,19,...); }
      ExFreePoolWithTag((PVOID)v11, 0);          // only reached when pending == 0
      

      So the ownership handoff is explicit and symmetric: the release thread unlinks the node (safely, idempotently) but if pending is set it leaves the pool allocation intact and returns, and the acquire thread — which will clear pending and observe refcount == 0 when it reacquires the lock — performs the single, authoritative ExFreePoolWithTag. Note the property value that release reads for the disarm call also moved from +0x14 to +0x18 (*(_DWORD *)(v11 + 24)), consistent with +0x14 being repurposed as the pending flag. Because the flag reads and writes all happen under the shared spinlock, there is exactly one winner for the free in every interleaving.

      Exploitability

      The primitive is a use-after-free of a 0x30-byte paged/nonpaged pool allocation, escalating to a double-free. In the vulnerable interleaving the acquire thread, after its blocking InetSetInterfacePropertyAf returns, writes to entry+0x10 (the decrement) and then reads *v13/v13[1] to drive a second unlink — all against memory that a racing release already returned to the pool with ExFreePoolWithTag. An attacker who wins the reallocation race for that freed chunk controls the Flink/Blink pointers the acquirer’s unlink logic writes through:

      *v24 = v23;                    // *(attacker_ptr) = attacker_value
      *(_QWORD *)(v23 + 8) = v24;
      

      That is a controlled write of a controlled pointer into another controlled pointer — the standard linked-list-unlink write primitive — plus a second ExFreePoolWithTag on the same address, either of which is a well-understood path to kernel code execution given pool grooming. The __fastfail(3) consistency checks do not help: they compare fields inside the freed (now attacker-owned) chunk, so a groomed replacement object satisfies them.

      The trigger is a race, so it is probabilistic, but the window is large and attacker-friendly: it spans an entire blocking InetSetInterfacePropertyAf interface-property push, during which the spinlock is released, giving a racing release thread ample time to look up the entry, zero the count, unlink, and free. The bug class MSRC assigns — “concurrent execution using shared resource with improper synchronization” — is exactly this dropped-lock window. Reachability is adjacent (on-link) and requires no authentication: wake-pattern port acquire/release is driven by interface operations and traffic an attacker on the same network segment can stimulate, and both operations target the same (address-family, interface) tuple, which is what makes them collide on one port entry. The CVSS 8.8 with an adjacent attack vector and no privileges required reflects that an unauthenticated on-link attacker can drive both sides of the race; the “high complexity” of winning it is offset by the width of the unlocked window and the attacker’s ability to retry the acquire/release pairing repeatedly until the free lands inside it.

      Detection

      The presence of Feature_3601311035__private_IsEnabledDeviceUsage(), the InetWakeRemovePortEntryIfPresent helper, and a pending-flag read at entry+0x14 inside InetWakeReleasePortAf/InetWakeAcquirePortAf distinguish a patched tcpip.sys (build 7548+) from the vulnerable 7417-era binary. On a live system, unexpected __fastfail(3) (FAST_FAIL_CORRUPT_LIST_ENTRY) bugchecks originating in the wake-port paths, or pool-corruption stops tagged InWP (0x50576e49), are consistent with attempts to exercise this race.

      Pre patch functions

      Full decompilation of InetWakeAcquirePortAf before the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      
      ulonglong InetWakeAcquirePortAf
                          (ushort param_1,longlong param_2,undefined8 *param_3,longlong param_4)
      
      {
        longlong *plVar1;
        code *pcVar2;
        char cVar3;
        uint uVar4;
        longlong lVar5;
        longlong *plVar6;
        ulonglong uVar7;
        undefined4 uVar8;
        int iVar9;
        undefined1 auStack_188 [32];
        undefined4 local_168;
        undefined1 *local_160;
        undefined4 local_158;
        undefined4 local_150;
        undefined1 local_148;
        undefined1 local_138 [36];
        ushort local_114;
        undefined4 local_110;
        undefined4 local_70;
        undefined4 local_68;
        ulonglong local_58;
        
        local_58 = __security_cookie ^ (ulonglong)auStack_188;
        uVar8 = 0;
        uVar4 = 0;
        local_148 = KeAcquireSpinLockRaiseToDpc(param_4);
        lVar5 = InetWakeLookupPort(param_1,param_2,param_3,param_4);
        if (lVar5 == 0) {
          plVar6 = (longlong *)ExAllocatePoolWithTag(0x200,0x30,0x50576e49);
          if (plVar6 == (longlong *)0x0) {
            uVar4 = 0xc0000017;
          }
          else {
            iVar9 = 1;
            *plVar6 = 0;
            plVar6[1] = 0;
            plVar6[2] = 0;
            plVar6[3] = 0;
            plVar6[4] = 0;
            plVar6[5] = 0;
            *(undefined4 *)(plVar6 + 2) = 1;
            *(ushort *)(plVar6 + 3) = param_1;
            plVar6[4] = param_2;
            plVar6[5] = (longlong)param_3;
            plVar1 = (longlong *)(param_4 + 0x10);
            lVar5 = *plVar1;
            if (*(longlong **)(lVar5 + 8) != plVar1) goto LAB_0;
            *plVar6 = lVar5;
            plVar6[1] = (longlong)plVar1;
            *(longlong **)(lVar5 + 8) = plVar6;
            *plVar1 = (longlong)plVar6;
            cVar3 = IsPortWithinRange(param_1,param_4 + 0x20);
            if (cVar3 == '\0') {
              *(int *)(plVar6 + 2) = (int)plVar6[2] + iVar9;
              KeReleaseSpinLock(param_4);
              memset(local_138,0,0xd8);
              local_110 = *(undefined4 *)(param_4 + 8);
              local_160 = local_138;
              local_158 = 0xd8;
              local_168 = 0;
              local_70 = 3;
              local_114 = param_1;
              uVar4 = InetSetInterfacePropertyAf(param_2,param_3,0,0x12);
              local_148 = KeAcquireSpinLockRaiseToDpc(param_4);
              plVar1 = plVar6 + 2;
              *(int *)plVar1 = (int)*plVar1 + -1;
              if ((int)*plVar1 == 0) {
                if (-1 < (int)uVar4) {
                  KeReleaseSpinLock(param_4,local_148);
                  local_160 = local_138;
                  local_158 = 0xd8;
                  local_168 = 0;
                  InetSetInterfacePropertyAf(param_2,param_3,0,0x13);
                  lVar5 = *plVar6;
                  if ((*(longlong **)(lVar5 + 8) != plVar6) ||
                     (plVar1 = (longlong *)plVar6[1], (longlong *)*plVar1 != plVar6)) goto LAB_0;
                  *plVar1 = lVar5;
                  *(longlong **)(lVar5 + 8) = plVar1;
                  ExFreePoolWithTag(plVar6,0);
                  goto LAB_1;
                }
              }
              else if (-1 < (int)uVar4) {
                *(undefined4 *)((longlong)plVar6 + 0x14) = local_68;
                goto LAB_2;
              }
              lVar5 = *plVar6;
              if ((*(longlong **)(lVar5 + 8) != plVar6) ||
                 (plVar1 = (longlong *)plVar6[1], (longlong *)*plVar1 != plVar6)) {
      LAB_0:
                pcVar2 = (code *)swi(0x29);
                (*pcVar2)(3);
                pcVar2 = (code *)swi(3);
                uVar7 = (*pcVar2)();
                return uVar7;
              }
              *plVar1 = lVar5;
              *(longlong **)(lVar5 + 8) = plVar1;
              ExFreePoolWithTag(plVar6,0);
            }
          }
        }
        else {
          *(int *)(lVar5 + 0x10) = *(int *)(lVar5 + 0x10) + 1;
        }
      LAB_2:
        KeReleaseSpinLock(param_4,local_148);
      LAB_1:
        if ((DAT_3 == 1) && ((Microsoft_Windows_TCPIPEnableBits & 8) != 0)) {
          if (param_3 == (undefined8 *)0x0) {
            local_150 = 0;
          }
          else {
            local_150 = *(undefined4 *)*param_3;
            uVar8 = *(undefined4 *)(param_3 + 1);
          }
          local_160 = (undefined1 *)CONCAT44(local_160._4_4_,(uint)*(ushort *)(param_2 + 0x18));
          local_168 = CONCAT22(local_168._2_2_,param_1 >> 8 | param_1 << 8);
          local_158 = uVar8;
          McTemplateK0qhqqq_EtwWriteTransfer(&MICROSOFT_TCPIP_PROVIDER_Context);
        }
        return (ulonglong)uVar4;
      }
      

      Full decompilation of InetWakeReleasePortAf before the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      
      undefined4
      InetWakeReleasePortAf(undefined2 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4)
      
      {
        longlong lVar1;
        longlong *plVar2;
        code *pcVar3;
        undefined1 *puVar4;
        undefined1 uVar5;
        char cVar6;
        longlong *plVar7;
        undefined1 *puVar8;
        undefined4 uVar9;
        undefined1 auStack_168 [8];
        undefined1 auStack_160 [24];
        undefined4 local_148;
        undefined1 *local_140;
        undefined4 local_138;
        undefined1 local_128 [208];
        undefined4 local_58;
        ulonglong local_48;
        
        puVar8 = auStack_168;
        local_48 = __security_cookie ^ (ulonglong)auStack_168;
        uVar9 = 0;
        uVar5 = KeAcquireSpinLockRaiseToDpc(param_4);
        plVar7 = (longlong *)InetWakeLookupPort(param_1,param_2,param_3,param_4);
        if (plVar7 == (longlong *)0x0) {
          KeReleaseSpinLock(param_4,uVar5);
          puVar8 = auStack_168;
          uVar9 = 0xc0000225;
        }
        else {
          plVar2 = plVar7 + 2;
          *(int *)plVar2 = (int)*plVar2 + -1;
          puVar4 = auStack_168;
          if ((int)*plVar2 == 0) {
            lVar1 = *plVar7;
            if ((*(longlong **)(lVar1 + 8) == plVar7) &&
               (plVar2 = (longlong *)plVar7[1], (longlong *)*plVar2 == plVar7)) {
              *plVar2 = lVar1;
              *(longlong **)(lVar1 + 8) = plVar2;
              KeReleaseSpinLock(param_4,CONCAT71((int7)((ulonglong)plVar2 >> 8),uVar5));
              cVar6 = IsPortWithinRange(param_1);
              if (cVar6 == '\0') {
                memset(local_128,0,0xd8);
                local_58 = *(undefined4 *)((longlong)plVar7 + 0x14);
                local_140 = local_128;
                local_138 = 0xd8;
                local_148 = 0;
                InetSetInterfacePropertyAf(param_2,param_3,0,0x13);
              }
              ExFreePoolWithTag(plVar7,0);
              uVar9 = 0;
              goto LAB_0;
            }
            pcVar3 = (code *)swi(0x29);
            (*pcVar3)(3);
            puVar4 = auStack_160;
          }
          puVar8 = puVar4;
          *(undefined8 *)(puVar8 + -8) = 0x1c01ba888;
          KeReleaseSpinLock(param_4,uVar5);
        }
      LAB_0:
        *(undefined8 *)(puVar8 + -8) = 0x1c01ba89f;
        return uVar9;
      }
      

      Post patch functions

      Full decompilation of InetWakeAcquirePortAf after the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      
      ulonglong InetWakeAcquirePortAf
                          (ushort param_1,longlong param_2,undefined8 *param_3,longlong param_4)
      
      {
        longlong *plVar1;
        code *pcVar2;
        char cVar3;
        undefined1 uVar4;
        int iVar5;
        uint uVar6;
        longlong lVar7;
        longlong *plVar8;
        ulonglong uVar9;
        undefined4 uVar10;
        undefined1 auStack_188 [32];
        undefined4 local_168;
        undefined1 *local_160;
        undefined4 local_158;
        undefined4 local_150;
        undefined1 local_148;
        undefined1 local_138 [36];
        ushort local_114;
        undefined4 local_110;
        undefined4 local_70;
        undefined4 local_68;
        ulonglong local_58;
        
        local_58 = __security_cookie ^ (ulonglong)auStack_188;
        uVar10 = 0;
        uVar6 = 0;
        local_148 = KeAcquireSpinLockRaiseToDpc(param_4);
        lVar7 = InetWakeLookupPort(param_1,param_2,param_3,param_4);
        if (lVar7 == 0) {
          plVar8 = (longlong *)ExAllocatePoolWithTag(0x200,0x30,0x50576e49);
          if (plVar8 == (longlong *)0x0) {
            uVar6 = 0xc0000017;
          }
          else {
            *plVar8 = 0;
            plVar8[1] = 0;
            plVar8[2] = 0;
            plVar8[3] = 0;
            plVar8[4] = 0;
            plVar8[5] = 0;
            *(undefined4 *)(plVar8 + 2) = 1;
            iVar5 = Feature_3601311035__private_IsEnabledDeviceUsage();
            if (iVar5 != 0) {
              *(undefined4 *)((longlong)plVar8 + 0x14) = 0;
            }
            plVar1 = (longlong *)(param_4 + 0x10);
            *(ushort *)((longlong)plVar8 + 0x1c) = param_1;
            plVar8[4] = param_2;
            plVar8[5] = (longlong)param_3;
            lVar7 = *plVar1;
            if (*(longlong **)(lVar7 + 8) != plVar1) goto LAB_0;
            *plVar8 = lVar7;
            plVar8[1] = (longlong)plVar1;
            *(longlong **)(lVar7 + 8) = plVar8;
            *plVar1 = (longlong)plVar8;
            cVar3 = IsPortWithinRange(param_1,param_4 + 0x20);
            if (cVar3 == '\0') {
              iVar5 = Feature_3601311035__private_IsEnabledDeviceUsage();
              if (iVar5 == 0) {
                *(int *)(plVar8 + 2) = (int)plVar8[2] + 1;
              }
              else {
                *(undefined4 *)((longlong)plVar8 + 0x14) = 1;
              }
              KeReleaseSpinLock(param_4);
              memset(local_138,0,0xd8);
              local_110 = *(undefined4 *)(param_4 + 8);
              local_160 = local_138;
              local_158 = 0xd8;
              local_168 = 0;
              local_70 = 3;
              local_114 = param_1;
              uVar6 = InetSetInterfacePropertyAf(param_2,param_3,0,0x12);
              uVar4 = KeAcquireSpinLockRaiseToDpc(param_4);
              local_148 = uVar4;
              iVar5 = Feature_3601311035__private_IsEnabledDeviceUsage();
              if (iVar5 == 0) {
                plVar1 = plVar8 + 2;
                *(int *)plVar1 = (int)*plVar1 + -1;
                if ((int)*plVar1 == 0) {
                  if (-1 < (int)uVar6) {
                    KeReleaseSpinLock(param_4,uVar4);
                    local_160 = local_138;
                    local_158 = 0xd8;
                    local_168 = 0;
                    InetSetInterfacePropertyAf(param_2,param_3,0,0x13);
                    lVar7 = *plVar8;
                    if ((*(longlong **)(lVar7 + 8) != plVar8) ||
                       (plVar1 = (longlong *)plVar8[1], (longlong *)*plVar1 != plVar8))
                    goto LAB_0;
                    *plVar1 = lVar7;
                    *(longlong **)(lVar7 + 8) = plVar1;
      LAB_1:
                    ExFreePoolWithTag(plVar8,0);
                    goto LAB_2;
                  }
                }
                else {
      LAB_3:
                  if (-1 < (int)uVar6) {
                    *(undefined4 *)(plVar8 + 3) = local_68;
                    goto LAB_4;
                  }
                }
              }
              else {
                *(undefined4 *)((longlong)plVar8 + 0x14) = 0;
                if ((int)plVar8[2] != 0) goto LAB_3;
                if (-1 < (int)uVar6) {
                  KeReleaseSpinLock(param_4,uVar4);
                  local_160 = local_138;
                  local_158 = 0xd8;
                  local_168 = 0;
                  InetSetInterfacePropertyAf(param_2,param_3,0,0x13);
                  goto LAB_1;
                }
              }
              iVar5 = Feature_3601311035__private_IsEnabledDeviceUsage();
              if (iVar5 == 0) {
                lVar7 = *plVar8;
                if ((*(longlong **)(lVar7 + 8) != plVar8) ||
                   (plVar1 = (longlong *)plVar8[1], (longlong *)*plVar1 != plVar8)) {
      LAB_0:
                  pcVar2 = (code *)swi(0x29);
                  (*pcVar2)(3);
                  pcVar2 = (code *)swi(3);
                  uVar9 = (*pcVar2)();
                  return uVar9;
                }
                *plVar1 = lVar7;
                *(longlong **)(lVar7 + 8) = plVar1;
              }
              else {
                InetWakeRemovePortEntryIfPresent(plVar8);
              }
              ExFreePoolWithTag(plVar8,0);
            }
          }
        }
        else {
          *(int *)(lVar7 + 0x10) = *(int *)(lVar7 + 0x10) + 1;
        }
      LAB_4:
        KeReleaseSpinLock(param_4,local_148);
      LAB_2:
        if ((DAT_5 == 1) && ((Microsoft_Windows_TCPIPEnableBits & 8) != 0)) {
          if (param_3 == (undefined8 *)0x0) {
            local_150 = 0;
          }
          else {
            local_150 = *(undefined4 *)*param_3;
            uVar10 = *(undefined4 *)(param_3 + 1);
          }
          local_160 = (undefined1 *)CONCAT44(local_160._4_4_,(uint)*(ushort *)(param_2 + 0x18));
          local_168 = CONCAT22(local_168._2_2_,param_1 >> 8 | param_1 << 8);
          local_158 = uVar10;
          McTemplateK0qhqqq_EtwWriteTransfer(&MICROSOFT_TCPIP_PROVIDER_Context);
        }
        return (ulonglong)uVar6;
      }
      

      Full decompilation of InetWakeReleasePortAf after the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      
      undefined8
      InetWakeReleasePortAf(undefined2 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4)
      
      {
        longlong lVar1;
        longlong *plVar2;
        code *pcVar3;
        undefined1 uVar4;
        char cVar5;
        int iVar6;
        longlong *plVar7;
        undefined8 uVar8;
        undefined1 auStack_168 [32];
        undefined4 local_148;
        undefined1 *local_140;
        undefined4 local_138;
        undefined1 local_128 [208];
        undefined4 local_58;
        ulonglong local_48;
        
        local_48 = __security_cookie ^ (ulonglong)auStack_168;
        uVar4 = KeAcquireSpinLockRaiseToDpc(param_4);
        plVar7 = (longlong *)InetWakeLookupPort(param_1,param_2,param_3,param_4);
        if (plVar7 == (longlong *)0x0) {
          KeReleaseSpinLock(param_4,uVar4);
          return 0xc0000225;
        }
        plVar2 = plVar7 + 2;
        *(int *)plVar2 = (int)*plVar2 + -1;
        if ((int)*plVar2 == 0) {
          iVar6 = Feature_3601311035__private_IsEnabledDeviceUsage();
          if (iVar6 == 0) {
            lVar1 = *plVar7;
            if ((*(longlong **)(lVar1 + 8) != plVar7) ||
               (plVar2 = (longlong *)plVar7[1], (longlong *)*plVar2 != plVar7)) {
              pcVar3 = (code *)swi(0x29);
              (*pcVar3)(3);
              pcVar3 = (code *)swi(3);
              uVar8 = (*pcVar3)();
              return uVar8;
            }
            *plVar2 = lVar1;
            *(longlong **)(lVar1 + 8) = plVar2;
          }
          else {
            InetWakeRemovePortEntryIfPresent(plVar7);
            if (*(int *)((longlong)plVar7 + 0x14) != 0) goto LAB_0;
          }
          KeReleaseSpinLock(param_4,uVar4);
          cVar5 = IsPortWithinRange(param_1);
          if (cVar5 == '\0') {
            memset(local_128,0,0xd8);
            local_58 = (undefined4)plVar7[3];
            local_140 = local_128;
            local_138 = 0xd8;
            local_148 = 0;
            InetSetInterfacePropertyAf(param_2,param_3,0,0x13);
          }
          ExFreePoolWithTag(plVar7,0);
        }
        else {
      LAB_0:
          KeReleaseSpinLock(param_4,uVar4);
        }
        return 0;
      }
      

      Full decompilation of InetWakeRemovePortEntryIfPresent after the patch:

      void InetWakeRemovePortEntryIfPresent(longlong *param_1)
      
      {
        longlong *plVar1;
        longlong *plVar2;
        code *pcVar3;
        
        plVar1 = (longlong *)*param_1;
        if (plVar1 != param_1) {
          if (((longlong *)plVar1[1] != param_1) ||
             (plVar2 = (longlong *)param_1[1], (longlong *)*plVar2 != param_1)) {
            pcVar3 = (code *)swi(0x29);
            (*pcVar3)(3);
            pcVar3 = (code *)swi(3);
            (*pcVar3)();
            return;
          }
          *plVar2 = (longlong)plVar1;
          plVar1[1] = (longlong)plVar2;
          param_1[1] = (longlong)param_1;
          *param_1 = (longlong)param_1;
        }
        return;
      }