개요

Shadow stack이란, 리턴 주소값을 특수한 스택에 보관함으로서, Stack buffer overflow와 같은 공격으로부터 프로그램을 보호하는 기법이다. Shadow stack을 위해서 사용되는 스택은, 별도의 Shadow로 존재하는 스택이다. Function이 시작하는 시점에서, Function은 Return address를 Call stack과 Shadow stack에 동시에 저장하게 된다. Function이 끝나는 시점에서 함수는 Call stack과 Shadow stack의 Return address를 비교해서 일치하는 지를 확인한다. 만약 일치하지 않는다면 공격이 탐지된것으로 Program을 종료하게 된다. Shadow stack은 Control flow integrity를 지키기 위한 방법으로 사용된다.

Shadow stack의 구현은 Binary pathcing, Compiler support, 혹은 Hardware support와 같은 방식으로 구현할 수 있다. 콜스택과는 다르게 Shadow stack은 보통, return address만을 저장한다.

Stack canary와는 다르게 연속적이지 않은 Buffer overflow에도 Stack의 Corupption을 감지할 수 있다는 점에서 더 강력한 보호기법이다. 하지만 Shadow stack은 메모리의 내용을 직접바꿀 수 있는 환경에서는 Shadow stack의 내용도 바꿀 수 있기 떄문에 해결책이 되지 못한다.

2016년 Intel은 Shadow stack을 Hardware단에서 제공하는 Control-flow Enforcement Technology를 제공하였다. Shadow stack과 같은 경우 Exception이나 Longjmp와 같이 원래 호출된 곳이 아니라 다른 곳으로 Jump하는 경우에 잘못된 동작을 야기할 수도 있는데, 이러한 경우 Shadow stack을 순환하면서, Return address가 있는지 확인하는 것으로 해결가능하다.

Multithreading환경에서 Context switch시에 Shadow stack또한 Switching해주어야 한다.