内存溢出(Memory Overflow)指的是程序尝试访问超出分配给它的内存块末尾的内存区域。这通常会导致未定义行为,比如数据损坏、系统crash等。正是因为超出末尾区域,所以边界标记法也就被设计出来了。
边界标记法
在分配的内存块的开始和结束位置添加特定的标记(例如,0xDEADBEEF),这样在内存操作前后检查这些标记是否被改变,从而检测到溢出。我们以FreeRTOS的内存分配API为例,
#define MEMORY_GUARD 0xDEADBEEF
void* secure_malloc(size_t size) {
void* ptr = pvPortMalloc(size + 2 * sizeof(unsigned int));
if (ptr != NULL) {
*(unsigned int*)ptr = MEMORY_GUARD; // 起始标记
*(unsigned int*)((unsigned int)ptr + size + sizeof(unsigned int)) = MEMORY_GUARD; // 结束标记
return (unsigned int*)ptr + 1; // 跳过起始标记
}
return NULL;
}
void secure_free(void* ptr) {
if (ptr != NULL) {
if (*(unsigned int*)((unsigned int)ptr - sizeof(unsigned int)) == MEMORY_GUARD &&
*(unsigned int*)((unsigned int)ptr + *(unsigned int*)((unsigned int)ptr - sizeof(unsigned int) * 2)) == MEMORY_GUARD) {
vPortFree((unsigned int*)ptr - 1); // 还原指针,并释放原始内存块
} else {
// 检测到溢出或损坏,可以采取措施(例如记录日志或重置系统)
}
}
}上述代码可以看到,在进行malloc()时,多分配出来2个uint32_t的空间,并在头和尾部填写标记,这样,在Free()的时候就可以通过判断待释放的内存的头和尾是否仍为预留的标记,从而观察到是否有内存溢出的情况。
我要赚赏金
