[PR #3099] fix(windows): sanitize process ancestry before driver registration #3077

Open
opened 2026-10-14 21:07:20 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/amnezia-vpn/amnezia-client/pull/3099
Author: @Rain0Ash
Created: 8/31/2026
Status: 🔄 Open

Base: dev ← Head: codex/a6-client-fix


📝 Commits (1)

  • a3d349f windows: discard stale process parent relationships

📊 Changes

1 file changed (+22 additions, -3 deletions)

View changed files

📝 client/platforms/windows/daemon/windowssplittunnel.cpp (+22 -3)

📄 Description

Problem

The Windows client builds a process-parent map from a live Toolhelp snapshot and sends it to the split-tunnel driver by PID. Between process enumeration and registration, a PID can be recycled; an unreadable or stale entry can therefore point to an unrelated process, including itself or another node in a cycle.

The driver uses these relationships while applying inherited split state. A cyclic or stale parent link can make the kernel-side ancestry walk non-terminating, leaving DeviceIoControl(IOCTL_SET_CONFIGURATION) blocked and the AmneziaVPN service unresponsive. This is consistent with the intermittent WindowsSplitTunnel::excludeApps hangs and high CPU reported in amnezia-vpn/amnezia-client#1996.

This is a strongly supported root-cause hypothesis, not a claim that the original report included runtime proof of a cycle.

Fix

  • Zero-initialize PROCESSENTRY32W before Toolhelp calls.
  • Use Process32FirstW and abort registration if the snapshot cannot be read.
  • Keep a parent link only when the parent is present in the same snapshot and its creation time is strictly older than the child.
  • Clear invalid parent PIDs before sending the process graph to the driver.

This prevents stale PID reuse and malformed ancestry from entering the kernel graph. The companion driver PR adds cycle detection as defense in depth and keeps cyclic processes in the safe non-split state.

The change is intentionally limited to process snapshot construction; it does not alter split-tunnel policy semantics for valid process trees.

Validation

The patch was reviewed against the existing Toolhelp snapshot and IOCTL contract. Invalid snapshot reads and recycled-PID relationships are rejected before IOCTL_SET_CONFIGURATION is called.

Related issue: amnezia-vpn/amnezia-client#1996
Companion driver PR: https://github.com/mullvad/win-split-tunnel/pull/56


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/amnezia-vpn/amnezia-client/pull/3099 **Author:** [@Rain0Ash](https://github.com/Rain0Ash) **Created:** 8/31/2026 **Status:** 🔄 Open **Base:** `dev` ← **Head:** `codex/a6-client-fix` --- ### 📝 Commits (1) - [`a3d349f`](https://github.com/amnezia-vpn/amnezia-client/commit/a3d349f41b4fe9e12038bbdcd8a6517b1190f3ef) windows: discard stale process parent relationships ### 📊 Changes **1 file changed** (+22 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `client/platforms/windows/daemon/windowssplittunnel.cpp` (+22 -3) </details> ### 📄 Description ## Problem The Windows client builds a process-parent map from a live Toolhelp snapshot and sends it to the split-tunnel driver by PID. Between process enumeration and registration, a PID can be recycled; an unreadable or stale entry can therefore point to an unrelated process, including itself or another node in a cycle. The driver uses these relationships while applying inherited split state. A cyclic or stale parent link can make the kernel-side ancestry walk non-terminating, leaving DeviceIoControl(IOCTL_SET_CONFIGURATION) blocked and the AmneziaVPN service unresponsive. This is consistent with the intermittent WindowsSplitTunnel::excludeApps hangs and high CPU reported in amnezia-vpn/amnezia-client#1996. This is a strongly supported root-cause hypothesis, not a claim that the original report included runtime proof of a cycle. ## Fix - Zero-initialize PROCESSENTRY32W before Toolhelp calls. - Use Process32FirstW and abort registration if the snapshot cannot be read. - Keep a parent link only when the parent is present in the same snapshot and its creation time is strictly older than the child. - Clear invalid parent PIDs before sending the process graph to the driver. This prevents stale PID reuse and malformed ancestry from entering the kernel graph. The companion driver PR adds cycle detection as defense in depth and keeps cyclic processes in the safe non-split state. The change is intentionally limited to process snapshot construction; it does not alter split-tunnel policy semantics for valid process trees. ## Validation The patch was reviewed against the existing Toolhelp snapshot and IOCTL contract. Invalid snapshot reads and recycled-PID relationships are rejected before IOCTL_SET_CONFIGURATION is called. Related issue: amnezia-vpn/amnezia-client#1996 Companion driver PR: https://github.com/mullvad/win-split-tunnel/pull/56 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amnezia-client#3077
No description provided.