From 823a89d3ab367ac68c47fed46685af67cca710d0 Mon Sep 17 00:00:00 2001 From: jeromew Date: Sun, 8 Sep 2024 12:18:56 +0200 Subject: [PATCH 1/2] Fix rare corner case in ntspawn.c There could be cases when libc/proc/describefds.c calls calloc(handlecount, ..) with handlecount = 0 to initialize what will later become opt_lpExplicitHandleList. but calloc(0, ..) does not always return null so if the chosen conditional is a->opt_lpExplicitHandleList then UpdateProcThreadAttribute produces a Windows error. The modification avoids this problem. --- libc/calls/ntspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/calls/ntspawn.c b/libc/calls/ntspawn.c index 1db070f1942..17093730a9a 100644 --- a/libc/calls/ntspawn.c +++ b/libc/calls/ntspawn.c @@ -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); From 255cbffbf765824b2cd3d1cd32315ec0ce3bea21 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 8 Sep 2024 17:59:34 -0700 Subject: [PATCH 2/2] Correctly predict item count --- libc/calls/ntspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/calls/ntspawn.c b/libc/calls/ntspawn.c index 17093730a9a..ba949b71de6 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));