[PATCH libgpg-error] spawn:w32: Fix use-after-scope of handle array passed to PROC_THREAD_ATTRIBUTE_HANDLE_LIST.

Mikhail Filippov mikhail at filippov.me
Mon Mar 16 20:37:16 CET 2026


I found this bug while testing GnuPG on Windows ARM64: gpg-agent and dirmngr would not start, with CreateProcessW returning error 87.

---

From ed2cccb9d778a918fd05a7af39be966e925db587 Mon Sep 17 00:00:00 2001
From: Mikhail Filippov <mikhail at filippov.me>
Date: Mon, 16 Mar 2026 19:52:56 +0400
Subject: [PATCH libgpg-error] spawn:w32: Fix use-after-scope of handle array
 passed to PROC_THREAD_ATTRIBUTE_HANDLE_LIST.

* src/spawn-w32.c (_gpgrt_process_spawn): Move the hd[32] array
declaration from inside the inner block to the function scope, so that
the array remains live when CreateProcessW is called.

UpdateProcThreadAttribute stores a pointer to the caller-supplied
handle array inside the PROC_THREAD_ATTRIBUTE_LIST.  The documentation
states: "lpValue: A pointer to the attribute value.  This value must
persist until the attribute list is destroyed using the
DeleteProcThreadAttributeList function."

In the original code, hd[32] was declared inside a { } block that ends
before CreateProcessW is called.  Its lifetime, therefore, expired before
the kernel read it back through si.lpAttributeList.  On x86-64, the
stack slot happened to remain undisturbed, masking the bug.  On
Windows ARM64, the compiler and/or kernel accesses the list at a
different point, causing CreateProcessW to return
ERROR_INVALID_PARAMETER (ec=87) and preventing gpg-agent / dirmngr
from being auto-spawned.
---
 src/spawn-w32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/spawn-w32.c b/src/spawn-w32.c
index c85be91..f21991a 100644
--- a/src/spawn-w32.c
+++ b/src/spawn-w32.c
@@ -548,6 +548,7 @@ _gpgrt_process_spawn (const char *pgmname, const char *argv[],
   HANDLE hd_in[2];
   HANDLE hd_out[2];
   HANDLE hd_err[2];
+  HANDLE hd[32];
   BOOL ask_inherit = FALSE;
   struct gpgrt_spawn_actions act_default;
   char *env = NULL;
@@ -710,7 +711,6 @@ _gpgrt_process_spawn (const char *pgmname, const char *argv[],
     hd_err[1] = w32_open_null (1, enable_null_device);
 
   {
-    HANDLE hd[32];
     HANDLE *hd_p = act->inherit_hds;
     int j = 0;
 
-- 
2.53.0


-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.gnupg.org/pipermail/gnupg-devel/attachments/20260316/0e498560/attachment.sig>


More information about the Gnupg-devel mailing list