threadx icon indicating copy to clipboard operation
threadx copied to clipboard

Unaligned writes are not allowed with gcc ubsan (-fsanitize=undefined), this fails on 6.1.8 with ports/linux/gnu

Open owbear opened this issue 3 years ago • 5 comments

https://github.com/azure-rtos/threadx/blob/b42c5acd8b9b1eb156c25e0b18c82beecfc033a1/ports/linux/gnu/src/tx_thread_stack_build.c#L131

The write here gives me an error regarding unaligned writes. memset() works

owbear avatar Nov 24 '22 09:11 owbear

You can ignore this. The stack is aligned previously - https://github.com/azure-rtos/threadx/blob/b42c5acd8b9b1eb156c25e0b18c82beecfc033a1/common/src/tx_thread_create.c#L132

goldscott avatar Dec 01 '22 02:12 goldscott

A bit more context here: in the linux/gnu port tx_thread_stack_ptr is always unaligned as it is tx_thread_stack_end-8:

/* Setup a fake thread stack pointer.   */
thread_ptr -> tx_thread_stack_ptr =  (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8);

/* Clear the first word of the stack.  */
*(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) =  0;

owbear avatar Dec 01 '22 08:12 owbear

Hi @owbear - my previous comment is only relevant if TX_ENABLE_STACK_CHECKING is defined. When this symbol is defined, ThreadX ensures that the stack pointer and stack size are aligned, as well as some runtime checking during context switches to check for stack overflows.

If not using TX_ENABLE_STACK_CHECKING, it is the developer's responsibility to ensure that the stack is aligned.

goldscott avatar Dec 15 '22 22:12 goldscott

Hi Scott! TX_ENABLE_STACK_CHECKING fails in a different way with ubsan enabled using ports/linux/gnu:

Starting program: arch/native/radiohub 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0xf4affb40 (LWP 37588)]
[New Thread 0xf3effb40 (LWP 37589)]
[New Thread 0xf36feb40 (LWP 37590)]
/home/gotber/src/radiohub/code-review/env/threadx/common/src/tx_thread_system_resume.c:108:5: runtime error: load of misaligned address 0x56815217 for type 'ULONG', which requires 4 byte alignment
0x56815217: note: pointer points here
 ef ef ef ef 00  00 00 00 ef ef ef ef ef  ef ef ef ef ef ef ef ef  d8 60 81 56 ee ee ff ff  00 00 00
             ^ 
[Thread 0xf36feb40 (LWP 37590) exited]
[Thread 0xf4affb40 (LWP 37588) exited]
[Thread 0xf7012440 (LWP 37584) exited]
[Inferior 1 (process 37584) exited with code 01]
(gdb) l env/threadx/common/src/tx_thread_system_resume.c:108
103	
104	
105	#ifdef TX_ENABLE_STACK_CHECKING
106	
107	    /* Check this thread's stack.  */
108	    TX_THREAD_STACK_CHECK(thread_ptr)
109	#endif
110	
111	    /* Lockout interrupts while the thread is being resumed.  */
112	    TX_DISABLE

This misaligned access is in TX_THREAD_STACK_CHECK when it tries to load a 4-byte word from thread_ptr->tx_thread_stack_highest_ptr - 1

    if (*(((ULONG *) (thread_ptr) -> tx_thread_stack_highest_ptr) - 1) != TX_STACK_FILL)

owbear avatar Dec 16 '22 08:12 owbear

That misalignment could be resolve with memcmp()

    static ULONG tx_stack_fill = TX_STACK_FILL;
    if (0 != memcmp(&tx_stack_fill, (thread_ptr)->tx_thread_stack_highest_ptr - 1, sizeof tx_stack_fill))

owbear avatar Dec 16 '22 09:12 owbear