SE for Android
Security Enhancements for Android™ (SE for Android) 는 안드로이드 보안을 강화하기 위한 구글 프로젝트다.
Android 4.3이전에는 sandbox를 이용했지만 Android 4.3 이후로 SELinux를 적용했고, Android 5.0 부터 완전하게 적용되었다.
- 보안정책 해제
enforcing : 보안정책에 위반되는 접근은 모두 거부되고, EPERM 에러를 반환한다.
permissive: 보안정잭이 적용되지 않고, 로깅만 된다.
Android 5.0 이후 버젼은 아래 명령으로 AVC 거부 로그를 확인할 수 있다.
adb logcat | grep avc:
enforcing 상태 확인:
adb shell getenforce
enforcing 로 전환
adb shell su 0 setenforce 1
permissive로 전환
adb shell su 0 setenforce 0
영구적으로 해제하려면, bootargs에 androidboot.selinux=permissive를 추가하면 된다.
- 정책설정
아래명령으로 거부로그를 캡춰한 후 audit2allow를 이용해서 보안정책을 적용할 수 있다.
adb shell su 0 cat /proc/kmsg > dmesg.txt &
audit2allow -p out/target/product/device/root/sepolicy < dmesg.txt
우분투에서 audit2allow를 사용하려면 아래 패키지를 인스톨해야한다.
sudo apt-get install policycoreutils
- 정책파일 로딩
정책파일은 안드로이드 빌드시 컴파일되고, 램디스크 이미지에 추가된다. 그래서 시스템파티션이 마운트되기전 부팅초기에 로딩된다. 부팅 후에는 정책파일을 /data/security/current에 위치시키고, selinux.reload_policy property를 1로 설정하면 업데이트된다.
- 정책소스파일 구성
정책설정파일은 external/sepolicy/* 에 위치한다. 이 정책은 안드로이드 플래폼 공통 정책이고 이 파일들은 수정할 필요가 없을 것이다. 각 보드별 정책은 device/vendor/device/BoardConfig.mk 에 BOARD_SEPOLICY* 변수로 설정하고, 정책파일은 device/vendor/device/sepolicy/*에 위치 한다. 여기에 필요한 정책을 추가하면 된다.
정책을 구성하기 위해서는 여러 소스파일이 이용된다. 아래는 주요 안드로이드 정책소스파일이다.
file_contexts : device node, socket, /data directory등 파일 label을 설정
property_contexts: Android properties 위한 label 설정
seapp_contests: 앱 프로세스나 앱 패키지 디렉토리를 위한 label 설정
mac_permissions.xml: middleware MAC(Mandatory Access Control) 정책 설정, SELinux에 없는 SE for Android 전용파일.
정책규칙은 아래 형식으로 구성된다.
allow Domains Types:Classes Permissions;
Domain : 프로세스 설정을 위한 레이블
Type : file, socket 같은 오브젝트 설정을 위한 레이블.
Class : 접근한는 오브젝트의 종류
Permission: 적용되는 오퍼레이션
예) allow appdomain app_data_file:file rw_file_perms;
appdomain은 file종류인 app_data_file오브젝트에 rw_fil_perms를 적용한다.
실행 중인 프로세스의 레이블 확인:
# adb shell ps -Z
LABEL USER PID PPID NAME
u:r:init:s0 root 1 0 /init
u:r:kernel:s0 root 2 0 kthreadd
u:r:kernel:s0 root 3 2 ksoftirqd/0
u:r:kernel:s0 root 4 2 kworker/0:0
….
u:r:system_app:s0 system 3582 2471 com.android.settings
u:r:untrusted_app:s0 u0_a16 3605 2471 com.android.voicedialer
u:r:untrusted_app:s0 u0_a22 3627 2471 com.android.calendar
u:r:untrusted_app:s0 u0_a25 3655 2471 com.android.deskclock
u:r:untrusted_app:s0 u0_a28 3684 2471 com.android.email
u:r:untrusted_app:s0 u0_a29 3707 2471 com.android.exchange
|
- SPI 장치를 접근하는 JNI를 통해 데이터를 읽어오는 앱을 위한 정책의 경우 아래와 같이 수정한다.
- 일단 앱을 실행시켜 AVC denial 로그를 확인한다.
~$ adb shell su -c dmesg | grep denied
<38>[ 322.415652] [6: logd.auditd: 2406] [c6] type=1400 audit(1491383781.160:3): avc: denied { read write } for pid=4529 comm="Thread-158" name="spidev1.0" dev="tmpfs" ino=7687 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
<38>[ 322.438108] [6: logd.auditd: 2406] [c6] type=1400 audit(1491383781.160:4): avc: denied { open } for pid=4529 comm="Thread-158" path="/dev/spidev1.0" dev="tmpfs" ino=7687 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
<38>[ 322.460911] [6: logd.auditd: 2406] [c6] type=1400 audit(1491383781.160:5): avc: denied { ioctl } for pid=4529 comm="Thread-158" path="/dev/spidev1.0" dev="tmpfs" ino=7687 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
|
로그를 보면 Thread-158 에서 /dev/spidev1.0 장치에 read, write, open, ioctl을 수행하다 실패했다. 아래 정보를 확인하고 정책소스를 수정시 참고한다.
source context: untrusted_app (프로세스 레이블)
target context: device (타겟 오브젝트 레이블)
target class: chr_file (오브젝트 클래스)
2. file_contex에 spidev레이블을 myspi_dev로 설정한다.
/dev/spidev1.0 u:object_r:myspi_device:s0
|
- external/sepolicy/domain.te를 보면 device:chr_file을 막았으므로, device말고 새로운 레이블이 필요하다.
everallow { domain -unconfineddomain -ueventd -recovery } device:chr_file { open read write };
3. 아래 경로에 타겟보드의 myspi_device를 위한 정책소스를 추가한다.
device/vendor//board/sepolicy/myspidevice.te
type myspi_device, dev_type;
allow untrusted_app myspi_device:chr_file rw_file_perms;
|
- external/sepolicy/global_macros 에서 rw_file_perms에 read/write/ioctl 이 포함되도록 정의 되어 있다.
define(`r_file_perms', `{ getattr open read ioctl lock }')
define(`w_file_perms', `{ open append write }')
define(`rx_file_perms', `{ r_file_perms x_file_perms }')
4.myspidevice.te가 빌드시 포함되도록 device/vendor/board/BoardConfig.mk를 수정한다.
BOARD_SEPOLICY_UNION +=
…
myspidevice.te
|
5. adb shell su -c dmesg | grep denied 명령으로 정책이 잘 적용되었는 지 확인한다. 잘 적용이 되었다면 아무 메시지가 나오지 않는다.
good job
답글삭제