Android System & AOSP Engineering/Android Security & SELinux

Android SELinux 정책 파일 구조 분석: public vs private 차이점 정리

임베디드 친구 2025. 4. 27. 16:24
반응형

안드로이드 시스템 개발자로서 특정 기능에 대한 권한을 추가하려고 할 때, 가장 먼저 고민되는 것은 "과연 어떤 파일에 이 정책을 써야 하는가?"입니다. AOSP(Android Open Source Project)의 sepolicy 구조는 안드로이드 버전이 올라감에 따라 더욱 복잡해졌고, 특히 플랫폼과 벤더 영역이 엄격히 분리되면서 정책 파일의 위치 선정이 매우 중요해졌습니다.

잘못된 위치에 정책을 추가하면 빌드 에러가 발생하거나, 향후 구글의 호환성 테스트(VTS)를 통과하지 못할 수도 있습니다. 오늘은 system/sepolicy 내부의 디렉터리 구조를 파헤치고, 각 정책 파일이 담당하는 역할을 상세히 정리해 보겠습니다.

Generated by Gemini AI.


📌 핵심 요약 3줄

  1. 영역의 분리: public은 하위 도메인에 노출되는 공용 정책을, private은 플랫폼 내부에서만 사용하는 사유 정책을 담습니다.
  2. 컨텍스트의 세분화: file, service, property, seapp 등 자원 성격에 따라 개별 컨텍스트 파일에서 라벨링을 관리합니다.
  3. 벤더 최적화: 기기 특화 정책은 device/ 또는 vendor/ 디렉터리에서 관리하여 안드로이드 순정 소스와의 충돌을 방지합니다.

1. SELinux 정책 디렉터리 구조 (Android 10+)

Android 10 이후부터는 플랫폼 정책의 캡슐화를 위해 public과 private 디렉터리 구조가 명확해졌습니다.

경로 구분 주요 내용
system/sepolicy/public/ 공용 정책 (API) 벤더/기기 정책에서 참조 가능한 타입 및 도메인 정의
system/sepolicy/private/ 사유 정책 (Internal) 플랫폼 내부에서만 사용하며 외부 노출이 불필요한 정책
system/sepolicy/vendor/ 벤더 공통 정책 SoC 벤더 등이 공통으로 사용하는 정책
device/[vendor]/[device]/sepolicy/ 기기 특화 정책 특정 하드웨어 기기에만 적용되는 커스텀 정책

2. 핵심 정책 파일별 역할 및 예시

각 파일은 특정 리소스에 '보안 이름표(라벨)'를 붙여주는 역할을 합니다.

2.1 컨텍스트(Context) 매핑 파일

파일명 역할 매핑 예시 (Labeling)
file_contexts 파일 시스템 경로와 라벨 매핑 /system/bin/sh u:object_r:shell_exec:s0
service_contexts 바인더 서비스와 라벨 매핑 surfaceflinger u:r:surfaceflinger:s0
property_contexts 시스템 속성과 라벨 매핑 ro.build.type u:object_r:build_prop:s0
seapp_contexts 앱(UID/패키지)과 도메인 매핑 user=_app domain=untrusted_app

2.2 정책 정의 파일 (.te)

  • domain.te: 모든 도메인이 공통으로 가져야 할 기본 규칙을 정의합니다.
  • app.te: 안드로이드 애플리케이션들이 가지는 공통 보안 정책을 포함합니다.
  • init.te: 시스템 부팅 시 가장 먼저 실행되는 init 프로세스의 권한을 다룹니다.

3. 기기 및 벤더 특화 정책 (Device/Vendor Policy)

표준 AOSP 정책만으로는 제조사 고유의 하드웨어(카메라, 센서 등)를 제어할 수 없습니다. 이때 아래 경로를 활용합니다.

  • device.te: 벤더 전용 하드웨어를 위한 새로운 도메인을 정의할 때 사용합니다.
  • genfs_contexts: sysfs, procfs와 같이 부팅 시 동적으로 생성되는 파일 시스템에 대한 라벨을 정의합니다.
    • 예: genfscon sysfs /devices/platform/my_hw u:object_r:sysfs_my_hw:s0

4. SELinux 정책 빌드 과정

정책 수정 후에는 반드시 컴파일 과정을 거쳐 바이너리 파일로 변환되어야 합니다.

  1. 결합: public, private, vendor, device 정책을 수집합니다.
  2. 컴파일: checkpolicy 도구를 통해 문법 및 neverallow 규칙 위반을 검사합니다.
  3. 이미지 생성: 빌드된 정책은 plat_sepolicy.cil, vendor_sepolicy.cil 등으로 생성되어 각 파티션에 저장됩니다.
Bash
 
# 특정 기기의 sepolicy만 빌드하는 예시
mmm system/sepolicy
# 빌드된 결과물 확인
ls out/target/product/[device]/system/etc/selinux/

🛠️ 개발자를 위한 팁 & 흔히 하는 실수

✅ 개발 팁 (Best Practices)

  • 위치 선정의 기술: 벤더 영역에서 참조해야 하는 타입(Type)이라면 반드시 public/에 정의해야 합니다. 반면, 플랫폼 내부 로직이라면 private/에 숨기는 것이 보안상 유리합니다.
  • BoardConfig.mk 확인: 기기 특화 정책이 반영되지 않는다면 BOARD_VENDOR_SEPOLICY_DIRS 변수에 해당 경로가 제대로 추가되어 있는지 확인하세요.

❌ 흔히 하는 실수 (Common Mistakes)

  • System 영역 직접 수정: system/sepolicy를 직접 수정하면 향후 안드로이드 버전 업그레이드 시 병합(Merge) 충돌이 발생할 확률이 매우 높습니다. 가급적 device/ 경로를 활용해 정책을 확장(Extend)하세요.
  • 정규식 오용: file_contexts에서 정규식을 잘못 쓰면 엉뚱한 파일에 권한이 부여되거나, 필요한 파일에 권한이 빠질 수 있습니다. 수정 후에는 반드시 ls -Z로 라벨을 확인해야 합니다.
  • 중복 정의: 동일한 서비스를 public과 vendor 정책에서 중복 정의하면 빌드 시 duplicate definition 에러가 발생합니다.

5. 마무리

Android의 sepolicy 파일 구조를 이해하는 것은 보안 오류를 해결하는 첫걸음입니다. 각 파일의 위치와 역할을 정확히 알면, 무분별하게 권한을 허용하기보다 보안 가이드라인에 맞는 견고한 정책을 설계할 수 있습니다.

오늘 포스팅이 안드로이드 시스템 보안의 기초를 다지는 데 도움이 되었기를 바랍니다. 질문이나 의견이 있으시면 댓글로 남겨주세요!

반응형