【问题标题】:GNU C: What will happen if i overwrite malloc() free() but not realloc()?GNU C:如果我覆盖 malloc() free() 而不是 realloc() 会发生什么?
【发布时间】:2020-03-26 08:20:02
【问题描述】:

我正在使用 ARM 交叉工具链 arm-none-ebi-gcc 为嵌入式系统编码。因为代码运行的是freeRTOS,它有自己的堆内存管理,所以我想覆盖libc中的malloc()、free()和realloc()并将它们简单地包装起来以调用freeRTOS中的函数。只有一个问题,freeRTOS 没有 realloc(),这很奇怪,但我的代码肯定需要它。所以我想了解,如果我只覆盖 malloc() 和 free() 但仍将 realloc() 保留为 libc 中的版本,会发生什么?另外,我觉得提供我自己的 realloc() 只是用新的大小调用 malloc() 并在分配新的内存块后执行 memcopy 在我看来不够安全,因为新的大小通常大于旧的大小我的应用程序,所以当我执行一个大小大于实际分配的内存块的 memcopy() 时,可能会产生一些指针访问错误,这可能吗?

提前致谢。 -木质

【问题讨论】:

    标签: c malloc freertos


    【解决方案1】:

    部分替换分配器(替换某些函数但不替换其他函数)不起作用。在最坏的情况下,您会因为一个实现将另一个数据结构解释为自己的数据结构而导致严重的堆数据结构损坏。如果这样做了,则可以加强对这一点的处理,以便在运行时无法链接或无法分配(提供空指针结果),我在 musl libc 中执行了此操作,如这些提交中所述:

    但我怀疑许多其他实现是否采取了相同的预防措施。他们不会帮助你真正想要的东西;他们只是防止灾难性的结果。

    如果你真的需要realloc,你将不得不为你正在采用的实现制作一个工作。最简单的方法是将其设为mallocmemcpyfree,但实际上您需要一种方法来确定传递给memcpy 的长度参数。如果您只是通过新的长度,它可能在没有 MMU 的微控制器上是安全的,只要您的长度不太大,它们就有可能超出 MMIO 范围或其他东西。但正确的做法是充分阅读malloc 实现以了解它存储分配大小的位置,然后编写自己的代码来提取它。此时,您可以使用memcpy 编写正确/有效的realloc

    【讨论】:

    • 非常有帮助。现在我可以决定我必须写一个新的realloc,因为我知道freeRTOS 的malloc 将先前分配的块的长度信息存储在哪里。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2017-08-19
    • 2010-10-30
    • 1970-01-01
    相关资源
    最近更新 更多