| OS-SANITIZER: System-wide Latent Defect Inference in Linux Applications | |
|---|---|
| Author | Addison Crump addison.crump@cispa.de CISPA Sahil Sihag sahil.sihag@cispa.de CISPA Florian Bauckholt florian.bauckholt@cispa.de CISPA Keno Hassler keno.hassler@cispa.de CISPA Thorsten Holz thorsten.holz@mpi-sp.org MPI-SP |
| Conference | USENIX Security |
| Year | 2026 |
개요
eBPF를 활용하여 커널 및 애플리케이션의 런타임 동작을 관찰하고, 해당 동작이 실제 failure로 이어지기 전에 잠재적인 defect가 될 수 있는지를 추론하는 Framework를 제안하였다. 즉, 기존 sanitizer가 주로 실제 fault나 failure가 발생한 이후 이를 탐지하는 데 초점을 맞추었다면, 본 논문은 정상적으로 실행되는 것처럼 보이는 런타임 동작에서도 향후 보안 취약점이나 correctness 문제로 이어질 수 있는 패턴을 탐지하고자 한다.
Motivation & Importance
기존의 static analyzer는 정적 분석 시점에 얻을 수 있는 정보를 바탕으로 버그를 찾는다. 이와 유사하게, 본 논문은 런타임에만 알 수 있는 정보들을 활용하여 defect를 추론하는 Dynamic Defect Inference가 가능하다고 주장한다.
특히 많은 결함은 코드 자체만으로는 명확히 드러나지 않고, 실제 실행 환경, 권한, 파일 시스템 상태, path traversal 과정, multi-threaded access, library usage pattern 등에 따라 문제가 된다. 따라서 런타임 context를 관찰할 수 있다면, 기존 static analysis나 sanitizer가 놓치는 잠재적 결함을 찾을 수 있다.
본 논문은 eBPF가 이러한 Dynamic Defect Inference를 수행하기에 적합한 기반임을 보이고자 한다. eBPF는 커널 내부 및 user-space function entry/exit에 hook을 삽입할 수 있고, BPF map을 통해 여러 이벤트 사이의 context를 축적할 수 있기 때문이다. 이를 통해 eBPF가 단순한 tracing이나 monitoring 도구를 넘어, runtime information을 기반으로 defect를 추론하는 testing/inference framework로 사용될 수 있음을 보인다.
Challenge
- Benign execution에서 defect를 추론해야 한다.
- 실제 crash나 fault가 발생한 것이 아니므로, 관찰되는 동작이 진짜 defect인지 단순한 code smell인지 구분하기 어렵다.
- 따라서 heuristic 기반의 판단이 필요하며, false positive를 완전히 제거하기 어렵다.
- Runtime context를 정확히 수집해야 한다.
- 일부 defect는 단일 system call이나 library call만으로 판단할 수 없다.
- 예를 들어 TOCTOU나 path traversal 문제는 access, open, path resolution, permission check 등 여러 이벤트를 종합해야 한다.
- System-wide monitoring의 overhead를 낮춰야 한다.
- OS-SANITIZER는 특정 프로그램 하나만 분석하는 것이 아니라, 시스템 전체에서 발생하는 이벤트를 장기간 관찰하는 것을 목표로 한다.
- 따라서 tracing overhead와 report volume을 낮게 유지해야 한다.
- eBPF의 제한 안에서 inference logic을 구현해야 한다.
- eBPF verifier는 bounded execution과 제한된 memory access를 요구한다.
- 복잡한 analysis logic이나 hot user-space function monitoring은 높은 overhead 또는 verifier 제약으로 인해 실용적이지 않을 수 있다.
Background
- 소프트웨어 테스팅의 단계
- Software testing은 다음 5단계로 나눌 수 있다: Errors, Code smells, Defects, Faults, and Failures.
- Error: Developer나 User에 의한 실수
- Code smell: 당장 failure를 만들지는 않지만, 향후 defect로 이어질 수 있는 위험한 패턴
- Defect: Program에 잘못된 영향을 끼칠 수 있는 에러
- Fault: Defect가 실제 program state에 잘못된 영향을 끼친 경우
- Failure: Fault가 외부에서 관찰 가능한 잘못된 동작이나 safety guarantee 위반으로 드러난 경우
- Dynamic Defect Inference에 대한 Related Work
- Program-Level Inference: Compiler의 도움을 받아 dynamic testing을 수행하는 방식이다. 대표적으로 AddressSanitizer, MemorySanitizer 등이 있다. 이러한 방식은 강력하지만 recompilation이 필요하고, 종종 performance overhead가 커서 production 환경보다는 testing 환경에서 주로 사용된다는 한계가 있다.
- Interprocedural Inference: Runtime에서 procedure 간 information flow를 추적하여 버그를 탐지하는 방식이다. Library call이나 network protocol의 사용 순서를 관찰하여 protocol violation을 찾는 방식으로 이해할 수 있다.
- OS-Integrated Inference: SELinux와 같이 OS의 기능을 활용하여 이상 동작을 감지하거나 policy violation을 탐지하는 방식이다. 다만 이러한 방식은 일반적으로 security policy enforcement에 가깝고, 다양한 defect class를 추론하는 데에는 제한적일 수 있다.
- Runtime Predictive Analysis: Runtime에서 얻을 수 있는 정보를 바탕으로 향후 발생할 수 있는 오류를 예측하거나 탐지하는 방식이다. 대표적으로 ThreadSanitizer와 같은 race detection 기법이 있다.
Main Idea
eBPF를 통해 kernel 및 user-space program의 런타임 동작을 수집하고, BPF map에 context를 축적한 뒤, heuristic 기반의 검증기를 통해 해당 동작이 잠재적 defect인지 판단한다.
핵심 아이디어는 static analysis의 code smell 개념을 runtime으로 가져오는 것이다. 즉, 실제 failure가 발생하지 않았더라도, 런타임에서 관찰된 실행 패턴이 특정 조건에서는 취약점이나 correctness 문제로 이어질 수 있다면 이를 report한다.
Design

