DOI QR코드

DOI QR Code

Union Type Confusion Detection System

유니온 타입 안전 위반 취약점 탐지 도구

  • Received : 2025.05.20
  • Accepted : 2025.07.02
  • Published : 2025.08.31

Abstract

Unions, which allow multiple data types to share a single memory space, have been consistently used from the early development of the C language to modern programming languages. Initially designed to overcome the limitations of insufficient hardware capacity, unions remain commonly used today for system optimization and efficiency, even in an era of ample hardware resources. However, due to the nature of union data handling, incorrect type interpretation or improper access by programmers can lead to memory corruption or unexpected behavior, resulting in union type safety violation vulnerabilities. Previously proposed detection tools for type safety violations have either focused solely on class casting or targeted union type safety violations in the context of COM (Component Object Model). As such, research focusing on detecting union type safety violations in C/C++ applications is still insufficient. Therefore, this paper proposes UnionTypeSan, a dynamic runtime detection tool for union type safety violations.

C언어가 처음 개발되었을 때부터 현대의 프로그래밍 언어에서까지 꾸준하게 사용되어온 유니온은 하나의 메모리 공간을 여러 데이터 타입이 공유하도록 허용한다. 과거의 부족한 하드웨어 용량을 극복하기 위해 설계된 유니온은 그 용량이 충분한 현대에도 시스템의 최적화 및 효율성을 위해 여전히 흔히 사용되고 있다. 이러한 유니온의 데이터 특성은 프로그래머가 부정확한 타입 해석이나 잘못된 접근을 하면 메모리 손상이나 예기치 않은 동작이 발생할 수 있으며, 이는 유니온 타입 안전 위반 취약점으로 이어질 수 있다. 하지만 이전에 발표된 타입 안전 위반 취약점 탐지 도구는 클래스 캐스팅에 한하여 탐지를 수행하였거나 COM(Component Object Model)을 대상으로 유니온 타입 안전 위반 취약점 탐지를 수행하였다. 따라서 C/C++의 유니온 타입 안전 위반 취약점을 대상으로 한 연구는 아직 미흡한 수준이며, 이에 본 논문에서는 런타임에 동적으로 유니온 타입 안전 위반 취약점을 탐지하는 UnionTypeSan을 제안한다.

Keywords

I. 서론

유니온은 C/C++에서 여러 타입의 데이터를 한 메모리 공간에 저장할 수 있도록 하는 구조체와 유사한 데이터 구조이다. 하지만 구조체와 달리, 유니온은 모든 멤버가 동일한 메모리 공간을 점유한다. 즉, 한 번에 하나의 멤버만 유효한 값을 가질 수 있으며 마지막으로 저장된 데이터의 타입에 따라 올바르게 접근해야 한다. 유니온 타입 안전 위반이란, 유효하지 않은 타입으로 유니온의 값을 읽는 문제를 의미한다. 유니온 타입 안전성이 위반되면 잘못된 타입 변환으로 인한 예상하지 못한 데이터 해석 오류, 메모리 접근 위반, 데이터 유출 등의 다양한 문제가 발생할 수 있다.

기존에도 타입 안전 위반 취약점 탐지 도구에 대한 연구는 꾸준히 진행되어 왔다. 이러한 타입 안전위반 취약점 탐지 도구에 대한 연구는 크게 클래스캐스팅에 대한 연구와 유니온 캐스팅에 대한 연구로 구분할 수 있다. 클래스 캐스팅에 대한 연구에는 Caver[1], TypeSan[2], HexType[3], EffectiveSan[4] 등이 있으며, C/C++에서는 유니온의 멤버에 대한 접근이 명시적인 타입 변환 없이 이뤄지기 때문에, 기존의 타입 안전 위반 취약점 탐지도구로는 현재 저장된 유니온의 타입을 추론하기 어렵다. 유니온 캐스팅에 대한 연구에는 COMFusion[5]이 있다. 해당 논문은 소프트웨어 구성 요소에 대한 바이너리 인터페이스의 표준인 COM에서의 유니온 타입 안전 위반 취약점에 대해서만 초점을 맞추고 있다. 따라서 일반적인 C/C++ 기반의 상용 어플리케이션에 적용하는 것은 어려움이 있었다.

본 연구는 유니온 타입 안전 위반 취약점의 중요성을 인지하고, 기존 타입 안전 위반 취약점 연구들의 한계점을 극복하기 위해 일반적인 C/C++ 기반의 어플리케이션에도 적용할 수 있는 유니온 타입 안전 위반 취약점을 탐지하는 UnionTypeSan을 제시한다. UnionTypeSan은 유니온 타입 안전 위반 취약점을 탐지하기 위해 런타임 맵을 이용하여 현재 유니온 객체의 멤버 변수 타입을 저장하고, 유니온을 사용할 때마다 사용될 멤버 변수 타입과 비교하여 유니온 타입 안전 위반 취약점을 탐지한다.

본 연구의 주요 기여는 다음과 같다 :

• 일반적인 C/C++ 기반의 어플리케이션을 대상으로 하는 최초의 유니온 타입 안전 위반 탐지도구인 UnionTypeSan을 개발하였다.

• 유니온 멤버 정보의 삽입 및 조회를 위해서 O(1)의 빠른 시간 복잡도를 사용하는 데이터 구조를 설계하여 SPEC CPU 2017에서 평균 1.56%의 오버헤드를 기록하였다.

II. 배경 지식

본 장에서는 타입 안전 위반 취약점에 대해 소개하고 이에 관한 연구 동향에 대해 설명하며, C/C++ 언어에서 찾을 수 있는 유니온에서의 타입 안전 위반 취약점에 대해 기술한다.

