Android는 OEM에서 자체 구현한 SELinux를 철저히 테스트할 것을 적극적으로 권장합니다. 제조업체가 SELinux를 구현하려면 먼저 테스트 기기 풀에 새 정책을 적용해야 합니다.
새 정책을 적용한 후에는 getenforce
명령어를 실행하여 SELinux가 기기에서 제대로 된 모드로 동작하는지 확인합니다.
그러면 전역 SELinux 모드가 시행 또는 허용인지 출력합니다. 각 도메인의 SELinux 모드를 확인하려면 관련 파일을 검사합니다. 또는 /platform/system/sepolicy/tools/
에 위치한 최신 버전의 sepolicy-analyze
에 적절한 플래그(-p
)를 추가하여 실행합니다.
거부 로그 판독
오류를 확인하세요. 이 오류는 이벤트 로그로 dmesg
와 logcat
에 라우팅되고 기기에서 로컬로 조회할 수 있습니다. 제조업체는 공개 출시 전 허용 모드를 통해 기기에서 SELinux가 dmesg
에 출력한 내용을 검사하고 설정을 조정한 후, 시행 모드로 최종 전환합니다. SELinux 로그 메시지는 avc:
를 포함하므로 grep
을 이용해 쉽게 찾을 수 있습니다. cat /proc/kmsg
를 실행하여 진행 중인 거부 로그를 캡처하거나 cat /sys/fs/pstore/console-ramoops
를 실행하여 이전 부팅에서 남아 있는 거부 로그를 캡처하는 것이 가능합니다.
제조업체는 출력된 결과를 이용하여 시스템 사용자나 구성요소가 SELinux 정책을 위반했을 때 쉽게 식별할 수 있습니다. 그런 다음 소프트웨어와 SELinux 정책 중 하나 또는 둘 다를 변경하여 잘못된 동작을 바로잡을 수 있습니다.
특히 이러한 로그 메시지는 시행 모드에서 어떤 프로세스가 실패할지와 그 원인을 보여 줍니다. 예를 들면 다음과 같습니다.
avc: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd" scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
다음과 같이 출력 내용을 해석합니다.
- 위
{ connectto }
는 실행 중인 작업을 나타냅니다. 문장 마지막의tclass
(unix_stream_socket
)와 함께 어떤 작업이 이루어졌는지 대략 알려 줍니다. 여기서는 무언가가 Unix 스트림 소켓에 연결하려고 했습니다. -
scontext (u:r:shell:s0)
는 어떤 컨텍스트가 작업을 시작했는지 알려 줍니다. 여기서는 셸로 실행된 무언가입니다. -
tcontext (u:r:netd:s0)
는 작업 대상의 컨텍스트를 표시합니다. 여기서는netd
가 소유한 unix_stream_socket입니다. - 윗부분의
comm="ping"
에서는 거부가 생성되었을 때 실행 중이었던 작업에 관해 추가적으로 알아볼 수 있습니다. 여기서 이 정보는 매우 유용합니다.
다른 예시를 확인해 보겠습니다.
adb shell su root dmesg | grep 'avc: '
출력:
<5> type=1400 audit: avc: denied { read write } for pid=177 comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0 tcontext=u:object_r:kmem_device:s0 tclass=chr_file
이 거부의 주요 요소는 다음과 같습니다.
- 작업 -
read write
또는setenforce
와 같이 시도한 작업이 대괄호에 강조표시되어 있습니다. - 행위자 -
scontext
(소스 컨텍스트) 항목은 행위자를 나타내며, 이 경우에는rmt_storage
데몬입니다. - 객체 -
tcontext
(대상 컨텍스트) 항목은 실행 중인 객체, 즉 여기에서는 kmem을 나타냅니다. - 결과 -
tclass
(대상 클래스) 항목은 실행 중인 객체의 유형을 나타내고 여기에서는chr_file
(문자 기기)입니다.
허용 모드로 전환
SELinux 시행은 userdebug 또는 eng 빌드에서 ADB를 통해 사용 중지할 수 있습니다. 이렇게 하려면 먼저 adb root
를 실행하여 ADB를 루트로 전환합니다. 그런 다음 SELinux 시행을 사용 중지하려면 다음을 실행합니다.
adb shell setenforce 0
또는 초기에 기기를 불러오는 동안 커널 명령줄에서 다음을 실행합니다.
androidboot.selinux=permissive
androidboot.selinux=enforcing
audit2allow 사용
selinux/policycoreutils/audit2allow
도구는 dmesg
거부를 이에 대응하는 SELinux 정책 구문으로 변환합니다. 따라서 SELinux 개발 속도를 크게 높일 수 있습니다.
audit2allow
는 Android 소스 경로의 일부로 제공되며 소스로부터 Android를 빌드할 때 자동으로 컴파일됩니다.
사용하려면 다음을 실행하세요.
adb pull /sys/fs/selinux/policy
adb logcat -b all -d | audit2allow -p policy
그래도 각각의 잠재적인 추가사항이 권한을 넘어설 수 있는지 조사해야 합니다. 예를 들어 앞에서 보았던 rmt_storage
거부를 audit2allow
에 입력하면 다음과 같이 제안된 SELinux 정책 구문이 나옵니다.
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
이 정책은 rmt
가 커널 메모리에 쓸 수 있도록 허용합니다. 이는 명백한 보안 취약점입니다. audit2allow
구문은 시작점일 뿐일 때가 많습니다 이 구문을 사용한 후에 좋은 정책을 완성하려면 제대로 된 매크로를 통합하고 소스 도메인과 대상의 라벨을 변경해야 할 수도 있습니다. 때로는 거부를 검토한 결과 정책이 아닌 문제의 애플리케이션을 수정해야 할 때도 있습니다.