728x90

memzero_explicit() 함수

 

메모리 영역을 명시적으로 0으로 초기화하는 함수로 민감한 데이터를 메모리에서 완전히 제거해야 할 때 사용한다.

보통 C/C++ ㅇ언어에서 보안 관련 프로그래밍을 할 때 사용한다. 암호화를 위한 키나 패스워드와 같은 민감한 정보를 메모리에서 확실하게 제거하기 위해서 사용된다.

 

일반적으로 memset()으로 메모리를 0으로 초기화하는 것이 가능하지만 컴파일러에 의한 최적화 과정에서 memset() 호출 코드를 제거할 수 있다. 이 경우에 제로화가 동작하지 않는다.

 

memset 대신 memzero_explicit() 함수를 사용하면 컴파일러에 의해 코드가 삭제 되지 않는다.

 

 

함수 원형

static inline void memzero_explicit(void *s, size_t count);

 

memzero_explicit 함수 사용 예시

  • 커널 또는 사용자 공간의 암호화 라이브러리
  • 로그인 시스템에서 비밀번호 처리 후
  • TLS 세션 키 삭제 시
  • 파일 암호화/복호화 작업 후

 

memzero_explicit() 함수는 Linux 커널의 include/linux/string.h 헤더 파일에 정의되어 있다.

함수는 static inline으로 정의되어 있어 컴파일 시점에 인라인으로 확장되어 함수 호출 오버헤드를 줄이고 최적화 방지 효과를 유지한다.

 

초기에는 memzero_explicit() 함수가 lib/string.c 파일에 정의되어 있었다. 그러나 이후 커널 버전에서 include/linux/string.h 헤더 파일로 이동되어 static inline 함수로 정의되었다.

static inline void memzero_explicit(void *s, size_t count)
{
	memset(s, 0, count);
	barrier_data(s);
}

 

barrier_data(s); 코드로 인해 컴파일러가 memset() 함수 호출을 최적화하여 제거하지 않도록 하는 역할을 한다.

 

 

 

barrir_data 는 매크로 함수로 정의되어 있으며, 코드는 다음과 같이 구현되어 있다.

#define barrier_data(ptr) \
  __asm__ __volatile__ ("" : : "r"(ptr) : "memory")

 

해당 매크로는 아무런 연산을 하지 않는 빈 인라인 어셈블리로 보이지만 매우 중요한 역할을 수행한다.

 

  • __asm__+ __volatile__
    • __asm__은 인라인 어셈블리를 의미한다.
    • __volatile__은 컴파일러가 이 코드를 절대로 제거하거나 재배치하지 않도록 강제한다.
  • "r"(ptr)
    • ptr을 레지스터에 넣으라고 명시한다. 이로 인해 컴파일러는 ptr이 실제로 참조되었음을 인식한다.
  • "memory"
    • 이는 메모리 클로버(memory clobber)라고 부르며, 컴파일러에게 이 어셈블리 코드는 메모리에 영향을 줄 수 있다고 알린다.
    • 따라서 컴파일러는 memset() 이후에 메모리 상태가 바뀔수 있다고 간주하게 되어 memset() 호출을 제거하거나 무시하지 못한다.
728x90

+ Recent posts