[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