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
This commit is contained in:
jeromew 2024-09-11 05:17:26 +02:00 committed by GitHub
parent fbdf9d028c
commit 51c0f44d1c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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);