2012-10-18 1 views
1

이 매크로는 안전합니까? 아니면 alloca가 NULL을 반환하지 않도록해야합니까?문자열을 복사 할 때이 매크로가 안전합니까?

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

alloca()? 그것이 malloc이라면 나는 그렇다고 말할 것입니다. – SparKot

+3

http://stackoverflow.com/questions/1018853/why-is-alloca-not-considered-good-practice- 만약 당신이 alloca를 사용한다면 당신은 당신이하고있는 일에 대해 꽤 확신 할 필요가 있습니다 ... – John3136

+0

전적으로 달려 있습니다. 당신이 그것을 사용하는 맥락에서. –

답변

2

문자열이 사용자가 제어하는 ​​경우 alloca는 안전하지 않다고 말하고 싶습니다. alloca가 많은 컴파일러에서 구현되는 방식은 스택 포인터에서 뺄셈하는 양 (또는 스택이 그렇게 커지면 증가시킨다)에 대해 온 전성 검사를하지 않는다. 스택 주위에 큰 빨간 영역이 있더라도 alloca() : 문자열을 스택 외부로 향하게하는 것은 상대적으로 쉽습니다.

특히 스레드 환경에서는 스레드 스택이 매우 작고 서로 가깝습니다.

리눅스 머신에서 나는 이것을 테스트 할 수 있는데,이 테스트에서는 10MB 문자열이 다른 스레드 스택에 낙서를 시작하도록 요구합니다. MacOS에서 512kB로 충분할 것 같습니다.

당신이 얼마나 가까이에 있는지 알 수있는 빠른 해킹이 있습니다. (스택 할당이 OpenBSD와 같은 무작위 할당 자나 할당 자 안전성을 심각하게 취하는 다른 시스템을 사용하여 이루어 졌다는 사실을 알려주지는 않습니다.). 수익을 차감하기 전에 신속하게 정렬 이외의 검사를 더 정신이 없다 방법

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

주의 사항 :

#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 (들) + 1),들)로 컴파일됩니다 것입니다 스택 포인터에서 strlen의 값 (% rax).

+0

StackOverflow에 대한 귀하의 우려와 관련된 질문 : http://stackoverflow.com/questions/5543330/. 거기에 대한 답은 데스크탑 OS와 적절한 컴파일러의 경우 상황이 당신이 말하는 것처럼 황량하지 않다는 것을 알게했습니다. 컴파일러가 새로 할당 된 페이지를'alloca()'와 함께 순서대로 액세스하는 코드를 생성하지 않는 이유가 있습니까? –

+0

아, GCC의 경우 선택 사항입니다. '-fstack-check'을 사용해야합니다. –

+0

@PascalCuoq MacOS에서 gcc와 clang을 모두 체크했는데 Linux의 두 가지 다른 맛을 보았습니다. 모든 종류의 온 전성 검사는 생략했습니다. 검사를 가능하게하는 플래그가있을 수 있지만 컴파일러의 안전 기능은 기본적으로 활성화되어 있지 않으면 사용할 수 없습니다 (사용하기 어렵습니다). – Art

관련 문제