2.1 타입 안전 위반 취약점

C/C++ 언어는 오랜 시간 다양한 분야에서 활발하게 사용되어 왔으며, 특히 운영체제, 데이터베이스, 브라우저 등 핵심 소프트웨어 개발에서 중요한 위치를 차지하고 있다. Windows, Linux, Mac,iOS와 같은 운영체제뿐만 아니라 MySQL, Oracle등의 데이터베이스, Firefox와 Chromium 같은 브라우저도 C/C++로 작성된 대표적인 예이다.

이러한 C/C++ 언어는 정적 타입 언어로써, 타입 캐스팅으로 인해 타입 안전 위반 취약점이 발생할 수 있다. 어떠한 객체의 타입을 다른 타입으로 캐스팅하는 것을 타입 캐스팅이라고 하는데, 이 타입 캐스팅을 통해 다른 타입으로 캐스팅된 객체를 호출하여 선언된 타입이 아닌 변경된 타입으로 메모리를 읽어올 때 유효하지 않은 타입으로 접근하게 된다면 잘못된 해석이 발생할 수 있다. 이를 타입 안전 위반 취약점이라고 한다.

예를 들어, 타입 안전 위반 취약점은 더 작은 크기의 메모리 영역을 가리키는 타입에서 더 큰 영역을 가리키는 타입으로 캐스팅 될때나, 메모리 영역 내 값을 읽는 방식이 달라질 때 발생할 가능성이 있다. 이러한 타입 안전 위반 취약점은 공격자가 메모리를 조작하여 시스템 또는 사용자에게 중요한 정보에 접근 또는 임의의 코드를 실행시킬 수 있는 위험을 갖고 있다. 실제 상용 어플리케이션인 Telegram, Firefox, Google Chromium 등에서는 최근 5년동안에도 여전히 타입 안전 위반 취약점이 지속적으로 보고되고 있다. 또한 MITRE는 이러한 타입 안전 위반을 ‘CWE-704:Incorrect Type Conversionor Cast’로 분류하였다[6].

마이크로소프트 보안 대응 센터는 Table 1과 같은 CVE 근본 원인 통계를 발표하였다. 여기에서 볼 수 있듯, 타입 안전 위반 취약점은 전체 메모리 취약점 중 3번째로 발생 빈도가 높은 문제이다. 이러한 빈도는 타입 안전 위반 취약점 탐지의 중요성을 보여주는 중요한 지표이다. C/C++ 언어를 포함한 시스템에 큰 권한을 갖는 언어에서 이러한 타입 안전 위반 취약점은 심각한 보안 문제를 야기할 수 있다. 따라서 이러한 타입 안전 위반 취약점을 탐지하는 기술은 사전에 프로그램의 안전성을 보장할 수 있고, 이를 기반으로 하는 다양한 보안 위협을 방지할 수 있다는 점에서 매우 중요한 역할을 한다.

Table 1. Statistics on the root causes of CVEs occurring annually

JBBHCB_2025_v35n4_745_3_t0001.png 이미지

2.2 유니온 타입 안전 위반 취약점

유니온은 C 언어에서 비롯된 개념으로, 메모리를 효율적으로 사용하고자 하는 목적에서 탄생했다. 1970년대 초반에 데니스 리치(Dennis Ritchie)가 C 언어를 설계할 때, 메모리 제약이 심했던 당시의 하드웨어 환경에서 여러 변수를 한 번에 저장할 수 있는 효율적인 방법이 필요했다[7]. C 언어의 유니온 개념은 하나의 메모리 공간을 여러 데이터 타입이 공유하도록 허용함으로써, 메모리 사용량을 줄이고, 하드웨어 제어와 같이 메모리 관리가 중요한 시스템 프로그래밍에 적합하도록 설계되었다. 예를 들어, 하드웨어 레지스터 값을 특정 상황에 따라 서로 다른 형식으로 해석하거나, 네트워크 패킷의 데이터를 여러 형식으로 변환하는 등의 작업에서 유니온이 유용하게 활용되었다. 이후 C++에도 이 개념이 도입되었으며, 유니온은 C/C++의 중요한 특징 중 하나로 자리 잡게 되었다. 현대의 프로그래밍 언어에서도 이러한 유니온은 빈번하게 사용되고 있다. C/C++ 언어와 같은 시스템 프로그래밍 언어에서 유니온은 메모리 효율성을 극대화하고, 하드웨어와 의 직접적 상호작용을 가능하게 한다는 점에서 여전히 필수적이다.

유니온은 하나의 데이터 공간을 다양한 데이터 타입으로 해석할 수 있는 강력한 유연성을 제공하지만, 동시에 치명적인 취약점을 갖고 있다. 유니온은 모든 멤버가 동일한 시작 주소를 가리키기 때문에, 프로그래머가 부정확한 타입 해석이나 잘못된 접근을 하면 메모리 손상이나 예기치 않은 동작이 발생할 위험이 존재한다. 본 절에서는 이러한 유니온 타입 안전 위반 취약점에 대해 예시로써 소개하고자 한다.

2.2.1 잘못된 유니온 타입 캐스팅에 의해 객체가 잘못된 메모리 참조

Fig. 1.은 잘못된 유니온 타입 캐스팅에 의해 객체가 잘못된 메모리를 참조하는 예시이다. 해당예시에서 16번째 코드 라인에서 int형 변수로 할당된 유니온 변수가 12번째 코드 라인에서 string 포인터로 캐스팅되어 잘못된 메모리를 참조하도록 작성되어 있다. 이러한 잘못된 메모리 참조는 메모리 또는 주소 오염 및 정의되지 않은 동작으로 이어질 수 있어 보안적으로 매우 위험하다. Fig. 2.를 통해 각 구조체가 어떻게 구성되어 있는지 확인할 수 있다.

