메모리 안전성
Memory safety메모리 안전이란 버퍼 오버플로나 행잉 [1]포인터 등 메모리액세스에 대처할 때 다양한 소프트웨어 버그나 보안 취약점으로부터 보호되는 상태를 말합니다.예를 들어 Java는 런타임 오류 검출이 배열 경계와 포인터 참조를 [1]검사하기 때문에 메모리 안전하다고 합니다.이와는 대조적으로 C와 C++는 직접 메모리 주소로 구현된 포인터를 사용하여 임의의 포인터 연산을 허용하며,[2] 따라서 잠재적으로 [3]메모리 안전하지 않습니다.
역사
메모리 오류는 포크 [4]폭탄과 같은 문제를 피하기 위해 자원 관리 및 시분할 시스템의 맥락에서 처음 고려되었습니다.개발은 모리스 웜이 핑거드의 [5]버퍼 오버플로를 이용하기 전까지는 대부분 이론적이었다.그 후 컴퓨터 보안 분야는 급속하게 발전하여 Return-to-libc 공격과 같은 수많은 새로운 공격과 실행 불가능한[6] 스택 및 주소 공간 레이아웃 랜덤화 같은 방어 기술로 확대되었습니다.랜덤화는 대부분의 버퍼 오버플로 공격을 방지하고 공격자가 힙 스프레이 또는 기타 응용 프로그램에 의존하는 방법을 사용하여 주소를 얻어야 하지만 채택 속도는 느립니다.[5]단, 이 테크놀로지의 도입은 일반적으로 랜덤화 라이브러리와 스택의 위치에 한정됩니다.
접근
DieHard,[7] 재설계된 DieHarder [8]및 Alinea Distributed Debugging Tool은 자체 랜덤 가상 메모리 페이지에서 개체를 할당하는 특수한 힙 할당기이며, 잘못된 읽기 및 쓰기를 원인이 되는 정확한 명령으로 중지 및 디버깅할 수 있습니다.보호는 하드웨어 메모리 보호에 의존하기 때문에 일반적으로 오버헤드는 크지 않지만 프로그램이 할당을 [9]많이 사용하는 경우 오버헤드가 크게 증가할 수 있습니다.랜덤화는 메모리 오류에 대한 확률적 보호만 제공하지만 바이너리를 재링크함으로써 기존 소프트웨어에서 쉽게 구현할 수 있는 경우가 많습니다.
Valgrind의 memcheck 도구는 명령 집합 시뮬레이터를 사용하여 메모리 검사 가상 시스템에서 컴파일된 프로그램을 실행하여 런타임 메모리 오류의 하위 집합을 확실하게 탐지합니다.단, 일반적으로 프로그램 속도가 40배 [10]느려지고 커스텀메모리 [11][12]할당에 대해 명시적으로 통지해야 합니다.
소스 코드에 대한 액세스로 포인터("메타데이터")의 정당한 값을 수집 및 추적하고 각 포인터 액세스를 메타데이터와 비교하여 검증하는 라이브러리가 존재합니다(예: Boehm 가비지 [13]콜렉터).일반적으로 가비지 컬렉션 추적과 모든 메모리 액세스에 런타임 체크를 삽입하여 메모리 안전을 안전하게 보장할 수 있습니다.이 접근방식은 오버헤드가 있지만 Valgrind보다 낮습니다.가비지 수집 언어는 모두 이 [1]방법을 사용합니다.C 및 C++의 경우 실행 시 메모리의 안전성을 체크하기 위해 코드의 컴파일 타임 변환을 실행하는 툴이 많이 있습니다.예를 들어 Check[14] Pointer 및 Address Sanitizer는 평균 속도 저하 계수를 [15]2로 합니다.
또 다른 접근법은 정적 프로그램 분석과 자동 정리 증명을 사용하여 프로그램에 메모리 오류가 없음을 보증합니다.예를 들어 Rust 프로그래밍 언어는 메모리 [16]안전을 보장하기 위해 차용 체커를 구현합니다.Coverity 등의 도구는 [17]C의 정적 메모리 분석을 제공합니다.C++의 스마트 포인터는 이 접근법의 제한된 형식입니다.
메모리 오류 유형
다음과 같은 다양한 유형의 메모리 오류가 [18][19]발생할 수 있습니다.
- 액세스 오류: 포인터의 읽기/쓰기가 잘못되었습니다.
- 버퍼 오버플로 - 경계 밖의 쓰기는 인접 개체의 내용이나 내부 데이터(히프의 부기 정보 등) 또는 반환 주소의 내용을 손상시킬 수 있습니다.
- 버퍼 오버 읽기 - 경계 밖의 읽기를 통해 중요한 데이터가 노출되거나 공격자가 주소 공간 레이아웃 랜덤화를 무시할 수 있습니다.
- 경쟁 조건 - 공유 메모리에 대한 동시 읽기/쓰기
- 잘못된 페이지 장애 - 가상 메모리 공간 외부에 있는 포인터에 액세스합니다.늘 포인터 디레퍼런스는 대부분의 환경에서 예외 또는 프로그램 종료를 발생시키지만 메모리 보호 기능이 없는 운영 체제 커널 또는 시스템이 손상되거나 늘 포인터의 사용이 큰 오프셋 또는 음의 오프셋을 포함할 경우 발생할 수 있습니다.
- 자유 참조 후 사용 - 삭제된 객체의 주소를 저장하는 매달림 포인터.
- 초기화되지 않은 변수 - 값이 할당되지 않은 변수가 사용됩니다.바람직하지 않은 값 또는 일부 언어에서는 손상된 값을 포함할 수 있습니다.
- 메모리 누전 - 메모리 사용량이 추적되지 않거나 잘못 추적된 경우
- 스택 소진 - 프로그램의 스택 공간이 부족할 때 발생합니다. 일반적으로 재귀가 너무 깊어집니다.일반적으로 가드 페이지는 프로그램을 중지시켜 메모리 손상을 방지하지만 스택 프레임이 큰 함수는 페이지를 무시할 수 있습니다.
- 힙 소진 - 프로그램은 사용 가능한 메모리 양보다 더 많은 메모리를 할당하려고 합니다.일부 언어에서는 할당 후 이 조건을 수동으로 확인해야 합니다.
- Double Free - free 호출을 반복하면 동일한 주소에서 새 개체가 너무 빨리 해방될 수 있습니다.정확한 주소를 재사용하지 않으면 특히 빈 목록을 사용하는 할당자에서 다른 손상이 발생할 수 있습니다.
- Invalid free - 비활성 주소를 전달하면 힙이 손상될 수 있습니다.
- 사용 가능한 불일치 - 여러 할당자가 사용 중일 때 다른 할당자의[20] 할당 해제 함수로 메모리를 해방하려고 시도합니다.
- 원치 않는 에일리어스 - 관련 없는 목적으로 동일한 메모리 위치를 두 번 할당하고 수정하는 경우.
레퍼런스
- ^ a b c Dhurjati, Dinakar; Kowshik, Sumant; Adve, Vikram; Lattner, Chris (1 January 2003). "Memory Safety Without Runtime Checks or Garbage Collection" (PDF). Proceedings of the 2003 ACM SIGPLAN Conference on Language, Compiler, and Tool for Embedded Systems. ACM: 69–80. doi:10.1145/780732.780743. ISBN 1581136471. S2CID 1459540. Retrieved 13 March 2017.
- ^ Koenig, Andrew. "How C Makes It Hard To Check Array Bounds". Dr. Dobb's. Retrieved 13 March 2017.
- ^ Akritidis, Periklis (June 2011). "Practical memory safety for C" (PDF). Technical Report - University of Cambridge. Computer Laboratory. University of Cambridge, Computer Laboratory. ISSN 1476-2986. UCAM-CL-TR-798. Retrieved 13 March 2017.
- ^ Anderson, James P. "Computer Security Planning Study" (PDF). 2. Electronic Systems Center. ESD-TR-73-51.
{{cite journal}}
:Cite 저널 요구 사항journal=
(도움말) - ^ a b van der Veen, Victor; dutt-Sharma, Nitish; Cavallaro, Lorenzo; Bos, Herbert (2012). "Memory Errors: The Past, the Present, and the Future" (PDF). Lecture Notes in Computer Science. 7462 (RAID 2012): 86–106. doi:10.1007/978-3-642-33338-5_5. ISBN 978-3-642-33337-8. Retrieved 13 March 2017.
- ^ Wojtczuk, Rafal. "Defeating Solar Designer's Non-executable Stack Patch". insecure.org. Retrieved 13 March 2017.
- ^ Berger, Emery D.; Zorn, Benjamin G. (1 January 2006). "DieHard: Probabilistic Memory Safety for Unsafe Languages" (PDF). Proceedings of the 27th ACM SIGPLAN Conference on Programming Language Design and Implementation. ACM: 158–168. doi:10.1145/1133981.1134000. S2CID 8984358. Retrieved 14 March 2017.
- ^ Novark, Gene; Berger, Emery D. (1 January 2010). "DieHarder: Securing the Heap" (PDF). Proceedings of the 17th ACM Conference on Computer and Communications Security. ACM: 573–584. doi:10.1145/1866307.1866371. S2CID 7880497. Retrieved 14 March 2017.
- ^ "Memory Debugging in Allinea DDT". Archived from the original on 2015-02-03.
- ^ Gyllenhaal, John. "Using Valgrind's Memcheck Tool to Find Memory Errors and Leaks". computing.llnl.gov. Archived from the original on 7 November 2018. Retrieved 13 March 2017.
- ^ "Memcheck: a memory error detector". Valgrind User Manual. valgrind.org. Retrieved 13 March 2017.
- ^ Kreinin, Yossi. "Why custom allocators/pools are hard". Proper Fixation. Retrieved 13 March 2017.
- ^ "Using the Garbage Collector as Leak Detector". www.hboehm.info. Retrieved 14 March 2017.
- ^ "Semantic Designs: CheckPointer compared to other safety checking tools". www.semanticdesigns.com. Semantic Designs, Inc.
- ^ "AddressSanitizerPerformanceNumbers". GitHub.
- ^ "References". The Rustonomicon. Rust.org. Retrieved 13 March 2017.
- ^ Bessey, Al; Engler, Dawson; Block, Ken; Chelf, Ben; Chou, Andy; Fulton, Bryan; Hallem, Seth; Henri-Gros, Charles; Kamsky, Asya; McPeak, Scott (1 February 2010). "A few billion lines of code later". Communications of the ACM. 53 (2): 66–75. doi:10.1145/1646353.1646374. Retrieved 14 March 2017.
- ^ Gv, Naveen. "How to Avoid, Find (and Fix) Memory Errors in your C/C++ Code". Cprogramming.com. Retrieved 13 March 2017.
- ^ "CWE-633: Weaknesses that Affect Memory". Community Weakness Enumeration. MITRE. Retrieved 13 March 2017.
- ^ "CWE-762: Mismatched Memory Management Routines". Community Weakness Enumeration. MITRE. Retrieved 13 March 2017.