jdoe95/mrtos

Casting ``struct lstitem_s`` from other list element types is unsafe

jdoe95 opened this issue · 0 comments

struct lstitem_s
{
	struct lstitem_s *volatile p_prev; /* previous item */
	struct lstitem_s *volatile p_next; /* next item     */
};

struct mblk_s
{
	struct mblk_s *volatile p_prev; /* previous block */
	struct mblk_s *volatile p_next; /* next block     */
	volatile uint_t size;           /* block size     */
	struct mlst_s *volatile p_mlst; /* parent list    */
};

The RTOS reuses its linked list code by defining insertion/removal methods for struct lstitem_s and then performs casts to other linked list element types like mblk_s to reuse some of the methods. Both lstitem_s and mblk_s have two pointers at the beginning of the struct. This however, may not always work, because no assumptions can be made on the internal layout of the structs even though they are defined very similarly.

There is something in the C standards called a 'common initial sequence', where multiple structs of different types with a common initial sequence when defined as members of a union share the same memory layout in their common part. However, in this case, even though the common part are both pointers, the pointers are to different types, so they are not generally considered a 'common initial sequence'.

It is unlikely that the compiler will generate different memory layouts for the initial part of these structs, but there is no guarantee that it wouldn't because this type of conversion is not backed by the language standards.