JBBHCB_2025_v35n4_745_3_f0001.png 이미지

Fig. 1. An example of an object incorrectly referencing memory due to improper union type casting

JBBHCB_2025_v35n4_745_4_f0001.png 이미지

Fig. 2. The structure of the object in Fig.1.

2.2.2 Ghostscript type confusion

Ghostscript는 C기반의 인터프리터로, 내부적으로 ref라는 구조체를 통해 동적 타입 객체를 추상화한다. 이 구조체는 타입 정보를 나타내는 type 필드와 다양한 타입을 저장할 수 있는 value 필드로 구성된다. 전체 구조는 Fig. 3.와 같다.

JBBHCB_2025_v35n4_745_4_f0002.png 이미지

Fig. 3. An example of ref struct at ghostscript

이 설계는 type 필드에 따라 value 내부의 어떤 멤버가 유효한지를 결정한다. 그러나 실제 구현에서는 이 타입 정보에 대한 검증이 누락되는 코드 경로가 존재했으며, 이로 인해 유니온 타입 안전 위반 취약점이 발생하였다.

예를 들어, 공격자가 type 필드를 t_integer로 설정하면서 value.ptr에 임의의 포인터 값을 삽입한 후, 이를 포인터로 참조하게 만들면, Ghostscript는 이를 유효한 정수로 간주하지 않고 포인터로 해석하게 되어 임의 메모리 접근 또는 코드 실행이 가능해진다.

III. 동기

본 장에서는 타입 안전 위반 취약점을 탐지하는 기존 연구들에 대해 분석하고, 해당 도구들의 공통적인 한계점을 도출하여 UnionTypeSan의 필요성을 강조하고자 한다.

3.1 기존 연구 소개

타입 안전 위반 취약점을 탐지하는기존 연구는 크게 유니온 캐스팅을 탐지 대상으로 하는 연구와 클래스 캐스팅을 탐지 대상으로 하는 연구가 있다. 본 절에서는 각 연구에 대해 분석하고자 한다.

3.1.1 유니온 타입 안전 위반 취약점 탐지 도구

3.1.1.1 COMFusion

COMFusion[5]는 Microsoft의 COM(Component Object Model)에서 발생할 수 있는 유니온 타입 안전 위반 취약점을 탐지하는 도구이다. COM은 1993년에 도입된 바이너리 인터페이스 표준으로, Windows의 OLE, ActiveX, DirectX와 같은 다양한 기술에서 핵심적으로 사용된다. 메모리 절약을 위해 COM은 구조체 대신 유니온을 광범위하게 사용하지만, 유니온은 메모리의 모든 멤버가 동일한 주소에서 시작하기 때문에 타입 안전 위반이라는 심각한 보안 취약점을 초래할 수 있다. 이러한 취약점은 메모리 손상, 서비스 거부(DoS), 권한 상승 등의 공격으로 이어질 수 있다. COMFusion은 이를 해결하기 위해 유니온 변수와 이의 판별자를 식별하는데 초점을 맞춘다. 네 가지 주요 단계를 거쳐 동작하는데, 먼저 Windows 레지스트리와 OleviewDotNet을 사용해 모든 COM 객체와 MIDL(MicrosoftInterface Definition Language) 파일을 추출한다. 이후, MIDL 파일을 분석해 유니온 선언을 분류하고 판별자와 그 값들을 식별한다. 그런 다음 taint propagation 기법을 이용해 COM 바이너리에서 유니온 변수의 흐름을 추적하고, 심볼릭 실행(symbolic execution)을 통해 유니온 멤버가 사용될 때 판별자가 제대로 확인되었는지 검증한다. 판별자가 확인되지 않은 경우, COMFusion은 이를 취약점으로 보고한다.

3.1.2 클래스 타입 안전 위반 취약점 탐지 도구

3.1.2.1 Caver

Caver[1]는 런타임 타입 캐스팅 검증 도구를 제안하여 C++에서 발생할 수 있는 타입 혼동(bad-casting) 문제를 탐지하는 연구이다. 타입 캐스팅은 C++의 다형성을 지원하는 데 필수적이지만, 잘못된 캐스팅이 발생할 경우 메모리 손상 및 보안 취약점으로 이어질 수 있다. 특히, static_cast는 컴파일 시점에서만 타입 검사를 수행하기 때문에 런타임 오류를 방지하지 못한다는 한계가 있다. Caver는 프로그램 소스 코드를 컴파일할 때 정적 기법으로 프로그램을 계측하고, 런타임에 동적 타입 추적(Type Hierarchy Table)을 사용하여 잘못된 타입 캐스팅을 실시간으로 탐지한다.

3.1.2.2 TypeSan

TypeSan[2]는 C++ 프로그램에서 발생하는 타입 안전 위반 취약점을 효율적이고 광범위하게 탐지할 수 있는 도구이다. TypeSan은 기존의 타입 혼동 탐지 기법이 가진 한계인 낮은 탐지 범위와 높은 성능 오버헤드를 극복하기 위해 설계되었다. 이 도구는 LLVM 기반의 컴파일러 계측을 통해 타입 캐스팅 지점을 자동으로 감지하고, 메모리 객체에 대한 효율적인 메타데이터 저장 방식을 사용하여 런타임에서 모든 캐스팅을 동적으로 검증한다. 특히, TypeSan은 heap, stack, global 메모리에 걸친 객체를 균일하게 관리하며, 압축된 메모리 섀도잉 방식을 도입해 런타임 성능 오버헤드를 최소화한다.

