KR20220095986A - 임베디드 프로세서의 소스 코드의 컴파일링 방법 및 컴파일러 - Google Patents

임베디드 프로세서의 소스 코드의 컴파일링 방법 및 컴파일러 Download PDF

Info

Publication number
KR20220095986A
KR20220095986A KR1020200188049A KR20200188049A KR20220095986A KR 20220095986 A KR20220095986 A KR 20220095986A KR 1020200188049 A KR1020200188049 A KR 1020200188049A KR 20200188049 A KR20200188049 A KR 20200188049A KR 20220095986 A KR20220095986 A KR 20220095986A
Authority
KR
South Korea
Prior art keywords
memory
instruction
additional
additional instruction
shadow
Prior art date
Application number
KR1020200188049A
Other languages
English (en)
Inventor
이진용
권동현
Original Assignee
한국전자통신연구원
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by 한국전자통신연구원 filed Critical 한국전자통신연구원
Priority to KR1020200188049A priority Critical patent/KR20220095986A/ko
Priority to US17/565,148 priority patent/US20220206767A1/en
Publication of KR20220095986A publication Critical patent/KR20220095986A/ko

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/52Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/07Responding to the occurrence of a fault, e.g. fault tolerance
    • G06F11/16Error detection or correction of the data by redundancy in hardware
    • G06F11/20Error detection or correction of the data by redundancy in hardware using active fault-masking, e.g. by switching out faulty elements or by switching in spare elements
    • G06F11/2017Error detection or correction of the data by redundancy in hardware using active fault-masking, e.g. by switching out faulty elements or by switching in spare elements where memory access, memory control or I/O control functionality is redundant
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F15/00Digital computers in general; Data processing equipment in general
    • G06F15/76Architectures of general purpose stored program computers
    • G06F15/78Architectures of general purpose stored program computers comprising a single central processing unit
    • G06F15/7839Architectures of general purpose stored program computers comprising a single central processing unit with memory
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/57Certifying or maintaining trusted computer platforms, e.g. secure boots or power-downs, version controls, system software checks, secure updates or assessing vulnerabilities
    • G06F21/577Assessing vulnerabilities and evaluating computer system security
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/30Creation or generation of source code
    • G06F8/37Compiler construction; Parser generation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/51Source to source
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2221/00Indexing scheme relating to security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F2221/03Indexing scheme relating to G06F21/50, monitoring users, programs or devices to maintain the integrity of platforms
    • G06F2221/033Test or assess software

Abstract

소스 코드에 포함된 메모리 명령어 중에서 임베디드 프로세서의 메모리 영역에 접근하는 타깃 메모리 명령어를 결정하는 단계, 타깃 메모리 명령어가 메모리 영역에 접근할 때 메모리 취약 에러를 검출하기 위한 추가 명령어를 타깃 메모리 명령어의 주변에 삽입하는 단계, 타깃 메모리 명령어를 바이너리 코드로 변환하는 단계, 그리고 추가 명령어를 바이너리 코드로 변환하는 단계를 통해 임베디드 프로세서의 프로그램의 소스 코드를 컴파일링하는 방법 및 컴파일러가 제공된다.

Description

