[newlib-cygwin/main] Cygwin: format_process_maps: avoid crashing PID when fetching heap info
Corinna Vinschen
corinna@sourceware.org
Thu Jul 3 11:00:06 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=f075f3ba2720b4cca65e63b67c865959ba6b6c92
commit f075f3ba2720b4cca65e63b67c865959ba6b6c92
Author: Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Thu Jul 3 12:57:10 2025 +0200
Commit: Corinna Vinschen <corinna@vinschen.de>
CommitDate: Thu Jul 3 12:59:06 2025 +0200
Cygwin: format_process_maps: avoid crashing PID when fetching heap info
To fetch heap info for a process in our /proc/PID/maps emulation,
we call RtlQueryProcessDebugInformation on this process since
commit b4966f91396b ("(heap_info::heap_info): Rearrange using
RtlQueryProcessDebugInformation").
However, it turns out that this call can crash the targeted
process, if it's called from multiple threads or processes in
parallel.
Worse, the entire code from creating the debug buffer, over
fetching the debug info, subsequent collecting the information
from said debug buffer, up to destroying the buffer, needs to be
guarded against parallel access.
We do this by adding a global mutex object, serializing access to
the debug info of a process.
Reported-by: Christian Franke <Christian.Franke@t-online.de>
Fixes: b4966f91396b ("(heap_info::heap_info): Rearrange using RtlQueryProcessDebugInformation")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
winsup/cygwin/fhandler/process.cc | 33 ++++++++++++++++++++++++++++++---
winsup/cygwin/release/3.6.4 | 4 ++++
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/winsup/cygwin/fhandler/process.cc b/winsup/cygwin/fhandler/process.cc
index 8fae9be5f678..e00cae58d7b2 100644
--- a/winsup/cygwin/fhandler/process.cc
+++ b/winsup/cygwin/fhandler/process.cc
@@ -621,14 +621,39 @@ struct heap_info
: heap_vm_chunks (NULL)
{
PDEBUG_BUFFER buf;
+ wchar_t mtx_name [32];
+ HANDLE mtx;
NTSTATUS status;
PDEBUG_HEAP_ARRAY harray;
+ /* We need a global mutex here, because RtlQueryProcessDebugInformation
+ is neither thread-safe, nor multi-process-safe. If it's called in
+ parallel on the same process it can crash that process. We can't
+ avoid this if a non-Cygwin app calls RtlQueryProcessDebugInformation
+ on the same process in parallel, but we can avoid Cygwin processes
+ crashing process PID just because they open /proc/PID/maps in parallel
+ by serializing RtlQueryProcessDebugInformation on the same process.
+
+ Note that the mutex guards the entire code from
+ RtlCreateQueryDebugBuffer to RtlDestroyQueryDebugBuffer including the
+ code accessing the debug buffer. Apparently the debug buffer needs
+ safeguarded against parallel access all the time it's used!!! */
+ __small_swprintf (mtx_name, L"cyg-heapinfo-mtx-%u", pid);
+ mtx = CreateMutexW (&sec_none_nih, FALSE, mtx_name);
+ if (!mtx)
+ return;
+ WaitForSingleObject (mtx, INFINITE);
buf = RtlCreateQueryDebugBuffer (16 * 65536, FALSE);
+ if (buf)
+ status = RtlQueryProcessDebugInformation (pid,
+ PDI_HEAPS | PDI_HEAP_BLOCKS,
+ buf);
if (!buf)
- return;
- status = RtlQueryProcessDebugInformation (pid, PDI_HEAPS | PDI_HEAP_BLOCKS,
- buf);
+ {
+ ReleaseMutex (mtx);
+ CloseHandle (mtx);
+ return;
+ }
if (NT_SUCCESS (status)
&& (harray = (PDEBUG_HEAP_ARRAY) buf->HeapInformation) != NULL)
for (ULONG hcnt = 0; hcnt < harray->Count; ++hcnt)
@@ -653,6 +678,8 @@ struct heap_info
}
}
RtlDestroyQueryDebugBuffer (buf);
+ ReleaseMutex (mtx);
+ CloseHandle (mtx);
}
char *fill_if_match (char *base, ULONG type, char *dest)
diff --git a/winsup/cygwin/release/3.6.4 b/winsup/cygwin/release/3.6.4
index eb0d92bd498e..3286991cc081 100644
--- a/winsup/cygwin/release/3.6.4
+++ b/winsup/cygwin/release/3.6.4
@@ -21,3 +21,7 @@ Fixes:
- Fix unexpected blocking mode change by pipe_data_available()
Addresses: https://github.com/git-for-windows/git/issues/5682#issuecomment-2997428207
+
+- Fix potential crashing a process PID by accessing /proc/PID/maps
+ in parallel.
+ Addresses: https://cygwin.com/pipermail/cygwin/2025-May/258198.html
More information about the Cygwin-cvs
mailing list