3.1.2.3 HexType

HexType[3]은 C++에서 발생하는 타입 혼동 취약점을 탐지하기 위한 도구이다. C++의 타입 혼동은 잘못된 타입 캐스팅으로 인해 메모리 손상과 보안 취약점으로 이어질 수 있는 주요 원인으로, 특히 static cast, dynamic cast, reinterpret cast와 같은 다양한 타입 변환에서 문제가 발생한다. 기존 도구들은 다형성 객체에 대한 제한적 지원이나 높은 성능 오버헤드로 인해 전체 캐스팅 검증에 한계가 있었다. HexType은 정적 분석과 런타임 검증을 결합하여 모든 타입 캐스팅을 동적으로 확인하며, placement new, reinterpret cast와 같은 복잡한 메모리 재사용 패턴도 지원한다. HexType은 런타임에 객체의 실제 타입 정보를 관리하고, 효율적인 해시 테이블과 적응형 데이터 구조를 통해 검증 성능을 최적화한다.

3.1.2.4 EffectiveSan

EffectiveSan[4]는 C/C++ 프로그램에서 발생하는 타입 혼동, 객체 경계 초과 접근, 재사용 후 해제 등 다양한 메모리 관련 오류를 탐지하기 위한 타입 검사 도구이다. EffectiveSan은 동적 타입 시스템을 도입하여 모든 객체에 실제 타입 정보를 런타임에 바인딩하고, 메모리 접근 시이를 기반으로 타입 및 경계 초과 검사를 수행한다. 이를 통해 명시적 캐스팅뿐만 아니라 함수 인자 전달, 메모리 복사 등에서 발생하는 암묵적 캐스팅에 의한 오류까지 탐지할 수 있다. 또한 low-fat 포인터 기술을 활용하여 메타데이터를 각 객체에 효율적으로 저장하고, 기존의 메모리 구조나 ABI를 변경하지 않으면서도 높은 호환성을 유지한다. EffectiveSan은 타입 오류 외에도 버퍼 오버플로우와 일부 Use-After-Free 취약점을 탐지할 수 있다.

3.1.2.5 libcrunch

Libcrunch는 C 언어에서 발생하는 잘못된 타입 캐스팅 오류를 동적으로 탐지하기 위한 런타임 타입 검사 도구이다. Libcrunch는 프로그램의 바이너리 호환성을 유지하면서도 소스 코드 수정 없이 사용할 수 있도록 설계되었으며, 각 객체에 대한 타입 정보를 할당 시점에 기록하고, 이후 포인터를 통해 접근할 때 기대 타입과의 일치 여부를 검사한다. 이를 통해 명시적 형 변환뿐만 아니라 구조체 포인터 간의 변환, 다형적 사용 등에서 발생하는 타입 혼동 오류를 효과적으로 식별할 수 있다. 또한 낮은 falsepositive 비율과 실용적인 성능 오버헤드를 바탕으로 실제 대형 코드베이스에서도 적용 가능성이 확인되었다. Libcrunch는 C 언어의 유니온과 같이 타입 정보가 명시적으로 유지되지 않는 구조에 대해서는 직접적인 지원을 제공하지는 않지만, 접근 시점의 타입 검사를 기반으로 향후 유니온 타입 안전 위반 취약점의 탐지에 대한 확장 가능성을 제시한다.

3.2 기존 연구 한계 도출

유니온 타입에 대한 타입 안전성 위반 문제를 기존 클래스 타입에 대한 도구들이 거의 다루지 못한다는 점은 기존 연구의 분석 범위 관점에서 공통된 한계점이다. 유니온 타입에서의 타입 안전성 위반을 탐지하기 위해 제시한 COMFusion 도구는 Symbolic Execution 기반의 분석을 진행함에 따라, Symbolic Execution이 가지는 한계점도 주목할만 하다. Symbolic Execution 기술은 변수를 하나의 심볼로 취급하여, 조건 분기를 거칠 때, 해당하는 변수 심볼에 조건을 추가하여 발생 가능한 실행상태를 동시에 분석하기 위한 기술이다. 여기서 Path Explosion이라 하는 문제점을 가지게 되는데, 조건 분기를 계속해서 거치다 보면 발생 가능한 실행 경로들이 폭발적으로 늘어나 분석 시간이 무수히 길어진다는 문제점이다. 또한, COMFusion은 마이크로소프트에서 소개한 소프트웨어 구성 요소에 대한 바이너리 인터페이스의 표준인 COM에서의 유니온 타입 안전 위반 취약점에 대해 초점을 맞추고 연구를 진행하였다. 따라서 일반적인 C/C++ 기반 상용 어플리케이션에 적용하는 것은 다소 어려움이 있다. Table 2는 위에서 언급한 기존 연구와 UnionTypeSan을 비교한 표이다. 이러한 한계점을 해결하여 유니온 타입 안전 위반을 탐지하는 동적 실행 기반의 분석 기술을 디자인한다면, 기존보다 다양한 분석 유형과 정확성을 가질 것으로 전망한다. 따라서 기존 타입 안전 위반 취약점 탐지도구의 한계점을 극복할 수 있고, 유니온 타입 안전 위반 취약점을 탐지할 수 있는 UnionTypeSan이 필요하다.

Table 2. Statistics on the root causes of CVEs occurring annually

JBBHCB_2025_v35n4_745_6_t0001.png 이미지

IV. 설계 및 구현

본 연구의 핵심 목표는 다음과 같다.

• 각 유니온 객체가 어떤 멤버 변수 타입으로 저장되어 있는지 파악

