c - 这个宏可以安全地复制字符串吗?

标签 c

这个宏是安全的还是我应该确保 alloca 永远不会返回 NULL?

#define DO_COPY(x) strcpy(alloca(strlen((x)) + 1), x)

最佳答案

如果字符串是用户控制的,我会说 alloca 是不安全的。 alloca 在许多编译器中的实现方式,它不会对从堆栈指针中减去(或添加到堆栈指针中)的数量进行任何类型的完整性检查。即使堆栈周围有大片红色区域,也可以相对容易地使 alloca():ed 字符串指向堆栈外部。

特别是在线程环境中,线程堆栈可能非常小并且彼此靠近。

在 linux 机器上我可以测试它需要一个 10MB 的字符串来开始在一些其他线程堆栈上涂鸦。在 MacOS 上 512kB 似乎就足够了。

这里有一个快速技巧,可以看看你最终能达到多近(请注意,如果堆栈分配是使用一些随机分配器(如 OpenBSD 或其他一些认真对待分配器安全的系统)完成的,这并不能真正告诉你太多信息) .

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>

void *
x(void *v)
{
    int x;

    return &x;
}

int
main(int argc, char **argv)
{
    pthread_t ta, tb;
    char *va, *vb;

    pthread_create(&ta, NULL, x, NULL);
    pthread_create(&tb, NULL, x, NULL);

    pthread_join(ta, (void **)&va);
    pthread_join(tb, (void **)&vb);

    printf("diff: %d\n", abs((intptr_t)vb-(intptr_t)va));

    return 0;
}

下面是 strcpy(alloca(strlen(s) + 1), s) 被编译成的内容:

    movq    %rbx, %rdi
    call    _strlen
    addq    $31, %rax
    andq    $-16, %rax
    subq    %rax, %rsp
    movq    %rsp, %rdi
    movq    %rbx, %rsi
    call    _strcpy

请注意,在从堆栈指针中减去 strlen(以 %rax 为单位)的返回值之前,除了快速对齐之外,没有任何健全性检查。

关于c - 这个宏可以安全地复制字符串吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12946385/

相关文章:

将 =C3=B6 转换为 ö 假设 UTF-8

C 尝试添加撇号

c - 分配对象和结构的有效类型

c - 服务器 "Kill"本身

c - C中void指针的指针算法

c++ - 将 argslist "..."从 C++ 转发到 C 函数

c - 从 c 调用汇编函数

c - 如何在 C 中调用 COM 组件

c - 如何删除在C循环中作为函数调用的字符图像?

c - 从文件读取到数组