이 매크로는 안전합니까? 아니면 alloca가 NULL을 반환하지 않도록해야합니까?문자열을 복사 할 때이 매크로가 안전합니까?
#define DO_COPY(x) strcpy(alloca(strlen((x)) + 1), x)
이 매크로는 안전합니까? 아니면 alloca가 NULL을 반환하지 않도록해야합니까?문자열을 복사 할 때이 매크로가 안전합니까?
#define DO_COPY(x) strcpy(alloca(strlen((x)) + 1), x)
문자열이 사용자가 제어하는 경우 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).
StackOverflow에 대한 귀하의 우려와 관련된 질문 : http://stackoverflow.com/questions/5543330/. 거기에 대한 답은 데스크탑 OS와 적절한 컴파일러의 경우 상황이 당신이 말하는 것처럼 황량하지 않다는 것을 알게했습니다. 컴파일러가 새로 할당 된 페이지를'alloca()'와 함께 순서대로 액세스하는 코드를 생성하지 않는 이유가 있습니까? –
아, GCC의 경우 선택 사항입니다. '-fstack-check'을 사용해야합니다. –
@PascalCuoq MacOS에서 gcc와 clang을 모두 체크했는데 Linux의 두 가지 다른 맛을 보았습니다. 모든 종류의 온 전성 검사는 생략했습니다. 검사를 가능하게하는 플래그가있을 수 있지만 컴파일러의 안전 기능은 기본적으로 활성화되어 있지 않으면 사용할 수 없습니다 (사용하기 어렵습니다). – Art
alloca()? 그것이 malloc이라면 나는 그렇다고 말할 것입니다. – SparKot
http://stackoverflow.com/questions/1018853/why-is-alloca-not-considered-good-practice- 만약 당신이 alloca를 사용한다면 당신은 당신이하고있는 일에 대해 꽤 확신 할 필요가 있습니다 ... – John3136
전적으로 달려 있습니다. 당신이 그것을 사용하는 맥락에서. –