안드로이드 프레임워크 개발 시 새로운 기능을 제공하기 위해 System Service를 추가하는 작업은 빈번하게 발생합니다. 하지만 서비스를 열심히 구현해 빌드하더라도, 정작 실행 시 서비스 매니저에 등록되지 않거나 권한 에러로 인해 동작하지 않는 경우가 대다수입니다. 이는 안드로이드의 강력한 보안 체계인 SEL인터넷(SELinux) 정책이 해당 서비스의 접근을 차단하기 때문입니다.
본 포스팅에서는 새로 추가한 System Service가 안드로이드 보안 가이드라인을 준수하면서도 정상적으로 동작할 수 있도록 SELinux 정책(sepolicy)을 작성하고 적용하는 전 과정을 상세히 정리해 보겠습니다.

📌 핵심 요약 3줄
- 보안 컨텍스트 정의: service_contexts에 서비스명을 등록하여 시스템이 인식할 수 있는 라벨을 부여해야 합니다.
- 권한 정책(TE) 작성: .te 파일을 통해 서비스가 실행되고, 바인더(Binder) 통신을 수행하며, 파일에 접근할 수 있는 명시적 규칙을 설정합니다.
- 디버깅과 검증: avc: denied 로그를 분석하고 audit2allow 도구를 활용하여 보안 구멍 없는 최적의 정책을 수립합니다.
1. SELinux 정책의 기본 이해
안드로이드의 SELinux는 모든 프로세스와 리소스에 라벨을 붙여 관리하는 강제 접근 제어(MAC) 방식을 취합니다. 새로운 서비스를 추가한다는 것은 이 보안 체계 안에 새로운 '신분(Context)'을 생성하고 '행동 허가'를 받는 과정과 같습니다.
파일명주요 역할service_contexts서비스 이름과 보안 라벨(u:object_r:...)을 매핑file_contexts실행 바이너리 및 관련 파일 경로에 대한 라벨 정의[name].te해당 도메인이 수행할 수 있는 구체적인 권한(allow) 정의attributes여러 도메인에 공통으로 부여할 속성 그룹 관리
2. 새로운 System Service 추가 및 등록
먼저 MySystemService라는 서비스를 프레임워크에 추가했다고 가정합니다. 서비스 코드가 준비되었다면 이제 시스템에 이 서비스의 존재를 알려야 합니다.
2.1. 서비스 보안 컨텍스트 정의 (service_contexts) AOSP 소스 트리(보통 device/제조사/보드/sepolicy 하위) 내의 service_contexts 파일을 열어 다음 내용을 추가합니다.
(설정 내용) my_system_service u:object_r:my_system_service_service:s0
2.2. 타입 정의 및 정책 파일 생성 (my_system_service.te) 해당 서비스가 어떤 성격을 갖는지 정의하는 .te 파일을 생성합니다. 시스템 서버 내에서 동작하는 서비스라면 system_server_service 속성이 필요합니다.
(파일 내용 예시) type my_system_service_service, system_server_service, service_manager_type;
3. 세부 허용 규칙(Allow Rules) 설정
서비스가 실제로 동작하기 위해서는 바인더 통신 및 시스템 자원 접근 권한이 필요합니다. .te 파일에 아래와 같은 규칙을 추가합니다.
| 규칙 | 설명 |
| allow system_server my_system_service_service:service_manager add; | 시스템 서버가 특정 서비스를 서비스 매니저에 등록(add)할 수 있도록 허용 |
| allow untrusted_app my_system_service_service:service_manager find; | **일반 앱(untrusted_app)**이 등록된 서비스를 찾아(find) 사용할 수 있도록 허용 |
| allow system_server my_system_service_service:binder { call transfer }; | 바인더(Binder) IPC를 통한 데이터 전송 및 호출 권한 부여 |
| allow system_server system_data_file:file { read write }; | 시스템 데이터 영역(/data/system)에 위치한 파일의 읽기/쓰기 권한 (보안상 꼭 필요한 경우에만 설정) |
4. 정책 빌드 및 적용 가이드
수정된 정책을 시스템에 반영하는 단계입니다.
- 정책 증분 빌드: 전체 빌드 대신 mmma system/sepolicy 명령어를 사용하여 정책 파일만 빠르게 빌드할 수 있습니다.
- 이미지 생성 및 플래싱: make bootimage 또는 make systemimage를 통해 이미지를 생성하고 fastboot flash로 디바이스에 적용합니다.
- 실시간 확인: adb shell getenforce 명령어로 Enforcing 모드인지 확인하고, adb shell dumpsys -l을 통해 서비스가 리스트에 올라왔는지 체크합니다.
💡 개발 꿀팁 및 흔히 하는 실수
| 구분 | 내용 |
| 개발 꿀팁 | audit2allow 활용법: adb logcat에서 발생한 avc 로그를 복사해 audit2allow -p out/target/product/.../policy 명령에 넣으면 필요한 allow 구문을 자동으로 생성해 줍니다. |
| 개발 꿀팁 | 최소 권한 원칙: 모든 앱에 find 권한을 주기보다, 접근이 필요한 특정 도메인(예: platform_app)에만 권한을 좁혀서 설정하는 것이 보안상 우수합니다. |
| 흔한 실수 | 서비스명 불일치: Java 코드의 ServiceManager.addService("name", ...)에 사용한 이름과 service_contexts에 등록한 이름이 다르면 서비스 등록/호출이 되지 않습니다. |
| 흔한 실수 | 세미콜론(;) 누락: .te 파일은 문법상 문장 끝에 세미콜론이 반드시 필요하며, 누락 시 빌드 에러가 발생합니다. |
결론
안드로이드 시스템 서비스 추가의 완성은 코딩이 아니라 SEL인터넷 정책 설정에 있다고 해도 과언이 아닙니다. 올바른 sepolicy 설정은 서비스의 정상 동작을 보장할 뿐만 아니라, 악의적인 앱으로부터 시스템 서비스를 보호하는 강력한 방어막이 됩니다.
본 가이드를 통해 service_contexts와 .te 파일의 유기적인 관계를 이해하고, 안전한 안드로이드 프레임워크 개발을 진행하시기 바랍니다. 작업 중 막히는 부분이나 로그 분석이 어렵다면 언제든 댓글로 질문 남겨주세요!
'Android System & AOSP Engineering > Android Security & SELinux' 카테고리의 다른 글
| Android Third-party 앱 SELinux 정책 가이드: untrusted_app과 isolated_app 차이점 (0) | 2025.05.09 |
|---|---|
| 안드로이드 Vendor 바이너리 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 |
| AOSP SELinux 정책(sepolicy) 빌드 및 적용 가이드: 기초부터 트러블슈팅까지 (0) | 2025.05.04 |