• 런타임에 유니온 객체가 사용될 멤버 변수 타입이 다음 저장되어 있는 멤버 변수 타입과 일치하는지 검증

이러한 핵심 목표를 달성하기 위해 본 연구에서는 UnionTypeSan을 제안한다. Fig. 4.는UnionTypeSan의 개괄적인 디자인이다. 먼저, 프로그램을 빌드할 때 컴파일러 단계에서 사용되는 모든 유니온을 수집한 뒤 각 유니온의 멤버 변수를 타입별로 인덱싱 한다. 다음으로 유니온을 사용하는 모든 표현식을 대상으로 초기화 및 변경 계측 코드를 삽입해야 하는지, 혹은 검증 계측 코드를 삽입해야 하는지 확인하여 각 계측 코드를 삽입한다. 이 때 계측 코드에는 현재 유니온의 타입 정보가 함께 전달되며, 이를 기반으로 런타임에 초기화 및 변경 함수와 검증 함수를 수행하여 유니온 타입 안전 위반 취약점을 탐지한다. 본 장에서는 이러한 UnionTypeSan의 각 기능들에 대해 자세히 소개하고자 한다.

JBBHCB_2025_v35n4_745_6_f0001.png 이미지

Fig. 4. The overview of UnionTypeSan

4.1 정적 계측 코드 삽입 모듈

4.1.1 유니온 수집 및 인덱싱

유니온의 표현식에 계측 코드를 삽입할 때 현재 유니온의 타입을 전달하기 위해, 각 유니온의 멤버 변수의 타입을 숫자로 인덱싱하는 작업이 필요하다. 이를 통해 런타임에 UnionTypeSan이 현재 유니온 객체가 어떤 타입의 멤버 변수로 사용되고 있는지 파악할 수 있다.

유니온의 수집 및 인덱싱은 총 세 개의 함수로 진행한다. 먼저 유니온의 선언이 저장되어 있는 클래스(Decl)를 조회한다. 다음으로 해당 클래스에서 유니온의 멤버 변수를 모두 가져온 다음, Fig. 5.와 같이 각 유니온의 이름이 아닌, 소스 코드의 위치로 유니온을 구분하고, 각 유니온의 멤버 변수를 숫자로 인덱싱한다. 마지막으로 이를 저장하는 함수를 통해 텍스트 파일로 저장하여 유니온의 수집 및 인덱싱 단계를 자동으로 진행한다.

JBBHCB_2025_v35n4_745_7_f0001.png 이미지

Fig. 5. An example image of union collection and indexing

단, C/C++는 이름이 존재하지 않는 익명 유니온의 사용을 지원한다. 만약 유니온의 이름으로 각 유니온을 구분할 경우, 이후 언급될 정적 계측 코드 삽입 과정에서 익명 유니온을 탐지하는 것이 불가능하다. 따라서, 이러한 익명 유니온까지 탐지 범위를 넓히기 위해 본 단계에서는 유니온의 이름 대신 소스 코드 위치를 기준으로 각 유니온을 구분하여 기록하였다.

4.1.2 정적 계측 코드 삽입

유니온 타입 안전 위반 취약점이 발생하는 원인은 유니온 객체에 저장된 값이 올바른 타입으로 해석되지 않는 것이다. 따라서 본 단계에서는 유니온이 초기화 및 변경될 때와 유니온이사용될 때를 구분하여 계측 코드를 삽입함으로써 유니온 객체의 타입을 추적하고, 검증 시점에 유니온에 저장된 값이 잘못된 타입으로 해석되는지 여부를 확인할 수 있다.

4.1.2.1 초기화 및 변경 계측 코드 삽입

유니온이 사용되는 표현식(expression)은 크게 초기화 및 변경 계측(instrumentation) 코드가 삽입되는 표현식과 검증 계측 코드가 삽입되는 표현식으로 구분된다. 표현식이란, clang에서 값의 계산과 연산을 수행하는 코드 조각으로, 변수참조, 함수호출, 연산 등의 다양한 형태가 있다. 본 섹션은 초기화 및 변경 계측이 필요한 표현식을 대상으로 구현 방식을 설명한다.

Clang의 Expr 노드 분석 단계에서, 각 표현식이 MemberExpr을 통해 유니온 멤버에 접근하는지 확인한다. 이후, 해당 Expr이 LHS로 쓰이며 할당 또는 수정 연산에 해당하는 경우, 내부 ClangIR에서 이를 인식하고 계측 함수 호출을 삽입한다. 구체적으로는, 현재 유니온 객체의 주소, 현재 접근 중인 멤버 타입의 인덱스를 함께 런타임으로 전달하는 형태의 함수를 삽입한다. 이 함수는 런타임 라이브러리 측에서 로그를 수집하거나 타입 추적에 활용한다.

초기화 및 변경 표현식에는 두 가지 케이스가 존재한다. 각각은 유니온 멤버 자체가 변경되는 경우와 동일한 멤버의 값만 변경되는 경우이며, 본 연구에서는 두 케이스 모두에 대해 동일하게 계측 코드를 삽입하고 있지만, 후자의 경우는 멤버 타입의 변경이 없기 때문에, 추후 최적화를 통해 계측 삽입을 생략할 수 있는 여지가 있다.

계측 함수는 __Union_Update (Addr, Type_Index)의 형태로 삽입되며, 모든 계측은 기존 메모리 모델이나 ABI에 영향을 주지 않으면서도 유니온 멤버 사용에 대한 추적이 가능하도록 살계되었다.

