안드로이드 오픈 소스 프로젝트(AOSP)를 통해 커스텀 빌드를 진행하다 보면, SoC 벤더에서 제공하는 HAL이나 제조사 고유의 기능을 수행하기 위해 Vendor 파티션에 새로운 바이너리를 추가해야 할 때가 많습니다. 하지만 바이너리를 단순히 경로에 넣는다고 해서 실행되지는 않습니다. 안드로이드의 강력한 보안 경계인 SELinux(보안 강화 리눅스)가 이를 엄격히 통제하기 때문입니다.
본 포스팅에서는 Vendor 영역에 추가된 바이너리가 보안 경계를 침해하지 않으면서도 정상적으로 동작하도록 SELinux 정책을 정의하고 적용하는 방법을 상세히 다루어 보겠습니다.

📌 핵심 요약 3줄
- 도메인 및 컨텍스트 분리: Vendor 바이너리 전용 도메인을 정의하고, file_contexts를 통해 실행 파일에 적절한 보안 라벨을 부여해야 합니다.
- Init 프로세스 연동: 서비스가 init에 의해 실행될 때 발생하는 도메인 전이(Domain Transition) 규칙을 정확히 설정하는 것이 핵심입니다.
- 분리된 보안 정책 준수: System 파티션과 Vendor 파티션의 정책 분리 기조에 따라 vendor_sepolicy 내에서 규칙을 관리해야 합니다.
1. Vendor 영역의 보안 경계 이해
안드로이드 8.0(Oreo) 이후 도입된 Treble 프로젝트로 인해 System과 Vendor 파티션은 완전히 분리되었습니다. 이에 따라 SELinux 정책 역시 각 영역의 독립성을 보장하는 방향으로 구성됩니다.
| 파일명 | 주요 역할 |
| file_contexts | /vendor/bin 하위 바이너리 등 벤더 영역 파일에 보안 컨텍스트(라벨) 부여 |
| device.te (또는 관련 .te) | 해당 바이너리 도메인이 가질 수 있는 자원 접근 권한 정의 |
| init.te (또는 관련 .te) | init 프로세스가 특정 바이너리를 실행(exec)할 수 있도록 허용하는 규칙 정의 |
| attributes | vendor_domain 등 여러 벤더 도메인에 공통으로 부여할 속성 그룹 관리 |
2. 바이너리 실행을 위한 sepolicy 작성 실전
예시로 /vendor/bin/vendor_service라는 바이너리를 추가한다고 가정했을 때의 설정 단계입니다.
2.1. 도메인 및 권한 정의 (vendor_service.te) 바이너리가 어떤 행동을 할 수 있는지 정의합니다.
(파일 내용 예시) type vendor_service, domain; type vendor_service_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(vendor_service) # init에서 실행될 수 있도록 도메인 전이 허용
2.2. 파일 컨텍스트 설정 (file_contexts) 파일 시스템상의 물리적 경로와 위에서 정의한 실행 타입을 연결합니다.
(설정 예시) /vendor/bin/vendor_service u:object_r:vendor_service_exec:s0
3. 서비스 등록 및 빌드 시스템 반영
바이너리를 서비스 형태로 상주시키기 위해 init.rc와 빌드 설정 파일을 수정합니다.
| 항목 | 내용 |
| init.rc 설정 | service vendor_service /vendor/bin/vendor_service 정의 및 seclabel 명시를 통해 서비스 실행 환경 설정 |
| BoardConfig.mk | BOARD_SEPOLICY_DIRS 변수에 새로 작성한 보안 정책 디렉터리 경로를 추가하여 빌드에 포함 |
| 빌드 명령어 | mmm system/sepolicy 명령어로 정책만 수정하여 컴파일하거나 전체 시스템 이미지 빌드 수행 |
4. SELinux 로그 분석을 통한 검증
정책 적용 후 바이너리가 실행되지 않는다면 dmesg를 통해 거부(denied) 로그를 분석해야 합니다.
예제 로그 분석: "avc: denied { execute } for scontext=u:r:init:s0 tcontext=u:object_r:vendor_service_exec:s0 tclass=file"
- 분석: init 프로세스가 vendor_service_exec 라벨이 붙은 파일을 실행(execute)하려다 거부됨.
- 해결: 도메인 전이 규칙(init_daemon_domain)이 빠졌거나, init 도메인에서 해당 실행 파일에 대한 접근 권한이 없는지 확인이 필요합니다.
💡 개발 꿀팁 및 흔히 하는 실수
| 구분 | 내용 |
| 개발 꿀팁 | permissive 모드 활용: 개발 단계에서는 setenforce 0으로 설정해 로그만 수집하고, 분석 후 audit2allow 도구로 정책을 자동 생성하면 효율적입니다. |
| 개발 꿀팁 | 속성(Attribute) 활용: vendor_domain 속성을 부여하면 기본적인 벤더 바이너리용 공통 권한이 자동으로 적용되어 코드를 간결하게 유지할 수 있습니다. |
| 흔한 실수 | 라벨링 미적용: 파일 추가 후 ls -Z 명령어를 통해 실제 바이너리에 의도한 보안 라벨이 정상적으로 부여되었는지 반드시 확인해야 합니다. |
| 흔한 실수 | 파티션 위반: Vendor 도메인이 System 영역의 민감한 파일에 접근하려 할 경우, neverallow 규칙에 걸려 빌드 오류가 발생할 수 있습니다. |
결론
Vendor 영역의 바이너리에 SELinux 정책을 적용하는 과정은 단순한 에러 수정을 넘어 안드로이드의 보안 아키텍처를 완성하는 핵심 작업입니다. 특히 Treble 구조 이후 System과 Vendor 간의 엄격한 분리가 강조되는 만큼, 각 파티션의 권한 경계를 명확히 이해하고 정책을 수립하는 것이 중요합니다.
본 가이드가 AOSP 기반 커스텀 빌드를 진행하는 개발자분들에게 실질적인 도움이 되길 바랍니다. 정책 수립 과정에서 해결되지 않는 avc 로그가 있다면 댓글로 함께 고민해 보아요!
'Android System & AOSP Engineering > Android Security & SELinux' 카테고리의 다른 글
| 안드로이드 SELinux avc: denied 로그 분석 및 해결 완벽 가이드 (0) | 2025.05.10 |
|---|---|
| Android Third-party 앱 SELinux 정책 가이드: untrusted_app과 isolated_app 차이점 (0) | 2025.05.09 |
| 안드로이드 시스템 서비스 추가 가이드: SELinux 정책(sepolicy) 완벽 설정법 (0) | 2025.05.08 |
| AOSP 커스텀 보드 sepolicy 추가 및 적용 가이드: 단계별 실전 예제 (0) | 2025.05.06 |
| AOSP SELinux 정책 설정: BOARD_SEPOLICY_DIRS vs PRODUCT_PRIVATE_SEPOLICY_DIRS 차이점 완벽 정리 (0) | 2025.05.05 |