HAL_ChibiOS: added check for overwrite of nullptr on H7

the STM32H7 has 64k of ITCM memory at address zero. We allow
allocation of everything except the first 1024 bytes. This checks for
those reserved bytes being overwritte, which would indicate a write to
nullptr
This commit is contained in:
Andrew Tridgell 2020-11-15 08:23:45 +11:00 committed by Peter Barker
parent 8f682c0782
commit 408f8b3940
3 changed files with 51 additions and 0 deletions

View File

@ -492,6 +492,34 @@ void Scheduler::_io_thread(void* arg)
}
}
#if defined(STM32H7)
/*
the H7 has 64k of ITCM memory at address zero. We reserve 1k of it
to prevent nullptr being valid. This function checks that memory is
always zero
*/
void Scheduler::check_low_memory_is_zero()
{
const uint32_t *lowmem = nullptr;
// we start at address 0x1 as reading address zero causes a fault
for (uint16_t i=1; i<256; i++) {
if (lowmem[i] != 0) {
// re-use memory guard internal error
AP_memory_guard_error(1023);
break;
}
}
// we can't do address 0, but can check next 3 bytes
const uint8_t *addr0 = (const uint8_t *)0;
for (uint8_t i=1; i<4; i++) {
if (addr0[i] != 0) {
AP_memory_guard_error(1023);
break;
}
}
}
#endif // STM32H7
void Scheduler::_storage_thread(void* arg)
{
Scheduler *sched = (Scheduler *)arg;
@ -499,11 +527,21 @@ void Scheduler::_storage_thread(void* arg)
while (!sched->_hal_initialized) {
sched->delay_microseconds(10000);
}
#if defined STM32H7
uint8_t memcheck_counter=0;
#endif
while (true) {
sched->delay_microseconds(10000);
// process any pending storage writes
hal.storage->_timer_tick();
#if defined STM32H7
if (memcheck_counter++ % 50 == 0) {
// run check at 2Hz
sched->check_low_memory_is_zero();
}
#endif
}
}

View File

@ -172,5 +172,9 @@ private:
void _run_timers();
void _run_io(void);
static void thread_create_trampoline(void *ctx);
#if defined STM32H7
void check_low_memory_is_zero();
#endif
};
#endif

View File

@ -84,6 +84,15 @@ void malloc_init(void)
chMtxObjectInit(&mem_mutex);
#endif
#if defined(STM32H7)
// zero first 1k of ITCM. We leave 1k free to avoid addresses
// close to nullptr being valid. Zeroing it here means we can
// check for changes which indicate a write to an uninitialised
// object. We start at address 0x1 as writing the first byte
// causes a fault
memset((void*)0x00000001, 0, 1023);
#endif
uint8_t i;
for (i=1; i<NUM_MEMORY_REGIONS; i++) {
chHeapObjectInit(&heaps[i], memory_regions[i].address, memory_regions[i].size);