안드로이드 시스템 개발 중 새로운 서비스나 바이너리를 추가하면 높은 확률로 'Permission Denied' 에러를 마주하게 됩니다. 이는 리눅스의 기본 권한 문제가 아니라, 안드로이드의 강제 접근 제어(MAC)인 SELinux 정책 때문인 경우가 많습니다. 수많은 보안 규칙을 수동으로 작성하는 것은 매우 까다로운 작업이지만, 안드로이드에서는 차단된 로그를 기반으로 정책을 자동 생성해주는 audit2allow라는 강력한 도구를 제공합니다.
본 포스팅에서는 audit2allow를 활용해 avc: denied 로그를 분석하고, 이를 실제 정책 모듈(.te 파일)로 만들어 시스템에 적용 및 검증하는 전체 과정을 다루어 보겠습니다.

📌 핵심 요약 3줄
- 로그 기반 정책 생성: dmesg나 logcat에 기록된 avc: denied 로그를 추출하여 필요한 allow 규칙을 자동으로 생성합니다.
- 정책 모듈화: 생성된 규칙을 .te 파일로 구성하고 컴파일하여 시스템 보안 정책에 안전하게 통합합니다.
- 실무 검증: setenforce를 활용한 Permissive 모드 테스트와 로드된 모듈 리스트 확인을 통해 정책의 유효성을 검토합니다.
1. SELinux 차단 로그(avc: denied) 분석
정책 수정을 시작하기 전, 어떤 동작이 왜 차단되었는지 정확히 파악해야 합니다.
[표: avc: denied 로그 핵심 구성 요소]
| 구성 요소 | 의미 | 분석 내용 |
| scontext | Source Context | 접근을 시도한 주체(도메인). 예: u:r:untrusted_app:s0 |
| tcontext | Target Context | 접근 대상이 되는 리소스의 타입. 예: u:object_r:system_file:s0 |
| tclass | Target Class | 대상 리소스의 종류. 예: file, dir, unix_stream_socket |
| action | Denied Action | 차단된 구체적인 동작. 예: read, write, execute, open |
2. audit2allow를 활용한 정책 자동 생성
차단된 로그를 파일로 저장한 뒤, audit2allow 도구에 입력하면 즉시 적용 가능한 allow 구문을 얻을 수 있습니다.
[표: audit2allow 실행 단계]
| 단계 | 작업 내용 | 실행 명령어 예시 |
| Step 1 | 실시간 로그 확인 및 저장 | adb logcat -b all | grep "avc: denied" > audit.log |
| Step 2 | 정책 구문 생성 | audit2allow -i audit.log |
| Step 3 | 출력 결과 확인 | allow untrusted_app system_file:file read; (출력 예시) |
3. 정책 모듈화 및 시스템 적용
단순히 구문을 추가하는 것을 넘어, 안드로이드 빌드 시스템에 맞게 정책을 모듈화하여 관리하는 것이 유지보수에 유리합니다.
정책 모듈 파일(my_policy.te) 예시:
module my_policy 1.0;
require {
type untrusted_app;
type system_file;
class file { read open getattr };
}
allow untrusted_app system_file:file { read open getattr };
[표: 정책 컴파일 및 적용 프로세스]
| 순서 | 작업 내용 | 사용 명령어 |
| 1 | 정책 모듈 컴파일 | checkmodule -M -m -o my_policy.mod my_policy.te |
| 2 | 정책 패키지 생성 | semodule_package -o my_policy.pp -m my_policy.mod |
| 3 | 시스템에 정책 설치 | semodule -i my_policy.pp |
| 4 | 적용 상태 확인 | semodule -l | grep my_policy |
💡 개발을 위한 팁
- 연쇄 차단 해결: 하나의 avc: denied를 해결하면 그 다음 단계의 차단 로그가 이어서 발생하는 경우가 많습니다. Permissive 모드에서 모든 로그를 한꺼번에 수집한 뒤 정책을 일괄 생성하는 것이 시간을 단축하는 비결입니다.
- 구조적 접근: audit2allow가 제안하는 정책이 항상 정답은 아닙니다. 보안상 위험한 권한(예: capability dac_override)을 요구한다면, 정책을 추가하기보다 대상 파일의 라벨(Label)이나 소유권을 변경하는 것이 더 나은 해결책일 수 있습니다.
- BoardConfig.mk 활용: 영구적인 적용을 위해서는 BOARD_SEPOLICY_DIRS 변수에 커스텀 정책 디렉터리를 추가하여 빌드 시점에 포함시켜야 합니다.
⚠️ 흔히 하는 실수
[표: SELinux 정책 수립 시 주의사항]
| 실수 유형 | 상세 내용 | 해결 방안 |
| 과도한 권한 허용 | audit2allow가 생성해준 대로 모든 권한을 다 주는 경우 | 필요한 최소한의 작업(예: read만)인지 확인 후 적용 |
| neverallow 위반 | 구글의 기본 보안 정책에서 금지한 규칙을 추가하는 경우 | 빌드 시 에러 발생. 도메인을 분리하거나 다른 접근 방식 모색 |
| Labeling 누락 | 정책은 추가했지만, 실제 파일에 file_contexts 라벨이 안 붙은 경우 | ls -Z로 파일 라벨을 확인하고 restorecon 수행 |
4. 결론
audit2allow는 복잡한 안드로이드 SELinux 환경에서 개발자의 생산성을 높여주는 필수적인 도구입니다. 하지만 이 도구가 생성해주는 정책을 맹목적으로 신뢰하기보다는, 시스템 보안 아키텍처 관점에서 적절한 권한인지 검토하는 과정이 반드시 병행되어야 합니다.
본 가이드에서 소개한 프로세스를 통해 차단 로그 분석부터 정책 모듈화 적용까지 능숙하게 다룰 수 있게 된다면, 안드로이드 시스템 개발의 보안 장벽을 훨씬 더 수월하게 넘을 수 있을 것입니다. 작업 중 해결되지 않는 독특한 avc: denied 로그가 있다면 댓글로 함께 공유해 주세요!
'Android System & AOSP Engineering > Android Security & SELinux' 카테고리의 다른 글
| 안드로이드 SELinux 보안의 핵심: neverallow 정책 개념 및 활용 가이드 (0) | 2025.05.13 |
|---|---|
| 안드로이드 SELinux 디버깅 완벽 가이드: dmesg와 logcat 활용법 (0) | 2025.05.12 |
| 안드로이드 SELinux avc: denied 로그 분석 및 해결 완벽 가이드 (0) | 2025.05.10 |
| Android Third-party 앱 SELinux 정책 가이드: untrusted_app과 isolated_app 차이점 (0) | 2025.05.09 |
| 안드로이드 Vendor 바이너리 SELinux 정책 적용 가이드: sepolicy 설정부터 디버깅까지 (0) | 2025.05.08 |