Fig. 6.은 초기화 및 변경 표현식으로 분류된 실제 예시 코드이다. 12번째 줄의u.intValue=10 문장은 u가 유니온이고 intValue가 해당 멤버에 접근하는 표현식이므로, Clang은 이 위치에서 계측 코드를 자동 삽입한다.

JBBHCB_2025_v35n4_745_8_f0001.png 이미지

Fig. 6. The Example Code of Update Expression

4.1.2.2 검증 계측 코드 삽입

유니온이 사용되는 C/C++ 코드가 검증 표현식이라고 판단되었을 경우, 해당 코드에 검증 계측 코드를 삽입하는 단계이다. 검증 표현식이란, 유니온 객체의 특정 멤버에 저장된 값을 읽어들이거나 사용하는 코드 조각을 의미하며, 변수 대입, 연산, 함수인자 전달 등 다양한 형태로 나타난다.

컴파일러 구현에서는, Clang의 Expr 트리 탐색 중 CallExpr을 통해 유니온 타입의 객체를 참조하는지를 분석한다. 이후, 해당 표현식이 r-value context에 위치하여 값을 읽는 방식으로 사용될 경우에는 검증용 계측 함수 호출을 삽입한다. 이 함수는 이전과 동일하게 현재 유니온 객체의 주소, 멤버 타입의 인덱스를 런타임에 전달하여, 유니온의 타입 안전 위반을 검증한다.

검증 계측 함수는 __Union_Verification (Addr, Type_Index)의 형태로 삽입되며, 이전과 동일하게 기존 메모리 모델이나 ABI에 영향을 주지 않는 형태로 디자인되었다.

Fig. 7.은 검증 계측 코드가 삽입되는 예시이다. 15번째 줄에서 u.intValue의 값을 변수 A에 삽입할 때, 16번째 줄에서 printf 함수에서 u.intValue를 사용할 때, 그리고 17번째 줄에서 변수 B를 u.intValue의 값으로 초기화할 때 검증 계측 코드를 삽입한다. 이 때 14번 째 줄에서 int형 타입의 멤버변수로 초기화된 u객체가 17번째 줄에서 float 형으로 호출되면 초기화되지 않은 영역이 호출되어 유니온 타입 안전 위반이 발생하게 된다.

JBBHCB_2025_v35n4_745_8_f0002.png 이미지

Fig. 7. The example code of Verification Expression

4.2 동적 유니온 타입 안전 위반 탐지 모듈

런타임에 실행되는 계측 코드는 총 두 개의 함수(초기화 및 변경 함수, 검증 함수)로 분류된다. 두 함수 모두 공통적으로 주소의 해시값을 인덱스로 갖는 런타임 맵을 참조하며, 혹시 모를 해시 충돌을 대비하여 HexType의 과 유사하게 RBTree를 추가로 구성한다.

4.2.1 초기화 및 변경 함수

본 단계는 유니온 객체가 어떤 타입으로 초기화 및 변경되었는지를 런타임 맵에 저장하는 단계이다. 런타임에 초기화 및 변경 함수가 실행되면 먼저 전달받은 유니온 객체의 주소값을 기반으로 한 해시값을 생성한다. 이 해시값을 인덱스로 하는 런타임 맵이 존재하지 않으면, 이를 생성한 다음 런타임 맵에 유니온 객체의 주소값과 현재 멤버 타입에 해당하는 인덱스를 삽입한다. 만약 런타임 맵이 존재한다면, 먼저 런타임 맵에 저장된 주소값과 현재 객체의 주소값을 비교한다. 두 주소값이 일치하면 같은 객체로 판단하여 현재 런타임 맵에 저장된 멤버 타입에 해당하는 인덱스를 전달받은 값으로 대체한다. 만약 두 주소값이 일치하지 않으면 해시 충돌로 판단하여 RBTree에서 다음 노드에 이를 저장한다. Fig. 8.은 이 함수에 대한 pseudocode이다.

JBBHCB_2025_v35n4_745_9_f0001.png 이미지

Fig. 8. The pseudocode code of update function

4.2.2 검증 함수

본 단계는 유니온 객체가 어떤 타입으로 초기화되어 있는지 파악한뒤 현재 사용될 타입과 비교하여 유니온 타입 안전 위반 취약점이 발생하는지 검증하는 단계이다. 런타임에 검증 함수가 실행되면 초기화 및 변경 함수와 동일하게 먼저 전달받은 유니온 객체의 주소값을 기반으로 한 해시값을 생성한다. 이 해시값을 인덱스로 하는 런타임 맵이 존재하지 않으면 초기화 및 변경이 누락된 것으로 판단해 이에 대한 리포트를 출력한다. 만약 런타임 맵이 존재한다면, 먼저 런타임 맵에 저장된 주소값과 현재 객체의 주소값을 비교한다. 두 주소값이 일치하면 같은 객체로 판단하여 현재 런타임 맵에 저장된 멤버 타입에 해당하는 인덱스와 전달받은 멤버 타입에 해당하는 인덱스를 비교한다. 두 인덱스가 일치하면 리포트 생성 없이 프로그램을 진행하며, 두 인덱스가 일치하지 않으면 유니온 타입 안전 위반 취약점 리포트를 생성한다. 만약 두 주소값이 일치하지 않으면 해시 충돌로 판단하여 RBTree에서 다음 노드를 찾아 검증을 진행한다. Fig. 9.는 이 함수에 대한 pseudocode이다.

JBBHCB_2025_v35n4_745_9_f0002.png 이미지

Fig. 9. The pseudocode code of verification function

V. 평가

본 장에서는 제안 기술인 UnionTypeSan의 성능을 비교 평가하기 위해 진행한 실험에 대해 기술한다.