임베디드 프로세서의 소스 코드의 컴파일링 방법 및 컴파일러{METHOD FOR COMPILING SOURCE CODE OF EMBEDED PROCESSOR AND COMPILER THEREOF}
본 기재는 임베디드 프로세서의 소스 코드를 컴파일링하는 방법 및 컴파일러에 관한 것이다.
메모리 취약점은 스택 오버플로(stack overflow), 힙 오버플로(heap overflow), 해제 후 사용(user after free) 등의 취약점을 말한다. 메모리 취약점은 공격자로 하여금 공격 타깃 시스템의 중요 정보를 저장하는 메모리에 접근하여 변조할 수 있도록 한다. 따라서 안전한 컴퓨팅 시스템을 구성하기 위해서, 메모리 취약점을 안전하고 효율적으로 검출할 수 있는 소프트웨어가 필요하다.
어드레스 새니타이저(address sanitizer)는 대표적인 메모리 취약점 검출 소프트웨어이다. 어드레스 새니타이저는 메모리가 사용되는 연산이 메모리 취약점으로서 악용되는지 여부를 판단함으로써 메모리 취약점을 검출할 수 있다.
한 실시예는, 임베디드 프로세서의 프로그램의 소스 코드를 컴파일링하는 방법을 제공한다.
다른 실시예는 임베디드 프로세서의 프로그램의 소스 코드를 컴파일링하는 컴파일러를 제공한다.
한 실시예에 따르면, 임베디드 프로세서의 프로그램의 소스 코드의 컴파일링 방법이 제공된다. 상기 컴파일링 방법은, 소스 코드에 포함된 메모리 명령어 중에서 임베디드 프로세서의 메모리 영역에 접근하는 타깃 메모리 명령어를 결정하는 단계, 타깃 메모리 명령어가 메모리 영역에 접근할 때 메모리 취약 에러를 검출하기 위한 추가 명령어를, 타깃 메모리 명령어의 주변에 삽입하는 단계, 타깃 메모리 명령어를 바이너리 코드로 변환하는 단계, 그리고 추가 명령어를 바이너리 코드로 변환하는 단계를 포함한다.
상기 컴파일링 방법에서 추가 명령어는 타깃 메모리 명령어의 데이터가 할당되는 스택의 이웃 스택에 더미 데이터를 할당하는 제1 추가 명령어를 포함할 수 있다.
상기 컴파일링 방법에서 추가 명령어는 더미 데이터에 대응하는 섀도 메모리 내의 비트를 기록하는 제2 추가 명령어를 더 포함할 수 있다.
상기 컴파일링 방법에서 추가 명령어는 제2 추가 명령어에 의해 기록된, 더미 데이터에 대응하는 섀도 메모리 내의 비트가 미리 결정된 값일 때 임베디드 프로세서의 사용자에게 알림을 표시하는 제3 추가 명령어를 더 포함할 수 있고, 알림은 메모리 영역에 대한 메모리 취약 에러가 발생한 것을 표시하는 시청각 경고를 포함할 수 있다.
상기 컴파일링 방법은 타깃 메모리 명령어의 바이너리 코드 및 추가 명령어의 바이너리 코드를 바탕으로 어드레스 새니타이저 기능이 적용된 프로그램을 생성하는 단계를 더 포함할 수 있다.
다른 실시예에 따르면, 임베디드 프로세서의 프로그램의 소스 코드를 컴파일하는 컴파일러가 제공된다. 상기 컴파일러는 프로세서 및 메모리를 포함하고, 프로세서는 메모리에 저장된 프로그램을 실행하여, 소스 코드에 포함된 메모리 명령어 중에서 메모리 영역에 접근하는 타깃 메모리 명령어를 결정하는 단계, 타깃 메모리 명령어가 메모리 영역에 접근할 때 메모리 취약점을 검출하기 위한 추가 명령어를, 타깃 메모리 명령어의 주변에 삽입하는 단계, 타깃 메모리 명령어를 바이너리 코드로 변환하는 단계, 그리고 추가 명령어를 바이너리 코드로 변환하는 단계를 수행한다.
상기 컴파일러에서 추가 명령어는 타깃 메모리 명령어의 데이터가 할당되는 스택의 이웃 스택에 더미 데이터를 할당하는 제1 추가 명령어를 포함할 수 있다.
상기 컴파일러에서 추가 명령어는 더미 데이터에 대응하는 섀도 메모리 내의 비트를 확인하는 제2 추가 명령어를 더 포함할 수 있다.
상기 컴파일러에서 추가 명령어는 제2 추가 명령어에 의해 기록된, 더미 데이터에 대응하는 섀도 메모리 내의 비트가 미리 결정된 값일 때 임베디드 프로세서의 사용자에게 알림을 표시하는 제3 추가 명령어를 더 포함할 수 있고, 알림은 메모리 영역에 대한 메모리 취약 에러가 발생한 것을 표시하는 시청각 경고를 포함할 수 있다.
상기 컴파일러에서 프로세서는 프로그램을 실행하여, 타깃 메모리 명령어의 바이너리 코드 및 추가 명령어의 바이너리 코드를 바탕으로 어드레스 새니타이저 기능이 적용된 프로그램을 생성하는 단계를 더 수행할 수 있다.
소스 코드에 삽입된 추가 명령어를 통해, 임베디드 프로세서의 메모리 또는 임베디드 프로세서와 연결된 메모리를 사용하는 프로그램에 메모리 취약점 탐지 기능이 탑재될 수 있다.
도 1은 한 실시예에 따른 컴파일러가 임베디드 프로세서의 프로그램의 소스 코드를 컴파일하는 컴파일링 방법을 나타낸 흐름도이다.
도 2는 한 실시예에 따른 임베디드 프로세서를 위한 메모리의 주소 공간을 나타낸 개념도이다.
도 3은 한 실시예에 따른 메모리 내에 할당된 섀도 메모리를 나타낸 개념도이다.
도 4는 한 실시예에 따른 섀도 메모리 영역의 구조를 나타낸 개념도이다.
도 5는 한 실시예에 따른 메인 메모리 영역의 스택 및 섀도 메모리를 나타낸 개념도이다.
도 6은 한 실시예에 따른 추가 명령어의 삽입 전 소스 코드 및 삽입 후 소스 코드를 나타낸 도면이다.
도 7은 한 실시예에 따른 추가 명령어에 의해 변경된 메인 메모리 영역의 스택을 나타낸 개념도이다.
도 8은 한 실시예에 따른 제2 추가 명령어가 삽입된 소스 코드를 나타낸 도면이다.
도 9는 한 실시예에 따른 제2 추가 명령어에 의해 결정된 섀도 메모리 영역 내의 섀도 메모리 워드를 나타낸 개념도이다.
도 10은 한 실시예에 따른 제3 추가 명령어가 삽입된 소스 코드를 나타낸 도면이다.
도 11은 한 실시예에 따른 다중 변이 실행을 위한 복수의 버전의 어드레스 새니타이저가 적용된 프로그램을 나타낸 개념도이다.
도 12는 한 실시예에 따른 컴파일러를 나타낸 블록도이다.
아래에서는 첨부한 도면을 참고로 하여 본 기재의 실시예에 대하여 본 발명이 속하는 기술 분야에서 통상의 지식을 가진 자가 용이하게 실시할 수 있도록 상세히 설명한다. 그러나 본 기재는 여러 가지 상이한 형태로 구현될 수 있으며 여기에서 설명하는 실시예에 한정되지 않는다. 그리고 도면에서 본 기재를 명확하게 설명하기 위해서 설명과 관계없는 부분은 생략하였으며, 명세서 전체를 통하여 유사한 부분에 대해서는 유사한 도면 부호를 붙였다.
명세서 전체에서, 어떤 부분이 어떤 구성요소를 "포함"한다고 할 때, 이는 특별히 반대되는 기재가 없는 한 다른 구성요소를 제외하는 것이 아니라 다른 구성요소를 더 포함할 수 있는 것을 의미한다.
본 명세서에서 단수로 기재된 표현은 "하나" 또는 "단일" 등의 명시적인 표현을 사용하지 않은 이상, 단수 또는 복수로 해석될 수 있다.
본 명세서에서 "및/또는"은 언급된 구성 요소들의 각각 및 하나 이상의 모든 조합을 포함한다.
본 명세서에서, 제1, 제2 등과 같이 서수를 포함하는 용어들은 다양한 구성요소들을 설명하는데 사용될 수 있지만, 상기 구성요소들은 상기 용어들에 의해 한정되지는 않는다. 상기 용어들은 하나의 구성요소를 다른 구성요소로부터 구별하는 목적으로만 사용된다. 예를 들어, 본 개시의 권리 범위를 벗어나지 않으면서 제1 구성요소는 제2 구성요소로 명명될 수 있고, 유사하게 제2 구성요소도 제1 구성요소로 명명될 수 있다.
본 명세서에서 도면을 참고하여 설명한 흐름도에서, 동작 순서는 변경될 수 있고, 여러 동작들이 병합되거나, 어느 동작이 분할될 수 있고, 특정 동작은 수행되지 않을 수 있다.
도 1은 한 실시예에 따른 컴파일러가 임베디드 프로세서의 프로그램의 소스 코드를 컴파일하는 컴파일링 방법을 나타낸 흐름도이다.
한 실시예에 따른 컴파일러는 임베디드 임베디드 프로세서의 프로그램의 소스 코드를 컴파일링할 때, 프로그램에 메모리 취약점 탐지 기능을 탑재시킬 수 있다. 예를 들어, 컴파일러는 소스 코드의 컴파일링시 메모리 취약점 탐지 기능으로서 프로그램에 어드레스 새니타이저 기능을 적용시킬 수 있다. 컴파일러는 타깃 메모리 명령어를 확인함으로써 타깃 메모리 명령어의 메인 메모리 영역에 대한 액세스가 적절한지 여부를 결정하기 위한 추가 명령어를 소스 코드 내에 삽입할 수 있다.
도 1을 참조하면, 한 실시예에 따른 컴파일러는 임베디드 프로세서의 프로그램의 소스 코드 내에 포함된 명령어 중에서 메인 메모리 영역에 접근하는 타깃 메모리 명령어를 확인할 수 있다(S110). 컴파일러는 코드 분석을 통해 소스 코드 내의 명령어가 어떤 메모리 영역에 접근하는지 확인할 수 있다. 본 기재에서, 메모리 영역에 액세스하는 명령어(아래에서 '메모리 명령어'라고 함) 중에서 메인 메모리 영역에 접근하는 메모리 명령어를 타깃 메모리 명령어라고 한다.
명령어에 의해 접근되는 메모리 영역을 구분하기 위해 컴파일러의 데이터 플로 분석(data flow analysis)이 수행될 수 있다. 일반적으로 메모리 명령어는, 하드웨어 추상화 계층(hardware abstraction layer, HAL)에 의해 제공된 상수 주소를 사용하여 주변 기기 영역에 접근할 수 있기 때문에, 타깃 메모리 명령어는 임베디드 프로세서에서 동작될 프로그램의 소스 코드 내에서 쉽게 구분될 수 있다.
어드레스 새니타이저는 C언어 또는 C++ 언어로 작성된 프로그램에서 발생할 수 있는 메모리 취약점을 검출하기 위한 컴파일러 기술이다. C언어 또는 C++ 언어로 작성한 소스 코드가 컴파일링될 때, 컴파일러는 어드레스 새니타이저 기능이 적용된 프로그램을 생성할 수 있다. 어드레스 새니타이저에 의해 검출될 수 있는 메모리 취약점은, 해제 후 사용(use after free), 힙 버퍼 오버플로(heap buffer overflow), 스택 버퍼 오버플로(stack buffer overflow), 글로벌 버퍼 오버플로(global buffer overflow), 반환 후 사용(use after return), 관찰 후 사용(use after scope), 초기화 순서 버그(initialization order bugs), 및 메모리 유출(memory leaks)을 포함할 수 있다.
어드레스 새니타이저가 적용된 프로그램의 실행 중에 메모리 취약점이 발생하면, 프로그램은 발생한 메모리 취약점의 검출을 알리는 메시지와 함께 종료될 수 있다. 어드레스 새니타이저는 사용되는 메모리 영역의 상태 정보를 담고 있는 섀도 메모리(shadow memory)를 사용하여 메모리 취약점을 검출할 수 있다. 예를 들어, 인텔(Intel) x64 비트 아키텍처에서 어드레스 새니타이저는 사용 중인 매 8바이트(byte)의 메모리마다 1바이트의 상태 정보를 담은 섀도 메모리를 사용한다. 섀도 메모리의 섀도 메모리 주소는 메모리의 메모리 주소를 바탕으로 아래 수학식 1과 같이 결정될 수 있다.
Figure pat00001
섀도 메모리는 메모리 할당, 할당된 메모리의 해제 등 메모리의 상태가 프로그램의 수행에 따라 변경되면 업데이트될 수 있다. 어드레스 새니타이저는 프로그램이 메모리 접근 명령어를 수행할 때 접근 대상 메모리 영역에 대응하는 섀도 메모리를 사용하여 접근 대상 메모리 영역에 대한 접근이 유효한지 여부를 판정할 수 있다. 예를 들어, 특정 메모리 영역이 메모리 해제로 전환되면, 특정 메모리 영역에 대응하는 섀도 메모리의 값은 메모리의 해제 상태를 나타내는 값으로 변경될 수 있다. 이후 해제된 특정 메모리 영역에 접근하는 메모리 접근 명령어가 실행되면, 어드레스 새니타이저는 특정 메모리 영역에 대응하는 섀도 메모리 내의 대응 영역의 값이 해제 상태라는 것을 바탕으로 Use-After-Free 취약점의 발생을 판정할 수 있다. 위와 같은 방식으로 메모리 취약점을 탐지할 수 있는 어드레스 새니타이저는, 소프트웨어의 검증 단계에서 메모리 취약점을 탐지하는 퍼저(fuzzer) 개발을 위해 사용될 수 있다.
도 2는 한 실시예에 따른 임베디드 프로세서를 위한 메모리의 주소 공간을 나타낸 개념도이다.
일반적으로 임베디드 프로세서는 메모리 관리 유닛(memory management unit, MMU)을 포함하고 있지 않으므로, 임베디드 프로세서는 가상 메모리를 지원하지 않는다. 임베디드 프로세서의 메모리(예를 들어, 임베디드 프로세서의 시스템 메모리 또는 임베디드 프로세서에 연결된 메모리)에서 연산을 위해 사용되는 메인 메모리 영역의 위치는 미리 결정되어 있다. 또한, 각종 주변 기기(peripheral device)의 주소 또한 전체 주소 공간 내에 미리 결정되어 있다.
도 2를 참조하면, 임베디드 프로세서의 메모리의 주소 공간 내에서 주요 데이터가 저장되는 SRAM(static random access memory)의 주소 영역과 주변 기기의 주소 영역은 각각 분리되어 위치한다. 일반적으로 임베디드 프로세서는 작은 크기의 SRAM을 사용하고, 적은 종류의 주변 기기와 연결되어 있기 때문에 SRAM의 많은 부분은 런타임 동안 사용되지 않을 수 있다.
도 3은 한 실시예에 따른 메모리 내에 할당된 섀도 메모리를 나타낸 개념도이고, 도 4는 한 실시예에 따른 섀도 메모리 영역의 구조를 나타낸 개념도이다.
도 3을 참조하면, 섀도 메모리 영역(10)은 임베디드 프로세서의 메모리의 메인 메모리 영역 내에 할당될 수 있다. 섀도 메모리 영역(10)은, 프로그램 내의 메모리 명령어가 액세스하는 메모리 영역의 상태를 체크하기 위해 사용될 수 있다.
도 4를 참조하면, 섀도 메모리 영역(10)은 메모리의 각 영역에 대응하는 부분을 포함할 수 있다. 섀도 메모리 영역(10)에 포함된 각 부분은 프로그램의 런타임 중에 임베디드 프로세서의 메모리 취약 에러의 발생을 탐지하기 위한 용도로 사용될 수 있다. 섀도 메모리 영역(10)은 메인 메모리 영역에 대응하는 부분을 포함할 수 있다.
도 3의 메모리에는 두 개의 주변 기기 영역(제1 주변 기기 영역 및 제2 주변 기기 영역)이 할당되어 있으므로(즉, 임베디드 프로세서에 두 개의 주변 기기가 연결되어 있음), 섀도 메모리 영역(10)은 각 주변 기기 영역에 대응하는 부분을 포함할 수 있다(제1 주변 기기 영역 상태 표시 및 제2 주변 기기 영역 상태 표시). 또한 섀도 메모리 영역(10)은 섀도 메모리 영역에 대응하는 부분을 포함할 수 있다. 도 4에서 섀도 메모리 영역에 대응하는 부분은 배드 영역(BAD region)이다. 배드 영역에는 배드 영역이 명령어에 의해 액세스되지 않도록 하기 위한 정보가 미리 저장될 수 있다.
한 실시예에 따른 임베디드 프로세서에서 메모리는 1워드(word) 단위로 액세스될 수 있고, 임베디드 프로세서에서 1워드는 4바이트이기 때문에 임베디드 프로세서의 메모리는 4바이트 단위로 액세스될 수 있다. 섀도 메모리는 액세스 단위로 할당될 수 있기 때문에, 임베디드 프로세서의 메모리의 1워드마다 1비트(bit)의 섀도 메모리가 할당될 수 있다. 예를 들어, 메인 메모리 영역 내의 0번째 워드에 대한 액세스는 섀도 메모리 영역 내의 0번째 비트에 저장된 상태 값을 확인함으로써 제어될 수 있다.
아래 수학식 2는 한 실시예에 따른 소스 코드의 일부이다.
Figure pat00002
수학식 2를 참조하면, 배열 길이 4인 정수형 변수 a를 위해 16바이트의 메모리가 메인 메모리 영역 내에 할당되고, 배열 길이 2인 정수형 변수 b를 위해 8바이트의 메모리가 메인 메모리 영역 내에 할당될 수 있다. 그리고 변수가 할당된 메인 메모리 영역에 대응하는 섀도 메모리는 각 워드(4바이트)당 1비트로 할당될 수 있다. 수학식 2의 변수 선언 명령어는 메인 메모리 영역에 액세스하기 때문에 컴파일러는 수학식 2의 변수 선언 명령어를 타깃 메모리 명령어로 결정할 수 있다.
한 실시예에 따른 컴파일러는 타깃 메모리 명령어에 추가 명령어를 삽입함으로써 임베디드 프로세서에 대한 메모리 취약 에러 탐지 기능을 구현할 수 있다. 아래에서는 도 5 내지 도 10을 참조하여 추가 명령어를 구체적으로 설명한다.
도 5는 한 실시예에 따른 메인 메모리 영역의 스택 및 섀도 메모리를 나타낸 개념도이고, 도 6은 한 실시예에 따른 추가 명령어의 삽입 전 소스 코드 및 삽입 후 소스 코드를 나타낸 도면이며, 도 7은 한 실시예에 따른 추가 명령어에 의해 변경된 메인 메모리 영역의 스택을 나타낸 개념도이다.
도 5를 참조하면, 소스 코드에서 선언된 변수 'a[4]' 및 'b[2]'의 데이터는 메인 메모리 영역 내의 스택에 저장될 수 있다. 호출 규칙(calling convention)에 따라 다를 수 있지만, 변수 a 및 변수 b에 대해, 메인 메모리 영역 내의 0x100 내지 0x114까지의 스택이 할당될 수 있다. 구체적으로, 변수 a[0]에 대해 0x100 내지 0x103까지의 스택이 할당되고, 변수 a[1]에 대해 0x104 내지 0x107까지의 스택이 할당되고, 변수 a[2]에 대해 0x108 내지 0x10b까지의 스택이 할당되고, 변수 a[3]에 대해 0x10c 내지 0x10f까지의 스택이 할당된다. 변수 b[0]에 대해 0x110 내지 0x113까지의 스택이 할당되고, 변수 b[1]에 대해 0x114 내지 0x117까지의 스택이 할당된다.
그리고 메인 메모리 영역 내의 각 스택은 섀도 메모리 영역(10) 내에 대응하는 비트를 가질 수 있다. 도 5를 참조하면, a[0]은 섀도 메모리 영역(10) 내의 0번째 비트에 대응하고, a[1]은 섀도 메모리 영역(10) 내의 1번째 비트에 대응하고, a[2]는 섀도 메모리 영역(10) 내의 2번째 비트에 대응하며, a[3]은 섀도 메모리 영역(10) 내의 3번째 비트에 대응할 수 있다. b[0]은 섀도 메모리 영역(10) 내의 4번째 비트에 대응하고, b[1]은 섀도 메모리 영역(10) 내의 5번째 비트에 대응할 수 있다.
다시 도 1를 참조하면, 한 실시예에 따른 컴파일러는 타깃 메모리 명령어의 데이터가 할당되는 스택의 이웃 스택에 더미 데이터를 할당하는 제1 추가 명령어를 삽입할 수 있다(S120). 도 6을 참조하면, 컴파일러는, 배열 길이 8의 정수 변수 a를 선언한 변수 선언 명령어 및 배열 길이 2의 정수 변수 b를 선언한 변수 선언 명령문의 데이터가 저장될 스택의 앞뒤에 더미 데이터를 할당하는 제1 추가 명령어를 소스 코드에 삽입할 수 있다. 즉, 컴파일러는 소스 코드 내에 "int dummy1;"을 삽입함으로써 스택 주소 0x100에 더미 데이터가 저장될 수 있도록 하고, 소스 코드 내에 "int dummy2;"를 삽입함으로써 스택 주소 0x12c에 더미 데이터가 저장될 수 있도록 할 수 있다.
도 7을 참조하면, 스택의 앞뒤에 더미 데이터가 4바이트 단위로 할당됨으로써, 변수 a의 스택 주소는 '0x100 내지 0x11f'에서 '0x104 내지 0x123으로 변경되고, 변수 b의 스택 주소는 '0x120 내지 0x127'에서 '0x124 내지 0x12b'로 변경될 수 있다.
한 실시예에 따른 컴파일러는 특정 함수에서 사용되는 적어도 하나의 변수에 할당된 스택의 이웃 스택에 더미 데이터가 저장되도록 함으로써, 특정 함수의 스택이 다른 함수에 의해 침범되지 않게 할 수 있다. 도 6의 for 문은 아웃오브바운드(out of bound) 에러를 설명하기 위한 예시이다.
도 8은 한 실시예에 따른 제2 추가 명령어가 삽입된 소스 코드를 나타낸 도면이며, 도 9는 한 실시예에 따른 제2 추가 명령어에 의해 결정된 섀도 메모리 영역 내의 섀도 메모리 워드를 나타낸 개념도이다.
도 1에서, 한 실시예에 따른 컴파일러는 더미 데이터에 대응하는 섀도 메모리에 비트를 기록하는 제2 추가 명령어를 소스 코드 내에 삽입할 수 있다(s130).
도 8을 참조하면, 더미 데이터 dummy1 및 dummy2에 대응하는 섀도 메모리 내에 비트를 기록하는 제2 명령어는 아래 수학식 3 및 수학식 4와 같이 소스 코드 내에 추가될 수 있다.
Figure pat00003
Figure pat00004
수학식 3 및 수학식 4의 첫 번째 줄(int *shadow_word1 = ~ 및 int *shadow_word2 = ~)은 shadow_word1 및 shadow_word2의 주소를 결정하는 명령어이다. 수학식 3 및 수학식 4의 두 번째 줄(*shadow_word1 = ~ 및 *shadow_word2 = ~)은 shadow_word1 및 shadow_word2의 비트를 1로 설정하는 명령어이다.
도 8의 소스 코드의 주석을 참조하면, 섀도 메모리_Offset이 0x1000일 때, dummy1에 대응하는 비트가 기록된 섀도 메모리의 워드 주소는 0x1002이다(dummy1의 주소가 0x100이고, 0x100>>7=0x2). 도 9를 참조하면, dummy1에 대응하는 비트는 주소 0x1002인 섀도 메모리 워드의 0번째 비트에 '1'이 기록되어 있다.
다시 도 8의 소스 코드의 주석을 참조하면, 섀도 메모리_Offset이 0x1000일 때, dummy1에 대응하는 비트가 기록된 섀도 메모리의 워드 주소는 0x1002이다(dummy1의 주소가 0x100이고, 0x12c>>7=0x2). 도 9를 참조하면, dummy2에 대응하는 비트는 주소 0x1002인 섀도 메모리 워드의 11번째 비트에 '1'이 기록되어 있다.
도 10은 한 실시예에 따른 제3 추가 명령어가 삽입된 소스 코드를 나타낸 도면이다.
도 1에서, 한 실시예에 따른 컴파일러는 더미 데이터에 대응하는 섀도 메모리 워드의 비트가 미리 결정된 값일 때 임베디드 프로세서의 사용자에게 알림을 표시하는 제3 추가 명령어를 소스 코드 내에 삽입할 수 있다(S140). 여기서 알림은 메모리 영역에 대한 메모리 취약 에러가 발생한 것을 사용자에게 표시하는 시청각 경고를 포함할 수 있다. 도 10을 참조하면, 섀도 메모리 워드에 기록된 비트 값이 1일 때 사용자에게 알림을 표시하기 위한,
"if ((*shadow_word&(1<<(((b_주소+i)>>2) %32))) == 1)
report_user("stack out of bound access");"
가 소스 코드 내에 제3 추가 명령어로서 추가되어 있다.
한 실시예에서, 사용자에게 알림을 표시하게 되는 섀도 메모리 워드의 비트 값은 1로 미리 결정된다. 즉, 섀도 메모리의 비트가 1일 때, 그 비트에 대응하는 메인 메모리 내의 데이터에 대한 액세스는 허용되지 않음이 미리 결정될 수 있다. 도 10를 참조하면, "b_주소"를 이용해 메모리 액세스가 수행되고, b_주소를 기준으로 총 5개의 메모리 워드에 대한 액세스가 수행될 수 있다. 변수 b에 할당된 메모리 워드의 크기는 2이기 때문에(b[2]), 5개 메모리 워드에 대한 액세스는 변수 b에 할당된 2 word의 크기를 초과하게 된다. 따라서, 이것은 원래 함수 a에 할당되어 있는 스택의 크기를 넘어서는 아웃오브바운드(out-of-bound) 액세스가 될 수 있다. 구체적으로 아웃오브바운드 액세스는, for문의 i가 0에서 5까지 되풀이(iteration)되지 않고, i가 0에서 사용자 입력(user_input)에 결정되는 수만큼 되풀이되는 경우일 수 있다. 이러한 아웃오브바운드 접근은 사용자의 입력에 의해 메모리 액세스의 바운드(bound)가 결정되므로, 보안상 매우 취약한 코드일 수 있다.
변수 b가 메모리 내의 데이터에 액세스를 수행할 때마다 컴파일러에 인해 제3 추가 명령어(도 10 참조)도 수행되고, 이에 따라 도 9의 섀도 메모리의 스택에 기록된, 현재의 액세스 주소에 대응하는 비트의 값이 체크될 수 있다. "B_주소"를 기준으로 2비트만큼은 제2 추가 명령어(도 8에서 추가된 코드)에 의해 1로 세팅되지 않았기 때문에 제3 추가 명령어(도 10에서 추가된 코드)는 "B_주소"를 기준으로 2비트만큼의 코드 수행을 적법 액세스인 것으로 판단할 수 있다. 하지만, "b_주소 + 2"의 코드가 수행되면, 이 코드가 액세스하는 영역은 dummy2의 위치에 해당된다. 따라서, 도 9에 도시된 섀도 메모리의 스택 의 비트는 제2 추가 명령어에 의해 1로 설정되고, 제3 추가 명령어에 의해 "b_주소 + 2"의 코드 수행은 아웃오브바운드 에러(out-of-bound error)인 것으로 판정될 수 있다.
일반적으로 아웃오브바운드 에러 또는 스택 오버플로의 경우, 잘못 작성된 소스 코드에 의해 접근 가능한 메모리 영역에서 시작된 액세스가 경계를 넘어 접근 불허된 메모리 영역으로 이어지는 것이 문제될 수 있다. 따라서 한 실시예에 따른 컴파일러는 메인 메모리 영역에 대한 액세스의 허용 여부를 탐지하기 위한 비트 값을 섀도 메모리 영역 내에 입력함으로써, 임베디드 프로세서의 메인 메모리 영역에 대한 액세스가 수행될 때마다 허용되지 않은 액세스가 탐지될 수 있게 할 수 있다.
한 실시예에 따른 컴파일러는 타깃 메모리 명령어 및 추가 명령어를 포함하는 소스 코드를 바이너리 코드로 변환함으로써 임베디드 프로세서에서 동작하는 프로그램을 생성할 수 있다(S150). 한 실시예에 따른 컴파일러는 위에서 설명된 제1 내지 제3 추가 명령어 중 적어도 하나의 추가 명령어를 소스 코드에 삽입함으로써, 임베디드 프로세서의 메모리 또는 임베디드 프로세서와 연결된 메모리를 사용하는 프로그램에 메모리 취약점 탐지 기능을 탑재시킬 수 있다.
도 11은 한 실시예에 따른 다중 변이 실행을 위한 복수의 버전의 어드레스 새니타이저가 적용된 프로그램을 나타낸 개념도이다.
일반적으로 임베디드 프로세서를 위한 섀도 메모리의 크기가 작기 때문에, 메모리 오버헤드가 클 수 있다. 예를 들어, Cortex-M 프로세서에서 4바이트마다 1바이트의 섀도 메모리가 사용되면, 메인 메모리 영역 및 주변 기기 영역을 포함하는 전체 주소 영역의 1/4이 섀도 메모리로서 사용되므로 메모리 오버헤드가 클 수 있다. 이 경우 어드레스 새니타이저 등 메모리 취약점 탐지 모듈이 임베디드 프로세서의 프로그램에 탑재되기 어려울 수 있다.
한 실시예에 따른 컴파일러는 임베디드 프로세서에서 동작될 각 프로그램마다 하나의 메모리 취약점을 탐지해내도록 할 수 있다. 도 11을 참조하면, 프로그램 #1은 스택 버퍼 오버플로 취약점(stack buffer overflow vuln.)을 검출할 수 있고, 전체 주소 영역의 4바이트마다 1비트의 섀도 메모리를 사용할 수 있다. 프로그램 #2는 힙 버퍼 오버플로 취약점(heap buffer overflow vuln.)을 검출할 수 있고, 전체 주소 영역의 4바이트마다 1비트의 섀도 메모리를 사용할 수 있다. 또한 프로그램 #n은 유즈 애프터 프리 취약점(use after free vuln.)을 검출할 수 있고, 전체 주소 영역의 4바이트마다 1비트의 섀도 메모리를 사용할 수 있다. 즉, 4바이트당 1바이트로 결정된 섀도 메모리를 사용할 때 최대 8개의 메모리 취약점을 검출할 수 있지만, 한 실시예에 따른 컴파일러는 임베디드 프로세서의 협소한 메모리 공간을 고려하여 섀도 메모리의 크기를 4바이트 당 1 내지 4비트 정도로 제한할 수 있다. 즉, 각 프로그램의 런타임 동안 섀도 메모리를 통해 적은 메모리 오버헤드로 1개 내지 4개의 메모리 취약점이 탐지될 수 있다.
도 12는 한 실시예에 따른 컴파일러를 나타낸 블록도이다.
한 실시예에 따른 컴파일러는, 컴퓨터 시스템, 예를 들어 컴퓨터 판독 가능 매체로 구현될 수 있다. 도 12를 참조하면, 컴퓨터 시스템(1200)은, 버스(1270)를 통해 통신하는 프로세서(1210), 메모리(1230), 입력 인터페이스 장치(1250), 출력 인터페이스 장치(1260), 및 저장 장치(1240) 중 적어도 하나를 포함할 수 있다. 컴퓨터 시스템(1200)은 또한 네트워크에 결합된 통신 장치(1220)를 포함할 수 있다. 프로세서(1210)는 중앙 처리 장치(central processing unit, CPU)이거나, 또는 메모리(1230) 또는 저장 장치(1240)에 저장된 명령 및/또는 프로그램을 실행하는 반도체 장치일 수 있다. 메모리(1230) 및 저장 장치(1240)는 다양한 형태의 휘발성 또는 비휘발성 저장 매체를 포함할 수 있다. 예를 들어, 메모리는 ROM(read only memory) 및 RAM(random access memory)를 포함할 수 있다. 본 기재의 실시예에서 메모리는 프로세서의 내부 또는 외부에 위치할 수 있고, 메모리는 이미 알려진 다양한 수단을 통해 프로세서와 연결될 수 있다. 메모리는 다양한 형태의 휘발성 또는 비휘발성 저장 매체이며, 예를 들어, 메모리는 읽기 전용 메모리(read-only memory, ROM) 또는 랜덤 액세스 메모리(random access memory, RAM)를 포함할 수 있다.
따라서, 실시예는 컴퓨터에 구현된 방법으로서 구현되거나, 컴퓨터 실행 가능 명령이 저장된 비일시적 컴퓨터 판독 가능 매체로서 구현될 수 있다. 한 실시예에서, 프로세서에 의해 실행될 때, 컴퓨터 판독 가능 명령은 본 기재의 적어도 하나의 양상에 따른 방법을 수행할 수 있다.
통신 장치(1220)는 유선 신호 또는 무선 신호를 송신 또는 수신할 수 있다.
한편, 실시예는 지금까지 설명한 장치 및/또는 방법을 통해서만 구현되는 것은 아니며, 실시예의 구성에 대응하는 기능을 실현하는 프로그램 또는 그 프로그램이 기록된 기록 매체를 통해 구현될 수도 있으며, 이러한 구현은 상술한 실시예의 기재로부터 본 발명이 속하는 기술 분야의 통상의 기술자라면 쉽게 구현할 수 있는 것이다. 구체적으로, 실시예에 따른 방법(예, 네트워크 관리 방법, 데이터 전송 방법, 전송 스케줄 생성 방법 등)은 다양한 컴퓨터 수단을 통해 수행될 수 있는 프로그램 명령 형태로 구현되어, 컴퓨터 판독 가능 매체에 기록될 수 있다. 컴퓨터 판독 가능 매체는 프로그램 명령, 데이터 파일, 데이터 구조 등을 단독으로 또는 조합하여 포함할 수 있다. 컴퓨터 판독 가능 매체에 기록되는 프로그램 명령은, 실시예를 위해 특별히 설계되어 구성된 것이거나, 컴퓨터 소프트웨어 분야의 통상의 기술자에게 공지되어 사용 가능한 것일 수도 있다. 컴퓨터 판독 가능 기록 매체는 프로그램 명령을 저장하고 수행하도록 구성된 하드웨어 장치를 포함할 수 있다. 예를 들어, 컴퓨터 판독 가능 기록 매체는 하드 디스크, 플로피 디스크 및 자기 테이프와 같은 자기 매체(magnetic media), CD-ROM, DVD와 같은 광 기록 매체(optical media), 플롭티컬 디스크(floptical disk)와 같은 자기-광 매체(magneto-optical media), 롬(ROM), 램(RAM), 플래시 메모리 등일 수 있다. 프로그램 명령은 컴파일러에 의해 만들어지는 것과 같은 기계어 코드뿐만 아니라, 인터프리터 등을 통해 컴퓨터에 의해 실행될 수 있는 고급 언어 코드를 포함할 수 있다.
이상에서 실시예에 대하여 상세하게 설명하였지만 권리범위는 이에 한정되는 것은 아니고 다음의 청구범위에서 정의하고 있는 기본 개념을 이용한 당업자의 여러 변형 및 개량 형태 또한 권리범위에 속하는 것이다.

