From 3501c5c31d9945b77649fec94382821f50d6148e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Sun, 16 Aug 2026 18:24:25 -0400 Subject: [PATCH] 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) --- utility/rtos_compatibility_layers/posix/px_mq_send.c | 11 ++++++++++- utility/rtos_compatibility_layers/posix/px_pth_init.c | 8 +++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/utility/rtos_compatibility_layers/posix/px_mq_send.c b/utility/rtos_compatibility_layers/posix/px_mq_send.c index d4702808..f641419a 100644 --- a/utility/rtos_compatibility_layers/posix/px_mq_send.c +++ b/utility/rtos_compatibility_layers/posix/px_mq_send.c @@ -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. */ diff --git a/utility/rtos_compatibility_layers/posix/px_pth_init.c b/utility/rtos_compatibility_layers/posix/px_pth_init.c index 5d2f36ad..a2f97be7 100644 --- a/utility/rtos_compatibility_layers/posix/px_pth_init.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_init.c @@ -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 */