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

Mikhail Filippov via Gnupg-devel <[email protected]> Mon, 16 Mar 2026 23:37:16 +0400
Newsgroups gmane.comp.encryption.gpg.devel
Message-ID <[email protected]>
This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
--===============8332165656532263093==
Content-Language: en-US
Content-Type: multipart/signed; micalg=pgp-sha256;
 protocol="application/pgp-signature";
 boundary="------------0D0RV8BdjheZP7duWgeUCGa0"

This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
--------------0D0RV8BdjheZP7duWgeUCGa0
Content-Type: multipart/mixed; boundary="------------XZ05pwe5KTGQq1HmqFhRHH0I";
 protected-headers="v1"
From: Mikhail Filippov <[email protected]>
To: [email protected]
Message-ID: <[email protected]>
Subject: [PATCH libgpg-error] spawn:w32: Fix use-after-scope of handle array
 passed to PROC_THREAD_ATTRIBUTE_HANDLE_LIST.

--------------XZ05pwe5KTGQq1HmqFhRHH0I
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

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

---

=46rom ed2cccb9d778a918fd05a7af39be966e925db587 Mon Sep 17 00:00:00 2001
From: Mikhail Filippov <[email protected]>
Date: Mon, 16 Mar 2026 19:52:56 +0400
Subject: [PATCH libgpg-error] spawn:w32: Fix use-after-scope of handle ar=
ray
=C2=A0passed 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.=C2=A0 The documentati=
on
states: "lpValue: A pointer to the attribute value.=C2=A0 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.=C2=A0 Its lifetime, therefore, expired b=
efore
the kernel read it back through si.lpAttributeList.=C2=A0 On x86-64, the
stack slot happened to remain undisturbed, masking the bug.=C2=A0 On
Windows ARM64, the compiler and/or kernel accesses the list at a
different point, causing CreateProcessW to return
ERROR_INVALID_PARAMETER (ec=3D87) and preventing gpg-agent / dirmngr
from being auto-spawned.
---
=C2=A0src/spawn-w32.c | 2 +-
=C2=A01 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[],
=C2=A0 =C2=A0HANDLE hd_in[2];
=C2=A0 =C2=A0HANDLE hd_out[2];
=C2=A0 =C2=A0HANDLE hd_err[2];
+=C2=A0 HANDLE hd[32];
=C2=A0 =C2=A0BOOL ask_inherit =3D FALSE;
=C2=A0 =C2=A0struct gpgrt_spawn_actions act_default;
=C2=A0 =C2=A0char *env =3D NULL;
@@ -710,7 +711,6 @@ _gpgrt_process_spawn (const char *pgmname, const char=
 *argv[],
=C2=A0 =C2=A0 =C2=A0hd_err[1] =3D w32_open_null (1, enable_null_device);
=C2=A0
=C2=A0 =C2=A0{
-=C2=A0 =C2=A0 HANDLE hd[32];
=C2=A0 =C2=A0 =C2=A0HANDLE *hd_p =3D act->inherit_hds;
=C2=A0 =C2=A0 =C2=A0int j =3D 0;
=C2=A0
--=C2=A0
2.53.0



--------------XZ05pwe5KTGQq1HmqFhRHH0I--

--------------0D0RV8BdjheZP7duWgeUCGa0
Content-Type: application/pgp-signature; name="OpenPGP_signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="OpenPGP_signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEeJWzo+MAlU66yOwRjvTumErJHV4FAmm4W+wACgkQjvTumErJ
HV59ZhAA3nYWHjsd02JzpEQ4z/p9YFI4gW12ZBpX2WvHoFZSah93BlpQFKXrt7BT
ygaqViqSy5YnRSKYbjPXr8TQFRLGqX8dzfx3l36G28roN9tVm4mcL5Ub/+K16D5f
+mfHoPbsnB0/i8foE796GJnp4zd3oJLc9LjY9gXkce/+EWvTiJyaLaitEKYdRKpy
qKx79STxRLQMjp1x+K6GtpoTFX7pcn6LnIPlITpym85lRzrpsaNfVfq2Wj2ietaR
wd+QQ/Z2gkggOJpNRiGHV2FLcwPAs6KVFq/GqZdorUvQiopiLcGlDEllnW6h1M1M
NfNHV5YHBLdb0qKkBLi/dBcNfi7CJfILFGBs089QI1P4DkihB/MkK4AWXQV+RI9z
8X1N29W6RnTWRvWBpYGlJd3+1NOY5Whd/TDCSe8Kgi5UjmPGfFIXn8kSBHoIXz9e
QyZigoTsofXig6PpNiDJEsSENPbddE4GyTAs/KeDVQ0i0vNV/znUb8rwtZSYLUHc
A/jKOS8cH3CndRUD1rgk7OBVD0TN464KfKXb9d6pT4t9pvEr9r1GD3xoCnsl8iKO
M5G6G04PKsyPTH3WG9HP+oPkKA1xIXCNiZ34l83keaBtjA5htZInNf9CENfNaJiO
PKmrG6RgjxVD22UA8glYOPMn6iQOgdRcm4EI3QsHcQWQj+/gI0I=
=pfxH
-----END PGP SIGNATURE-----

--------------0D0RV8BdjheZP7duWgeUCGa0--


--===============8332165656532263093==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Gnupg-devel mailing list
[email protected]
https://lists.gnupg.org/mailman/listinfo/gnupg-devel

--===============8332165656532263093==--