Added Address/Leak/Thread/Undefined Behavior Sanitizer to the CI
workflow. Summary reports are displayed in the Job Summary, while full
logs are available via GitHub Artifacts. Initial verification is
handled by vpntools-check.sh.
Thread Sanitizer reports two data races on CancelAccept and
CallingThread in SOCK, shared between Accept(Accept6) and Disconnect.
These are used when interrupting an Accept operation from a Disconnect.
These races are benign because they work correctly even if both fields
have old values.
The Lock/Unlock mechanism on Unix is a manual, hand-coded implementation
of PTHREAD_MUTEX_RECURSIVE. We avoid using the PTHREAD_MUTEX_RECURSIVE
directly because it exhibits critical bugs, such as deadlocks on
certain older systems(Linux, Solaris, or macOS).
followup #2219
Thread Sanitizer reports data races on PoolHalting in THREAD, shared
between ThreadPoolProc and WaitThread. But if WaitThread reads false,
synchronization is ensured by Wait from the PoolWaitList. If it reads
true, WaitThread simply returns.
Using no_sanitize("thread") disables instrumentation for the entire
stack frame, meaning functions called within that scope are also not
checked. By using race_top in a suppression file, we can suppress
erros only when they occur at the top of the stack. This provides more
granular control over errors suppression.
As an example, this suppression addresses #2222.
Define ATTRIBUTE_NO_TSAN as __attribute__((no_sanitize(\"thread\")))
when building with thread sanitizer enabled. Falls back to empty
definition when thread sanitizer is not active or not supported
compiler.
Left shifting UCHAR promotes it to a signed integer. When the
value is >= 128 and shifted by 24, the result sets the sign bit,
causing undefined behavior. Fixes it by explicit casting to UINT.
The password input handling on Linux to match the behavior on Windows.
It allows deleting characters using the Backspace, Delete, and
Left arrow keys, and correctly handles other input sequences are handling
correctly.
Previously, The address of a local stack variable was passed to a new
thread. Fix dangling pointer by switching to dynamic allocation.
This problem is also known as CVE-2025-25568.