【问题标题】:SIGSEGV in malloc?malloc中的SIGSEGV?
【发布时间】:2011-10-21 06:12:14
【问题描述】:

谁能给出一些使malloc信号成为sigsegv的示例代码? 谷歌了一下,堆损坏可能会导致 malloc 中的 sigsegv,但我无法理解。

非常感谢。

【问题讨论】:

标签: c linux


【解决方案1】:

这很有可能会导致问题,尽管它可能是 free() 而不是 malloc() 为您提供 SIGSEGV。

 void *vp = malloc(1024);
 memset((char *)vp - 32, 0, 1024);
 free(vp);

您可能会在malloc() 中遇到崩溃:

 enum { SZ_ALLOC = 1024, SZ_PREFIX = 32, SZ_SUFFIX = 32, SET_BYTE = '\0' };

 void *v1 = malloc(SZ_ALLOC);
 free(v1);
 memset((char *)v1 - SZ_PREFIX, SET_BYTE, SZ_ALLOC + SZ_PREFIX + SZ_SUFFIX);
 void *v2 = malloc(SZ_ALLOC);

这会覆盖分配内存之前和之后的 32 个字节,如果控制信息与分配的内存连续存储(通常是这种情况),则可能会破坏任何控制信息。使用零可以最大限度地提高您获得空指针访问的机会。您可以选择一个替代值来覆盖数据,这可能意味着大小看起来大于零(其中零大小可能会保护您免受内存访问)。

当然,这都是完全未定义的行为;您可能会在memset() 中遇到崩溃,或者您可能根本不会遇到崩溃。

【讨论】:

    【解决方案2】:

    试试这个:

    void **x = malloc(1000);
    free(x);
    x[0] = x[1] = "hello";
    x = malloc(1000);
    

    它的工作原理是破坏链接的空闲列表,一个刚刚释放的块是指向不可修改内存的成员。当malloc 尝试从该列表中出列时会发生崩溃。它几乎可以肯定适用于 mallocfree 为 O(1) 的任何实现。

    【讨论】:

    • 我在我的 ubuntu 上用 vitualbox 测试过,但是什么也没发生,有什么问题吗?
    • 我已经确认它不会在 glibc 上崩溃。不幸的是我还没有弄清楚机制......
    • 我想虽然在 x[0] = x[1] = "hello"; x 指向不可修改的内存,但是 &x 可以存储任何东西,所以在 new malloc() 之后,x 只是指向新的空间...
    猜你喜欢
    • 2013-12-25
    • 2010-11-29
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多