5.1 실험 환경

먼저, 실험 환경은 다음과 같이 구성한다.

• Apple MacBook Pro

• Processor : Apple M1

• RAM : 16GB

실험 평가는 다음 항목에 대해 진행한다.

• RQ1 : 유니온 타입에 대한 타입 위반 탐지 기능을 보이는가?

• RQ2. : 추가적인 성능 오버헤드가 얼마나 발생하는가?

실험 평가를 위한 데이터셋은 다음과 같이 구성한다. 이 때, SPEC CPU Benchmark 2017의 경우, 전체 프로그램 중 C/C++기반으로 유니온이 사용되는 프로그램에 대해서만 실험을 진행하였다.

• 유니온 타입 캐스팅 테스트 케이스: 비교할 수 있는 기존 테스트 케이스가 존재하지 않아 구현한 4가지의 자체 테스트 케이스

• (SPEC) SPEC CPU Benchmark2017:유니온이 포함된 6개의 프로그램. 508.namd_r, 510.parest_r, 511.povray_r, 520.omnetpp_r, 523.xalancbmk_r, 526.blender_r 프로그램들이 해당한다.

5.2 기능 평가

1절에서 제시한 실험 평가 항목 중 RQ1. 기능 평가를 진행하기 위해 다음의 실험을 진행하였다.

5.2.1 유니온 타입 캐스팅 테스트 케이스

Table 3은 유니온 타입 캐스팅에 대해 UnionTypeSan이 탐지 기능을 정확히 수행하는지를 평가한 결과이다. 현재까지 발표된 기존 연구들에서는 상용 어플리케이션에서 발생한 유니온 타입 안전 위반을 체계적으로 검증한 선행 사례가 존재하지 않으며, 대부분의 보안 도구들 또한 유니온의 타입 안전성을 대상으로 하지 않기 때문에, 본 논문에서는 이를 보완하기 위해 UnionTypeSan의 기능을 정량적으로 검증할 수 있도록 자체적인 유닛 테스트 케이스를 구성하였다.

Table 3. Comparison of union type casting detection features through test cases

JBBHCB_2025_v35n4_745_10_t0001.png 이미지

총 5개의 유닛 테스트 세트는 모두 본 연구에서 직접 작성한 C 프로그램을 기반으로 하며, 각 세트는 5~12개의 세부 테스트로 구성되어 있다. 이들은 각기 다른 유형의 유니온 사용 상황을 모사하고 있으며, 실제 발생 가능한 타입 안전 위반 시나리오를 중심으로 설계되었다. Table 3의 실험 결과에 다르면, UnionTypeSan은 모든 테스트 케이스에서 100%의 탐지율을 기록하였다. 각 테스트셋의 구성은 다음과 같으며, Fig. 10.은 모든 테스트셋의 예시를 포함한 그림이다.

JBBHCB_2025_v35n4_745_10_f0001.png 이미지

Fig. 10. The simple code of 5 unit test case set

5.2.1.1 Union_allocation_test

유니온이 할당될 때 해당 유니온을 탐지 도구가 잘 탐지하여 update instrumentation이 정확히 삽입되었는지 평가하는 테스트 케이스이다.

5.2.1.2 Union_deallocation_test

유니온이 free()를 통해 해제된 이후, 추가적인 업데이트 계측이 발생하지 않도록 추적이 중단되는지를 확인하는 테스트 케이스이다.

5.2.1.3 Stack_union_test

앞선 두 테스트와 다르게 스택 영역에 선언된 유니온에 대해서도 계측이 정상적으로 적용되는지를 검증하는 테스트 케이스이다.

5.2.1.4 Simple_union_test

유니온 타입 안전 위반이 명확히 발생하는 단순한 예제를 통해 유니온 타입 안전 위반 취약점 탐지가 정확히 동작하는지 검증하는 테스트 케이스이다.

5.2.1.5 Complex_union_test

조건 분기, 함수 호출, 포인터 전달 등 복잡한 흐름 속에서 유니온이 사용되는 상황을 구성하여 UnionTypeSan의 분석 정확도를 검증하는 테스트 케이스이다.

5.2.2 SPEC CPU Benchmark 2017

Table 4는 SPEC CPU Benchmark 2017 데이터셋을 대상으로 얼마나 많이 유니온 캐스팅 검증이 진행되었는지 측정한 결과이다. 기존에 제안된 연구 중에서는 SPEC CPU Benchmark 2017의 유니온 캐스팅을 측정한 결과가 없기 때문에 다른 탐지 도구와의 비교 없이 UnionTypeSan의 검증 결과에 대해서만 확인했다.

Table 4. Comparison of union casting validation counts in the SPEC CPU Benchmark 2017

JBBHCB_2025_v35n4_745_11_t0001.png 이미지

실험 결과, 일부 벤치마크에서는 verification instrumentation 수가 0으로 기록되었는데, 이는 UnionTypeSan의 탐지 한계가 아니라 해당 유니온 객체가 프로그램 실행 중 값은 저장되었지만, 이후 그 값을 실제로 사용하는 코드가 존재하지 않았기 때문이다. 즉, 실행 흐름 상 유니온을 읽는 표현식이 등장하지 않아 검증 계측이 필요하지 않았기 때문에 발생하였다. 이러한 구조는 특히 조건 분기, 호기화만 수행하고 실질적 사용 없이 종료되는 유닛 테스트 함수 또는 초기화 이후 다른 경로로 제어 흐름이 넘어가는 경우에서 자주 나타나는 것으로 확인되었다.

5.3 성능 오버헤드 평가