Claims (10)

  1. 임베디드 프로세서의 프로그램의 소스 코드의 컴파일링 방법으로서,
    상기 소스 코드에 포함된 메모리 명령어 중에서 상기 임베디드 프로세서의 메모리 영역에 접근하는 타깃 메모리 명령어를 결정하는 단계,
    상기 타깃 메모리 명령어가 상기 메모리 영역에 접근할 때 메모리 취약 에러를 검출하기 위한 추가 명령어를, 상기 타깃 메모리 명령어의 주변에 삽입하는 단계,
    상기 타깃 메모리 명령어를 바이너리 코드로 변환하는 단계, 그리고
    상기 추가 명령어를 바이너리 코드로 변환하는 단계
    를 포함하는 컴파일링 방법.
  2. 제1항에서,
    상기 추가 명령어는 상기 타깃 메모리 명령어의 데이터가 할당되는 스택의 이웃 스택에 더미 데이터를 할당하는 제1 추가 명령어를 포함하는, 컴파일링 방법.
  3. 제2항에서,
    상기 추가 명령어는 상기 더미 데이터에 대응하는 섀도 메모리 내의 비트를 기록하는 제2 추가 명령어를 더 포함하는, 컴파일링 방법.
  4. 제3항에서,
    상기 추가 명령어는 상기 제2 추가 명령어에 의해 기록된, 상기 더미 데이터에 대응하는 섀도 메모리 내의 비트가 미리 결정된 값일 때 상기 임베디드 프로세서의 사용자에게 알림을 표시하는 제3 추가 명령어를 더 포함하고, 상기 알림은 상기 메모리 영역에 대한 메모리 취약 에러가 발생한 것을 표시하는 시청각 경고를 포함하는, 컴파일링 방법.
  5. 제1항에서,
    상기 타깃 메모리 명령어의 바이너리 코드 및 상기 추가 명령어의 바이너리 코드를 바탕으로 어드레스 새니타이저 기능이 적용된 프로그램을 생성하는 단계
    를 더 포함하는 컴파일링 방법.
  6. 임베디드 프로세서의 프로그램의 소스 코드를 컴파일하는 컴파일러로서,
    프로세서 및 메모리를 포함하고, 상기 프로세서는 상기 메모리에 저장된 프로그램을 실행하여,
    상기 소스 코드에 포함된 메모리 명령어 중에서 메모리 영역에 접근하는 타깃 메모리 명령어를 결정하는 단계,
    상기 타깃 메모리 명령어가 상기 메모리 영역에 접근할 때 메모리 취약점을 검출하기 위한 추가 명령어를, 상기 타깃 메모리 명령어의 주변에 삽입하는 단계,
    상기 타깃 메모리 명령어를 바이너리 코드로 변환하는 단계, 그리고
    상기 추가 명령어를 바이너리 코드로 변환하는 단계
    를 수행하는, 컴파일러.
  7. 제6항에서,
    상기 추가 명령어는 상기 타깃 메모리 명령어의 데이터가 할당되는 스택의 이웃 스택에 더미 데이터를 할당하는 제1 추가 명령어를 포함하는, 컴파일러.
  8. 제7항에서,
    상기 추가 명령어는 상기 더미 데이터에 대응하는 섀도 메모리 내의 비트를 확인하는 제2 추가 명령어를 더 포함하는, 컴파일러.
  9. 제8항에서,
    상기 추가 명령어는 상기 제2 추가 명령어에 의해 기록된, 상기 더미 데이터에 대응하는 섀도 메모리 내의 비트가 미리 결정된 값일 때 상기 임베디드 프로세서의 사용자에게 알림을 표시하는 제3 추가 명령어를 더 포함하고, 상기 알림은 상기 메모리 영역에 대한 메모리 취약 에러가 발생한 것을 표시하는 시청각 경고를 포함하는, 컴파일러.
  10. 제6항에서,
    상기 프로세서는 상기 프로그램을 실행하여,
    상기 타깃 메모리 명령어의 바이너리 코드 및 상기 추가 명령어의 바이너리 코드를 바탕으로 어드레스 새니타이저 기능이 적용된 프로그램을 생성하는 단계
    를 더 수행하는 컴파일러.
