From 3c4f753840b8637d6dc402a74c0f70a13eafac6f Mon Sep 17 00:00:00 2001 From: thexai <58434170+thexai@users.noreply.github.com> Date: Sat, 25 Jul 2026 19:46:26 +0200 Subject: [PATCH 1/3] gh-152433: Windows: fix ``ctypes`` MemoryError in UWP build UWP does not allow allocating memory with code execution permissions. --- Modules/_ctypes/malloc_closure.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index 62c7aa5d6affbfb..95ebb043687ea72 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -68,10 +68,24 @@ static void more_core(void) /* allocate a memory block */ #ifdef MS_WIN32 +#ifdef MS_WINDOWS_DESKTOP item = (ITEM *)VirtualAlloc(NULL, count * sizeof(ITEM), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else // UWP + /* Due security restrictions, UWP not allows request Read-Write-Execute permissions at once. + The correct flow in UWP for execute dynamic code in memmory is: + 1. Alloate as Read-Write (PAGE_READWRITE) and write dynamic code to memmory. + 2. Change to Executable (PAGE_EXECUTE_READ) with 'VirtualProtectFromApp'. + 3. Flush cache with 'FlushInstructionCache' to ensure CPU instruction cache coherency + before executing the generated code. + !@todo implement points 2. 3. in the appropriate places */ + item = (ITEM*)VirtualAllocFromApp(NULL, + count * sizeof(ITEM), + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); +#endif // !MS_WINDOWS_DESKTOP if (item == NULL) return; #else From 7bd108c5b3fa6597407559a3722aa7803892c1f8 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 17 Sep 2026 17:25:30 +0100 Subject: [PATCH 2/3] Apply suggestion from @zooba --- Modules/_ctypes/malloc_closure.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index 95ebb043687ea72..9b9d0411b83b323 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -80,7 +80,8 @@ static void more_core(void) 2. Change to Executable (PAGE_EXECUTE_READ) with 'VirtualProtectFromApp'. 3. Flush cache with 'FlushInstructionCache' to ensure CPU instruction cache coherency before executing the generated code. - !@todo implement points 2. 3. in the appropriate places */ + TODO: Implement 2 and 3 in the appropriate places. For now, this defers + the error from import time to time of use (or never, if an app avoids it). item = (ITEM*)VirtualAllocFromApp(NULL, count * sizeof(ITEM), MEM_COMMIT | MEM_RESERVE, From b8becdf44b2d79832f43317eb795a6b9c88f06fd Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 17 Sep 2026 18:16:15 +0100 Subject: [PATCH 3/3] Apply suggestion from @zooba --- Modules/_ctypes/malloc_closure.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index 9b9d0411b83b323..3abab8873acbd01 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -81,7 +81,7 @@ static void more_core(void) 3. Flush cache with 'FlushInstructionCache' to ensure CPU instruction cache coherency before executing the generated code. TODO: Implement 2 and 3 in the appropriate places. For now, this defers - the error from import time to time of use (or never, if an app avoids it). + the error from import time to time of use (or never, if an app avoids it). */ item = (ITEM*)VirtualAllocFromApp(NULL, count * sizeof(ITEM), MEM_COMMIT | MEM_RESERVE,