From 51c0f44d1c664fe44c4a825b9ad9b5913844df9d Mon Sep 17 00:00:00 2001 From: jeromew Date: Wed, 11 Sep 2024 05:17:26 +0200 Subject: [PATCH] Fix rare corner case in ntspawn.c (#1284) This change fixes a CreateProcess failure when a process is spawned with no handles inherited. This is due to violating a common design rule in C that works as follows: when you have (ptr, size) the ptr must be ignored when size is zero. That's because cosmo's malloc(0) always returns a non null pointer, which was happening in __describe_fds(), but ntspawn() was basing its decision off the nullness of the pointer rather than its size --- libc/calls/ntspawn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/calls/ntspawn.c b/libc/calls/ntspawn.c index 1db070f19..ba949b71d 100644 --- a/libc/calls/ntspawn.c +++ b/libc/calls/ntspawn.c @@ -153,7 +153,7 @@ static textwindows int ntspawn2(struct NtSpawnArgs *a, struct SpawnBlock *sb) { alignas(16) char memory[128]; size_t size = sizeof(memory); struct NtProcThreadAttributeList *alist = (void *)memory; - uint32_t items = !!a->opt_hParentProcess + !!a->opt_lpExplicitHandleList; + uint32_t items = !!a->opt_hParentProcess + !!a->dwExplicitHandleCount; ok = InitializeProcThreadAttributeList(alist, items, 0, &size); if (!ok && GetLastError() == kNtErrorInsufficientBuffer) { ok = !!(alist = freeme = ntspawn_malloc(size)); @@ -166,7 +166,7 @@ static textwindows int ntspawn2(struct NtSpawnArgs *a, struct SpawnBlock *sb) { alist, 0, kNtProcThreadAttributeParentProcess, &a->opt_hParentProcess, sizeof(a->opt_hParentProcess), 0, 0); } - if (ok && a->opt_lpExplicitHandleList) { + if (ok && a->dwExplicitHandleCount) { ok = UpdateProcThreadAttribute( alist, 0, kNtProcThreadAttributeHandleList, a->opt_lpExplicitHandleList, a->dwExplicitHandleCount * sizeof(*a->opt_lpExplicitHandleList), 0, 0);