Tcl Source Code

View Ticket
Login
Ticket UUID: 40b1814b93e50b4a9627e6651184880233d63616
Title: App verifier shows user-after-free on ThreadSpecificData for Windows sockets
Type: Bug Version: trunk
Submitter: apnadkarni Created on: 2025-06-13 17:43:50
Subsystem: - New Builtin Commands Assigned To: nobody
Priority: 5 Medium Severity: Important
Status: Closed Last Modified: 2025-06-25 15:49:01
Resolution: Fixed Closed By: apnadkarni
    Closed on: 2025-06-25 15:49:01
Description:

The offending tsdPtr access is here and happens on exit.

Preliminary thoughts:

Why does this show up only under AppVerifier? Because it scrubs memory and protects freed blocks (above requires compile with -DPURIFY so Tcl_Alloc translates directly to malloc). Under normal operation, the freed tsdPtr page remains accessible though the memory block has been freed. The tsdPtr->readyEvent actually is garbage data and so the SetEvent call which checks for valid handles returns an error which Tcl ignores.

Note the tsdPtr referenced above is thread specific data in a different thread which is really asking for trouble but it appears to have been that way forever, likely even before 8.6.

User Comments: apnadkarni added on 2025-06-25 15:49:01:
Fixed in [a36f76eb6b].

apnadkarni added on 2025-06-14 05:37:49:

Also, use-after-free of socket handle here on socket_inet-2.9.

The tsdPtr bug appears to be caused by use of the same event handle to communicate socket notifications and worker thread completion to the main thread. The main thread waits for completion of worker to ensure its TSD is still available but mistakenly confuses a pending socket notification for thread completion as they use the same event and frees the TSD immediately while the worker thread is still active.

Proposed fix for both is in commit bug-40b1814b93. The tsdPtr bug is fixed by waiting on the worker thread handle rather than the notification event handle. The socket handle bug is a simple failure to mark socket closed in a loop error and then attempting to close it again.


apnadkarni added on 2025-06-14 03:32:00:

Notes for reproduction:

Build as

nmake /f makefile.vc /nologo INSTALLDIR=C:\Tcl\wip\%VSCMD_ARG_TGT_ARCH%-debug OPTS=pdbs cdebug="-Zi -Od -DPURIFY" tcltest

Add tcltest90.exe to AppVerifier. Run tcltest90 within a VS debugger (that's where AppVerifier messages will show up).

close [socket www.example.com 443]
exit <- where the use after free is triggered