Grigorii Belokrylov

Bugs in _lwmem_alloc_align_internal and _io_doprint

Discussion created by Grigorii Belokrylov on Feb 6, 2014
Latest reply on Feb 23, 2014 by Grigorii Belokrylov
  • Under certain conditions lightweight memory allocator doesn't fill BLOCKSIZE field of the new block which can lead to very nasty bugs after deallocation:

in mqx/source/kernel/lwmem.c in function _lwmem_alloc_align_internal on lines 450-473:

            if (next_block_size >= LWMEM_MIN_MEMORY_STORAGE_SIZE)
            {
                /*
                 * The current block is big enough to split.
                 * into 2 blocks.... the part to be allocated is one block,
                 * and the rest remains as a free block on the free list.
                 */
                next_block_ptr = (LWMEM_BLOCK_STRUCT_PTR) (pointer) ((uchar_ptr) block_ptr + requested_size);
                /* Initialize the new physical block values */
                next_block_ptr->BLOCKSIZE = next_block_size;
                /* Link new block into the free list */
                next_block_ptr->POOL = mem_pool_ptr;
                next_block_ptr->U.NEXTBLOCK = block_ptr->U.NEXTBLOCK;
                block_ptr->U.NEXTBLOCK = (pointer) next_block_ptr;

                /* Modify the current block, to point to this newly created block*/
                block_ptr->BLOCKSIZE = requested_size;
            }
            else
            {
                /* Take the entire block */
                requested_size = block_size;
                next_block_ptr = block_ptr->U.NEXTBLOCK;
            } /* Endif */

Here block_ptr points to memory in a free block with offset from the start of the block of at least (2 * LWMEM_MIN_MEMORY_STORAGE_SIZE) bytes. In the else block block_ptr->BLOCKSIZE should be set to block_size minus offset (size of a new free block).

  • Printing functions incorrectly handle "s" conversion specifier when precision is given and string doesn't contain null character:

in mqx/source/fio/_io_dopr.c in function _io_doprint:

on lines 665-668:

      for (; str_ptr[length] != '\0'; length++ )
      {
         ;
      } /* Endfor */

str_ptr equals pointer to the given string (which is not null-terminated) and it will traverse until it hits any null character in the memory that doesn't belong to the given array (though length will be reduced to precision value afterwards).

on line 859:

         number_of_characters += _io_putstr(farg, func_ptr, length, (char_ptr) str_ptr);

Function _io_putstr is called which also traverses whole array and past of it until it hits any null character. Moreover, it will return number of characters from the start of array until null character, and returned number of written characters from functions like snprintf will be greater than actual number of characters that were written.

Outcomes