diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2023-01-17 12:18:51 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2023-01-17 21:49:39 +0300 |
commit | fb16f490bf6e56ace20a7d7ee29a8a46aef3adba (patch) | |
tree | efdfa8caef3ad6785852549bdcd000bb689c397f /winsup | |
parent | 1e854c18e5b2261e159671f6c09de593f3618ca2 (diff) |
Cygwin: open_shared: try harder allocating a shared region
For fixed regions (cygwin/user/myself/shared console), try fixed
address first. Fallback to non-fixed region. Don't even try fixed
address if the Cygwin DLL gets dynamically loaded.
For non-fixed regions, try to allocate in a loop within the area
from SHARED_REGIONS_ADDRESS_LOW to SHARED_REGIONS_ADDRESS_HIGH.
Fixes: 60675f1a7eb2 ("Cygwin: decouple shared mem regions from Cygwin DLL")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/mm/shared.cc | 58 | ||||
-rw-r--r-- | winsup/cygwin/release/3.4.4 | 6 |
2 files changed, 53 insertions, 11 deletions
diff --git a/winsup/cygwin/mm/shared.cc b/winsup/cygwin/mm/shared.cc index aa9997c75..d23cc8e0e 100644 --- a/winsup/cygwin/mm/shared.cc +++ b/winsup/cygwin/mm/shared.cc @@ -122,6 +122,7 @@ static uintptr_t region_address[] = SHARED_CONSOLE_REGION_ADDRESS, /* SH_SHARED_CONSOLE */ 0 }; +static NO_COPY uintptr_t next_address = SHARED_REGIONS_ADDRESS_LOW; void * open_shared (const WCHAR *name, int n, HANDLE& shared_h, DWORD size, @@ -138,14 +139,9 @@ open_shared (const WCHAR *name, int n, HANDLE& shared_h, DWORD size, { WCHAR map_buf[MAX_PATH]; WCHAR *mapname = NULL; - void *shared; + void *shared = NULL; void *addr; - if (m == SH_JUSTCREATE || m == SH_JUSTOPEN) - addr = NULL; - else - addr = (void *) region_address[m]; - created = false; if (!shared_h) { @@ -170,14 +166,54 @@ open_shared (const WCHAR *name, int n, HANDLE& shared_h, DWORD size, return NULL; } - shared = MapViewOfFileEx (shared_h, FILE_MAP_READ | FILE_MAP_WRITE, - 0, 0, 0, addr); + if (m < SH_TOTAL_SIZE && !dynamically_loaded) + { + /* Fixed regions. Don't do that if Cygwin gets dynamically loaded. + The process loading the DLL might be configured with High-Entropy + ASLR. Chances for collisions are pretty high. + + Note that we don't actually *need* fixed addresses. The only + advantage is reproducibility to help /proc/<PID>/maps along. */ + addr = (void *) region_address[m]; + shared = MapViewOfFileEx (shared_h, FILE_MAP_READ | FILE_MAP_WRITE, + 0, 0, 0, addr); + } + /* Also catch the unlikely case that a fixed region can't be mapped at the + fixed address. */ + if (!shared) + { + /* Locate shared regions in the area between SHARED_REGIONS_ADDRESS_LOW + and SHARED_REGIONS_ADDRESS_HIGH, retrying until we have a slot. + Don't use MapViewOfFile3 (loader deadlock during fork. */ + bool loop = false; + + addr = (void *) next_address; + do + { + shared = MapViewOfFileEx (shared_h, FILE_MAP_READ | FILE_MAP_WRITE, + 0, 0, 0, addr); + if (!shared) + { + next_address += wincap.allocation_granularity (); + if (next_address >= SHARED_REGIONS_ADDRESS_HIGH) + { + if (loop) + break; + next_address = SHARED_REGIONS_ADDRESS_LOW; + loop = true; + } + addr = (void *) next_address; + } + } + while (!shared); + } if (!shared) - api_fatal ("MapViewOfFileEx '%W'(%p), %E. Terminating.", mapname, shared_h); + api_fatal ("MapViewOfFileEx '%W'(%p, size %u, m %d, created %d), %E. " + "Terminating.", mapname, shared_h, size, m, created); - debug_printf ("name %W, n %d, shared %p (wanted %p), h %p, m %d", - mapname, n, shared, addr, shared_h, m); + debug_printf ("name %W, shared %p (wanted %p), h %p, m %d, created %d", + mapname, shared, addr, shared_h, m, created); return shared; } diff --git a/winsup/cygwin/release/3.4.4 b/winsup/cygwin/release/3.4.4 index 2c93cd066..409c58929 100644 --- a/winsup/cygwin/release/3.4.4 +++ b/winsup/cygwin/release/3.4.4 @@ -16,3 +16,9 @@ Bug Fixes - Fix vmstat(1) printing an error message on single core CPUs. Addresses: https://cygwin.com/pipermail/cygwin/2023-January/252857.html + +- Fix potential process termination during process initialization. + Most easily reproducible is the case of non-Cygwin processes running + with high-entropy VA enabled and loading the Cygwin DLL dynamically. + Addresses: https://cygwin.com/pipermail/cygwin/2023-January/252765.html + https://cygwin.com/pipermail/cygwin/2023-January/252865.html |