OS-SANITIZER는 eBPF program을 kernel function 또는 user-space function의 entry/exit point에 부착하여 runtime event를 수집한다. 각 eBPF program은 관찰한 정보를 BPF map에 저장하고, 이후 관련 operation이 끝났을 때 map에 축적된 context를 바탕으로 heuristic 검사를 수행한다.
각 eBPF pass는 대체로 다음 네 가지 역할을 가진다.
- Suspicious code region report
- Context enrichment
- Stale context cleanup
- Known false positive filtering
이를 통해 논문은 다음과 같은 pass들을 구현하였다.
1. Fault-Prone System Interactions
- access: access/stat 이후 open 사용으로 인한 TOCTOU 가능성 탐지
- fixed_mmap: overlapping fixed mmap 탐지
- rwx_mem: readable/writable/executable memory allocation 탐지
2. Fault-Prone Library Usage
- filep_unlocked: multi-thread 환경에서 unsynchronized FILE* access 탐지
- gets: unsafe gets usage 탐지
- snprintf: snprintf 관련 information leak 또는 footgun 탐지
- printf_mut: mutable string을 format string으로 사용하는 경우 탐지
- system_mut: mutable command string을 system()으로 실행하는 경우 탐지
- system_abs: absolute path 없이 system command를 실행하는 경우 탐지
3. Environmental Defects
- sec_file_open: unsafe file permission 또는 unsafe open pattern 탐지
- intercept_path: attacker가 path traversal을 가로챌 수 있는 상황 탐지
4. Unsafe Memory-Manipulating Function Usage
- memcpy
- strcpy
- strncpy
- sprintf
Result
논문은 microbenchmark, SPEC CPU 2017, BrowserBench Speedometer, reproduction study, long-term desktop deployment를 통해 OS-SANITIZER를 평가하였다.
중요한 결과는 다음과 같다.
- System interaction 중심의 pass들은 대체로 낮은 overhead로 동작한다.
- 반면 memcpy, strcpy, strncpy, sprintf와 같은 hot user-space function을 uprobe로 추적하는 pass들은 overhead가 커서 practical deployment에는 부적합하다.
- 기존 CUU(check-use-use) TOCTOU detection model을 OS-SANITIZER pass로 재구현하여, eBPF 기반 framework가 기존 kernel modification 기반 testing logic을 더 쉽게 표현할 수 있음을 보였다.
- 장기 사용 실험에서 Golang, Docker, Kubernetes, runc, dotconf, Firefox, Chrome, Rust, GDB, NetworkManager 등 실제 software stack에서 여러 latent defect를 발견하였다.
Contribution
- Dynamic Defect Inference라는 문제 설정을 제시하였다.
- 기존 dynamic testing이 실제 fault나 failure를 찾는 데 집중했다면, 본 논문은 benign execution에서 defect 가능성을 추론하는 방향을 제시하였다.
- eBPF를 testing/inference tool로 활용하였다.
- eBPF를 단순 tracing이나 security monitoring이 아니라, runtime context를 축적하고 defect-level report를 생성하는 framework로 사용하였다.
- System-wide runtime context를 활용하였다.
- user-space function, kernel function, LSM hook 등을 조합하여 단일 프로그램 내부에서는 알기 어려운 실행 환경 정보를 활용하였다.
- 실제 software에서 latent defect를 발견하였다.
- 여러 mature software stack에서 실제 issue를 찾았다는 점이 논문의 실용성을 뒷받침한다.
Criticize
- Heuristic 의존성이 크다.
- OS-SANITIZER는 실제 failure를 직접 관찰하는 것이 아니라 위험한 pattern을 추론한다.
- 따라서 false positive를 완전히 피하기 어렵고, 어떤 report가 진짜 defect인지 triage cost가 발생한다.
- False positive와 coverage를 정량화하기 어렵다.
- Code smell 또는 contextual defect는 true positive와 false positive의 경계가 명확하지 않다.
- 논문에서도 false positive rate를 엄밀하게 계산하기보다는 case study 중심으로 효과를 보인다.
- Pass 개발의 일반성이 충분히 검증되지는 않았다.
- 논문은 여러 pass를 구현했지만, 새로운 domain이나 새로운 defect class에 대해 pass를 얼마나 쉽게 만들 수 있는지는 더 많은 사례가 필요하다.
- Hot function monitoring에는 eBPF overhead가 크다.
- memcpy, strcpy와 같은 high-frequency function을 uprobe로 추적하면 overhead가 커진다.
- 따라서 OS-SANITIZER가 모든 bug class에 적합한 것은 아니다.
- Long-term deployment 평가가 제한적이다.
- 실제 desktop 환경에서 유용한 defect를 찾았다는 점은 강하지만, 다양한 production workload에서 report volume이나 triage cost가 어떻게 되는지는 더 평가가 필요하다.
Conclusion
본 논문의 핵심 의의는 Dynamic Defect Inference라는 문제를 명확히 제시하고, eBPF를 runtime testing/inference framework로 사용할 수 있음을 보였다는 점이다. 기존 sanitizer나 fuzzer가 실제 fault/failure를 trigger하는 데 집중했다면, OS-SANITIZER는 정상적으로 실행되는 것처럼 보이는 runtime behavior에서도 잠재적 defect를 추론한다.
다만 heuristic에 의존하기 때문에 false positive, coverage, triage cost를 정밀하게 평가하기 어렵다는 한계가 있다. 또한 모든 defect class에 적합한 것은 아니며, 특히 hot user-space function을 추적하는 경우 eBPF overhead가 커질 수 있다. 그럼에도 불구하고, eBPF를 활용해 system-wide runtime context를 수집하고 실제 software에서 latent defect를 발견했다는 점에서 의미 있는 contribution을 가진 논문으로 볼 수 있다.