레이블이 SE for Android인 게시물을 표시합니다. 모든 게시물 표시
레이블이 SE for Android인 게시물을 표시합니다. 모든 게시물 표시

2017년 4월 5일 수요일

SE for Android

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를 통해 데이터를 읽어오는 앱을 위한 정책의 경우 아래와 같이 수정한다.
  1. 일단 앱을 실행시켜 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  명령으로 정책이 잘 적용되었는 지 확인한다. 잘 적용이 되었다면 아무 메시지가 나오지 않는다.