성능 오버헤드 평가를 진행하기 위해 다음의 실험을 수행하였다. SPEC CPU Benchmark 2017 데이터셋을 대상으로, 실행 시간에 따른 오버헤드를 5회 반복 실행한 후 평균을 통해 측정하였다. 오버헤드 측정은 본 연구에서 제안한 유니온 검증 계측을 적용하지 않은 baseline 버전과 적용한 버전 간의 실행 시간을 비교하여 진행하였으며, 단위는 초로 계산되었다. 실험 결과는 Fig. 11.에 제시되어 있으며, 각 항목의 ratio(%) 열을 통해 오버헤드 비율을 확인할 수 있다.

JBBHCB_2025_v35n4_745_11_f0001.png 이미지

Fig. 11. Evaluation results of runtime overhead on SPEC CPU Benchmark 2017 targets

평균적으로 1.56%의 실행 오버헤드가 측정되었고, 최소 –0.43% (508.namd_r)부터 최대 +3.18% (511.povray_r)까지의 분포를 보였다. 일부 벤치마크에서 측정된 음수 오버헤드는 계측을 통해 성능이 향상되었다는 것을 의미하는 것은 아니며, 다음과 같은 시스템적 요인에의해 발생한 것으로 판단된다.

음수 오버헤드가 발생한 항목은 실질적인 verification이 수행되지 않은 508.namd_r 프로그램으로, 런타임 계측에 의한 비용이 거의 발생하지 않았고, 상대적으로 baseline 실행에서의 IO대기나 컨텍스트 스위칭 등이 더 큰 지연을 유발했을 가능성이 크다. 특히 update instrumentation 연산은 단순히 runtime map에 값을 저장하는 작업만 수행하며, 메모리 접근이나 조건 분기와 같은 고비용 연산이 포함되지 않기 때문에 실제 실행시간에는 거의 영향을 받지 않는다.

이러한 결과는 UnionTypeSan이 일반적인 시스템 성능에 영향을 최소화하면서도 정밀한 타입 검증 기능을 제공한다는 점에서 긍정적으로 해석할 수 있다. 또한 SPEC 벤치마크 내에서 계측이 실제 수행된 구간은 정적 분석 결과와도 일치하여, 계측이 무의미한 영역에 불필요하게 삽입되지 않았음을 확인하였다.

VI. 결론

본 연구의 목표는 유니온을 대상으로 하는 타입 안전 위반 취약점을 탐지하는 것이다. 이를 위해 기존 연구들을 비교 분석하여 공통적인 한계를 도출하고, C/C++로 작성된 대형 소프트웨어에서의 유니온 타입 안전 문제에 대한 인식을 강화하였다. 유니온은 여러 타입을 하나의 메모리 공간에서 공유할 수 있어 런타임에서 잘못된 타입 접근이 발생할 위험이 있으며, 이를 방지하려면 저장된 타입을 추적하고 타입 변환 및 접근을 명시적으로 검사해야 한다. 이를 해결하기 위해 본 연구에서는 정적 계측 삽입 모듈과 동적 탐지 모듈로 구성된 UnionTypeSan을 제안하였으며, 본 연구에서 만든 테스트 케이스 및 SPEC CPU Benchmark 2017을 대상으로 실험을 통해 탐지 성능과 오버헤드를 평가한 결과, 합리적인 오버헤드로 유니온 타입 안전 위반을 탐지할 수 있음을 확인하였다.

References

  1. Byoungyoung Lee and Chengyu Song and Taesoo Kim and Wenke Lee, "Type Casting Verification: Stopping an Emerging Attack Vector," 24th USENIX Security Symposium (USENIX Security 15), pp. 81-96, Aug. 2015.
  2. Haller, Istvan and Jeon, Yuseok and Peng, Hui and Payer, Mathias and Giuffrida, Cristiano and Bos, Herbert and van der Kouwe, Erik, "TypeSan: Practical Type Confusion Detection," Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security, no. 12, pp. 517-528, Oct. 2016.
  3. Jeon, Yuseok and Biswas, Priyam and Carr, Scott and Lee, Byoungyoung and Payer, Mathias, "HexType: Efficient Detection of Type Confusion Errors for C++," Proceedings of the 2017 ACM SIGSAC Conferenceon Computer and Communications Security, no. 15, pp. 2373-2387, Oct.2017.
  4. Duck, Gregory J. and Yap, Roland H.C., "EffectiveSan: type and memory error detection using dynamically typed C/C++," Proceedings of the 39th ACM SIGPLAN Conference on Programming Language Design and Implementation, no. 15, pp. 181-195,Jun. 2018.
  5. Yuxing Zhang and Xiaogang Zhu and Daojing He and Minhui Xue and Shouling Ji and Mohammad Sayad Haghighi and Sheng Wen and Zhiniang Peng, "Detecting Union Type Confusion in Component Object Model," 32nd USENIX Security Symposium (USENIX Security 23),pp. 4265-4281, Aug. 2023.
  6. CWE Content Team, "CWE-704:Incorrect Type Conversion or Cast", https://cwe.mitre.org/data/definitions/704.html, Dec. 2024.
  7. Wikipedia, "C(programming language)", https://en.wikipedia.org/wiki/C_(programming_language), Dec. 2024.
  8. Google Chromium, "CVE-2022-1096," https://nvd.nist.gov/vuln/detail/CVE2022-1096, Dec. 2024.
  9. Google Chromium, "CVE-2022-4262," https://nvd.nist.gov/vuln/detail/CVE2022-4262, Dec. 2024.
  10. Paul Jansen, "TIOBE Index for February 2025," https://www.tiobe.com/tiobe-index/, May. 2025.