realloc调用失败抛出SIGABORT信号,glibc-2.27对应代码含义咨询
代码逻辑说明
这段是glibc 2.27中__libc_realloc函数的前置安全校验逻辑,用于提前拦截非法的待重分配指针,避免后续内存操作产生不可预期的问题。
首先对应注释的含义如下:
这是一个不影响性能的轻量安全校验:内存分配器管理的内存范围永远不会在地址空间末端发生回绕,因此我们可以直接排除那些意外产生、或是被攻击者刻意构造的非法size值。只有从旧主分配区(main arena)dump出来的伪造mmap块可以跳过这个校验,因为新的malloc调用可能会提供额外的地址对齐。
整个判断逻辑可以拆解为三个部分:
- 第一个校验条件
(uintptr_t) oldp > (uintptr_t) -oldsize:用来检查内存块的地址范围是否会触发无符号整数溢出回绕。oldp是待重分配内存块的起始地址,oldsize是内存块的大小,-oldsize转换为无符号整数后等价于地址空间最大值减去oldsize再加1,如果oldp大于这个值,说明oldp + oldsize会超出地址空间上限,属于完全不可能存在的非法内存块。 - 第二个校验条件
misaligned_chunk(oldp):用来检查内存块指针是否符合glibc malloc的对齐规则。glibc默认分配的内存块地址会按架构字长的2倍对齐(64位系统为16字节对齐,32位系统为8字节对齐),如果传入的指针不满足对齐要求,说明不是glibc分配出的合法指针。 - 第三个豁免条件
!DUMPED_MAIN_ARENA_CHUNK(oldp):针对特殊场景的例外规则,如果当前内存块是从旧主分配区dump出来的伪造mmap块,就可以跳过前面两项校验,适配dump恢复场景的特殊需求。
当前面两项校验任意一项命中,同时不满足豁免条件时,就会调用malloc_printerr输出realloc(): invalid pointer错误,随后触发SIGABRT信号终止进程。
触发报错的常见场景
- 传入realloc的指针不是malloc/calloc/realloc分配的合法指针,比如传入栈地址、全局常量地址、已经被free释放的野指针
- 内存越界改写了指针值,比如缓冲区溢出覆盖了堆上存储的chunk指针,导致传入realloc的指针存在几个字节的偏移,不满足对齐要求
- 程序存在整数溢出漏洞,构造出了异常的chunk size值,导致chunk地址范围计算触发地址回绕
- 跨内存分配器重分配内存,比如用jemalloc/tcmalloc分配的指针传给glibc的realloc,或是动态库和主程序链接了不同版本的glibc,分配的指针跨实例调用realloc
内容的提问来源于stack exchange,提问作者Learner09
相关产品推荐
相关产品推荐

