2016-06-27 6 views
-1

:없음 SEG_FAULT 없습니다 내가 다음과 같이 정수 오버 플로우 버그 및 작은 코드를 작성하여 그 결과를 증명하기 위해 노력하고있어

int main(int argc, char** argv) 
{ 
    size_t len = 0; 
    sscanf (argv[1], "%lu", &len); 
    char* buffer = malloc(len + 5); 
    strcpy (buffer, argv[2]); 
    printf("str = \'%s\'\n", buffer) 
    return 0; 
} 

이 프로그램에 대한 안전 입력이됩니다 같은 :

./program 16 "This is a string" 

안전하지 않은 입력이 정수 오버 플로우 데모 위치를 다음과 같이이다 :

./program 18446744073709551613 "`perl -e 'print "This is a very very large string "x20'`" 

그러나 놀랍게도 정수 오버플로가 발생하고 아주 작은 버퍼가 할당 되어도 프로그램은 분할 오류를 생성하지 않으며 프로그램은 문제없이 정상적으로 실행됩니다!

이유가 무엇인지 설명 할 수 있습니까?

나는 이것을 GCC-5.2.1로 컴파일하고 64 비트 우분투 시스템에서 실행합니다.

코드의 더 완전한 버전은 viewed here 일 수 있습니다.

+2

정의되지 않은 동작은 정의되지 않았습니다. 특히 "붕괴"를 포함하여 무엇이든 할 필요는 없습니다. – EOF

+0

이 질문을 "http://stackoverflow.com/questions/31450678"의 중복으로 표시하는 것은 ** 우습다 **! 이 질문은 왜 우리가'malloc'이 필요한지를 묻지 않고 있습니다. * 큰 문자열을 힙의 작은 버퍼에 복사하면 SEG_FAULT *가 발생하지 않습니다. –

+0

@SeyedMohammad 그것이 최고의 복제본이 아니라고 동의했지만 문제는 동일합니다. 할당 된 메모리 외부에 쓸 때, 어떤 일이 일어날 수 있습니다. 당신에게 seg 결함을 줄 필요가 없습니다. 고속도로에서 조깅을하면 차로 치는 것이 보장되지 않는 것과 같습니다. 비록 당신이 차에 치일 가능성이 있지만, 당신은 그것을 긁지 않을 수도 있습니다. 이 시간. – Lundin

답변

2

여기 보이는 것은 정의되지 않은 동작입니다. 하지만 실제로는 무작위로 작동 할 수도 있지만 실제로는 다른 버퍼를 할당하고 나중에 둘 다 해제하는 등의 복잡한 시나리오에서는 실패 할 수 있습니다.

특히 C 라이브러리는 더 큰 메모리 덩어리를 할당하고 필요에 따라 분할합니다. 즉, 버퍼 뒤의 메모리가 여전히 존재하고 OS 관점에서 볼 때 유효합니다. 그러나 거기에 쓰기는 조만간 또 다른 버퍼 또는 링크를 손상시키고 오류 또는 예기치 않은 내용을 초래합니다.

+0

감사합니다. 실제 문제는 "스택 기반 오버플로"와 비슷한 즉각적인 피드백을 기대하고있었습니다. 이와 같이 작고 간단한 프로그램에서 "힙 기반 오버플로"는 충돌을 일으키지 않을 수도 있습니다 ... 왜? ... 힙에는 많은 공간이 있고 다른 할당 및 해제가 수행되지 않으면 프로그램 제어 흐름 (스택과 반대)에 영향을 미치지 않기 때문에. –