KR1020200188049A 2020-12-30 2020-12-30 임베디드 프로세서의 소스 코드의 컴파일링 방법 및 컴파일러 KR20220095986A (ko)

Priority Applications (2)

Application Number Priority Date Filing Date Title
KR1020200188049A KR20220095986A (ko) 2020-12-30 2020-12-30 임베디드 프로세서의 소스 코드의 컴파일링 방법 및 컴파일러
US17/565,148 US20220206767A1 (en) 2020-12-30 2021-12-29 Method for compiling source code of embedded processor and compiler thereof

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
KR1020200188049A KR20220095986A (ko) 2020-12-30 2020-12-30 임베디드 프로세서의 소스 코드의 컴파일링 방법 및 컴파일러

Publications (1)

Publication Number Publication Date
KR20220095986A true KR20220095986A (ko) 2022-07-07

Family

ID=82119046

Family Applications (1)

Application Number Title Priority Date Filing Date
KR1020200188049A KR20220095986A (ko) 2020-12-30 2020-12-30 임베디드 프로세서의 소스 코드의 컴파일링 방법 및 컴파일러

Country Status (2)

Country Link
US (1) US20220206767A1 (ko)
KR (1) KR20220095986A (ko)

Families Citing this family (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN116305173B (zh) * 2023-05-24 2023-07-28 中国人民解放军国防科技大学 一种整数漏洞查找方法、装置、计算机设备和存储介质

Family Cites Families (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP3552627B2 (ja) * 2000-02-04 2004-08-11 インターナショナル・ビジネス・マシーンズ・コーポレーション スタック保護システム、コンピュータシステム、コンパイラ、スタック保護方法および記憶媒体
US9183114B2 (en) * 2005-12-27 2015-11-10 International Business Machines Corporation Error detection on the stack
US11188470B2 (en) * 2019-05-22 2021-11-30 Vdoo Connected Trust Ltd. Dynamic identification of stack frames

Also Published As

Publication number Publication date
US20220206767A1 (en) 2022-06-30

Similar Documents

Publication Publication Date Title
US9390261B2 (en) Securing software by enforcing data flow integrity
US10990667B2 (en) Systems and/or methods for automatically protecting against memory corruption vulnerabilities
US9996696B2 (en) Systems and methods to optimize execution of a software program using a type based self assembling control flow graph
US8434064B2 (en) Detecting memory errors using write integrity testing
Akritidis et al. Preventing memory error exploits with WIT
US8762797B2 (en) Method and apparatus for detecting memory access faults
CN107771335B (zh) 受保护区域
JP2008276763A (ja) メモリエラーの検出法
US11210402B2 (en) Gate-level information flow security
US6697971B1 (en) System and method for detecting attempts to access data residing outside of allocated memory
US11868465B2 (en) Binary image stack cookie protection
KR20220095986A (ko) 임베디드 프로세서의 소스 코드의 컴파일링 방법 및 컴파일러
KR102254159B1 (ko) 운영체제 커널 메모리의 실시간 오류 검출 방법
US20220308991A1 (en) Test processing method and information processing apparatus
US11055202B1 (en) Compilation scheme for tagged global variables
KR101842263B1 (ko) 어플리케이션에 대한 역공학 차단 방법 및 장치
Arora et al. Architectural support for run-time validation of program data properties
Liljestrand et al. Color My World: Deterministic Tagging for Memory Safety
CN111881485A (zh) 一种基于arm指针验证的内核敏感数据完整性保护方法
CN114981811A (zh) 用于软件安全的装置和方法
Maebe et al. Mitigating smart card fault injection with link-time code rewriting: a feasibility study
KR100580071B1 (ko) 메모리 오류 검출방법
US20190042116A1 (en) Techniques for preventing memory corruption
Saeed et al. Tag-protector: an effective and dynamic detection of illegal memory accesses through compile time code instrumentation
Krebbers et al. Subtleties of the ANSI/ISO C standard

Legal Events

Date Code Title Description
E902 Notification of reason for refusal