답변:
소프트웨어, 하드웨어 또는 둘 다 또는 없음 일 수 있습니다.
두 가지 종류의 오버플로가 있습니다. 스택을 확장 할 때 오버플로 (함수를 입력 할 때)와 스택의 배열에 액세스 할 때 오버플로가 있습니다. 스택을 확장 할 때 오버플로는 함수 입력에 대한 경계 검사를 수행하여 충분한 공간이 있는지 확인하고 오류가 있거나 스택이없는 경우 스택을 늘리면 감지 할 수 있습니다. 스택의 배열에 액세스 할 때 오버플로는 배열 범위를 확인하지 않는 저수준 언어에서만 문제가됩니다. 해결책은 배열 범위를 확인하는 것입니다.
이러한 소프트웨어 접근 방식은 완전히 안정적으로 작동한다는 이점이 있습니다. 스택 오버플로가 감지 될 수 있습니다. 단점은 코드 크기와 실행 시간이 늘어난다는 것입니다. 하드웨어는 오버플로가 발생하지 않는 한 대부분의 오버플로를 무료로 감지하는 방법을 제공함으로써 도움을 줄 수 있습니다. MMU ¹가 있는 아키텍처 에서 런타임 환경은 스택을 페이지 경계에 매핑하고 다음 페이지는 매핑되지 않은 상태로 유지할 수 있습니다.
+---------------+---------------+---------------+---------------+
| stack | unmapped | other stuff |
| ----> direction of growth | | |
+---------------+---------------+---------------+---------------+
^ ^ ^ ^ ^ page boundaries
이렇게하면 소프트웨어가 페이지 경계를 넘어서 데이터에 액세스하려고하면 (스택 포인터가 경계를 넘어 이동했거나 어레이 액세스가 경계를 벗어 났거나 경계를 벗어난 경우) 매핑되지 않은 영역에 액세스하여 오류가 발생합니다. . 이는 오버플로가 충분히 작은 경우에만 발생합니다. 오버플로의 양이 너무 크면 프로그램이 주소 공간의 갭 반대편에있는 다른 항목에 액세스 할 수 있습니다.
하드웨어 접근 방식의 단점은 대량의 오버플로가 감지되지 않을 수 있고 주소 지정 가능한 공간 내에 남아있는 어레이 오버플로를 감지하지 못하기 때문에 완전히 신뢰할 수 없다는 것입니다.
배열 오버플로를 감지하기 위해 다른 소프트웨어 기술은 카나리아 입니다. 스택의 상단 또는 프레임 사이에 특수 값을 넣고 카나리아 값이 함수 반환에서 변경되지 않았는지 확인하십시오. 오버 플로우가 카나리아를 완전히 피하거나 카나리아 값이 점검 될 때 카나리아 값이 복원 되었기 때문에 감지되지 않을 수 있기 때문에 이것은 또한 불완전한 기술입니다. 그럼에도 불구하고 일부 보안 취약성을 악용하기 어렵게 만드는 것이 유용합니다.
스택 오버플로를 피하는 가장 안전하고 저렴한 방법은 정적 분석을 통해 프로그램을 실행하기 전에 스택에 필요한 스택의 양을 계산하는 것입니다. 그러나 이것이 항상 실용적이지는 않습니다. 프로그램이 필요로하는 스택의 양은 일반적으로 결정 불가능하며 프로그램이 조작하는 데이터에 따라 다릅니다.
¹ 기존 물리적 매핑의 가장자리에 스택이있는 단일 스레드가있는 경우 MPU 만 또는 메모리 보호없이 동일한 원칙을 적용 할 수도 있습니다.