Stopped two POSIX call sites falling through their error handler (#625)

posix_internal_error() never comes back for a non-zero code: its body is
"while (error_code) { ; }". Most callers in the layer still follow it with an
explicit error return. Two do not, and both fall through into a pointer
dereference, so they are only correct because the handler happens to hang.

That is a fragile thing to rely on. The C standard permits an implementation to
assume a loop with no side effects terminates (C11 6.8.5p6), so the guarantee is
a property of the toolchain rather than of the language. Both toolchains the
project supports do preserve the loop today - checked with GCC 14.3 at -O0, -O1,
-O2 and -Os, and with Clang 22 at -O0 and -O2 - so nothing is broken right now.
Neither call site should depend on that.

mq_send() falls through with bp indeterminate, having just been told the
allocation failed, and would copy msg_len bytes through it. Report ENOMEM and
return ERROR instead.

posix_thread2tid() falls through with thread_ptr NULL. posix_thread2tcb() returns
NULL for that input, and the next line reads p_tcb->pthreadID. Return zero, which
is never a valid pthread ID because px_pth_create.c assigns the address of the
TCB as the ID.

No behaviour changes while the handler keeps hanging; both additions are
unreachable today.

Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
This commit is contained in:
Frédéric Desbiens
2026-08-16 18:24:25 -04:00
committed by GitHub
parent 2f378a4c8e
commit 3501c5c31d
2 changed files with 17 additions and 2 deletions
@@ -167,7 +167,16 @@ ULONG msg[TX_POSIX_MESSAGE_SIZE];
if (temp1 != TX_SUCCESS)
{
posix_internal_error(9999);
posix_internal_error(9999);
/* posix_internal_error() does not return today, but do not depend on
that: bp is indeterminate here, so falling through would copy
msg_len bytes through an unset pointer. */
posix_errno = ENOMEM;
posix_set_pthread_errno(ENOMEM);
/* Return ERROR. */
return(ERROR);
}
/* Got the memory , Setup source and destination pointers
Cast them in UCHAR as message length is in bytes. */
@@ -538,7 +538,13 @@ POSIX_TCB *p_tcb;
if (!thread_ptr)
{
/* Not called from a thread - error! */
posix_internal_error(222);
posix_internal_error(222);
/* posix_internal_error() does not return today, but do not depend on
that: posix_thread2tcb() hands back NULL for this input and the read
below would dereference it. A pthread ID is the address of the TCB,
so zero is never a valid one. */
return((pthread_t) 0);
}
/* Get the TCB for this pthread */