ARMmbed / core-util

DEPRECATED: Mbed 3 utilities library
Other
12 stars 17 forks source link

Race condition in PoolAllocator #104

Closed bremoran closed 8 years ago

bremoran commented 8 years ago

There is a race condition in PoolAllocator. The conditions for failure are:

  1. There is exactly one element left in the pool
  2. An alloc() call is initiated
  3. The first alloc call passes line 38
  4. A second alloc() call is initiated with higher priority before the first alloc() call completes line 40

Failing behaviour:

  1. prev_free will be reloaded with the new contents of _free_block, which will be 0.
  2. line 39 will cause new_free to be loaded with *(uint32_t *)(0) (this is __stack so it is a pointer to valid memory)
  3. atomic_cas((uintptr_t*)&_free_block, &prev_free, (uintptr_t)new_free) will install __stack in _free_block
  4. alloc() will return NULL (this is expected behaviour)
  5. A subsequent call to either alloc() or free() will have unintended consequences: * A call to alloc() will return __stack * A call to free() will hide __stack for a later alloc()

To solve this problem, alloc() should check for prev_free == NULL on each loop, rather than just on entry.

bremoran commented 8 years ago

cc @bogdanm @rgrover @0xc0170

ciarmcom commented 8 years ago

ARM Internal Ref: IOTSFW-2381