본문 바로가기

Programming/Android

Neverallow 관련 sepolicy 처리 방법

[출처] : https://ehxm.wordpress.com/2017/04/20/neverallow-%EA%B4%80%EB%A0%A8-sepolicy-%EC%B2%98%EB%A6%AC-%EB%B0%A9%EB%B2%95/


Neverallow 관련 sepolicy 처리 방법

Android selinux의 neverallow와 관련된 sepolicy 처리 방법

아래와 같은 selinux denial log가 발생하면, enforce mode에서 해당 동작시 권한이 없으므로 해당 operation은 거부된다. 그러므로 이에 맞는 알맞은 sepolicy를 추가해야 한다.

1
avc:  denied  { set } for property=com.casper.dvr.init pid=179 uid=0 gid=0 scontext=u:r:dvr_service:s0 tcontext=u:object_r:default_prop:s0 tclass=property_service permissive=1

해당 denial log에 대한 알맞은 sepolicy를 설정하여 필요한 operation에 대한 권한을 줘야 하고, 아래와 같이 audit2allow 유틸을 사용하면 필요 sepolicy를 생성해 주므로, 이를 참조하면 된다.

1
2
adb shell "dmesg | grep audit" > audit_0413.txt
audit2allow -i audit_0413.txt -o audit_0413.te -p out/target/product/<project>/root/sepolicy

Android에서는 보안을 위해 특정 권한에 대해서는 지정된 object에 대해서만 허용하는 neverallow rule이 있고, 이를 CTS test시 check를 한다. neverallow rule을 위배하는 sepolicy에 대해서는 android make시 error를 출력하게 되고,

1
neverallow on line 263 of system/sepolicy/domain.te (or line 8976 of policy.conf) violated by allow casper device:chr_file { read write open };

아래 각각의 예시 case와 같이 올바른 sepolicy를 지정해 주어야 한다. 보통은 광범위한 부분에 대해 neverallow rule이 설정되어 있고 이를 세부적으로 relabeling하여 해당 부분에 대해서만 policy를 적용하는 방식이다.

아래 각각의 예시 case와 같이 올바른 sepolicy를 지정해 주어야 한다. 보통은 광범위한 부분에 대해 neverallow rule이 설정되어 있고 이를 세부적으로 relabeling하여 해당 부분에 대해서만 policy를 적용하는 방식이다.

Property

property를 추가해서 사용하려면 property_context에 property에 대한 label을 지정해서 사용하여야 하고 지정되지 않은 property 사용에 대해서는 아래와 같이 default_prop 관련 denial log 발생.

1
2
3
4
5
avc:  denied  { set } for property=com.casper.dvr.init pid=179 uid=0 gid=0 scontext=u:r:dvr_service:s0 tcontext=u:object_r:default_prop:s0 tclass=property_service permissive=1
 
init: avc:  denied  { set } for property=com.casper.dvr.power pid=535 uid=1000 gid=1000 scontext=u:r:system_server:s0 tcontext=u:object_r:default_prop:s0 tclass=property_service permissive=1
 
...

이를 아래와 같이 default_prop 접근을 allow하는 policy를 만들면 neverallow rule 위배하게 된다.

1
allow dvr_service default_prop:property_service set;

(관련 neverallow rule)

1
2
3
# Require that domains explicitly label unknown properties, and do not allow
# anyone but init to modify unknown properties.
neverallow { domain -init } default_prop:property_service set;

그래서 아래와 같은 방식으로 property에 대한 label를 지정하고, 필요 부분에 대해 그 context에만 allow를 하는 rule을 추가해야 함.

android/device/vendor/device/property.te

1
type casper_dvr_prop, property_type;

android/device/vendor/device/property_contexts.te

1
com.casper.dvr         u:object_r:casper_dvr_prop:s0

android/device/vendor/device/dvr_service.te

1
allow dvr_service casper_dvr_prop:property_service set;

Device

block device

device에 대한 것도 마찬가지로 필요 device file에 대해 labeling하고 사용하여야 하고, 아래 예는, block_device에 대한 denial log이다.

1
type=1400 audit(1491961004.814:18): avc: denied { open } for pid=2263 comm="mount" path="/dev/block/mmcblk1p3" dev="tmpfs" ino=1649 scontext=u:r:system_app:s0 tcontext=u:object_r:block_device:s0 tclass=dir permissive=1

이를 일반 block_device에 allow하는 rule을 추가하면, neverallow rule 위배

1
allow casper block_device:blk_file { open rw_file_perms };

(관련 neverallow rule)

1
2
libsepol.report_failure: neverallow on line 257 of system/sepolicy/domain.te (or line 8970 of policy.conf) violated by allow casper block_device:blk_file { read write open };
libsepol.check_assertions: 1 neverallow failures occurred

아래와 같이 사용하는 세부 device에 대해 label을 적용하고, 해당 context에 allow rule을 추가함.

device/vendor/device/sepolicy/device.te:

1
type casper_sd_device, dev_type;

device/vendor/device/sepolicy/file_contexts:

1
/dev/block/mmcblk1p3 u:object_r:casper_sd_device:s0

device/vendor/device/sepolicy/casper.te:

1
allow casper casper_sd_device:blk_file { read write open };

chr device

device:chr_file denial log

1
2
avc: denied { read write } for pid=892 comm="RootInit" name="spidev1.2" dev="tmpfs" ino=1758 scontext=u:r:casper:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
avc: denied { open } for pid=892 comm="RootInit" path="/dev/spidev1.2" dev="tmpfs" ino=1758 scontext=u:r:dtv_dvb:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1

neverallow 위배

1
allow casper device:chr_file { open read write };

(관련 neverallow rule)

1
2
3
4
5
6
# domain.te
# Don't allow raw read/write/open access to generic devices.
# Rather force a relabel to a more specific type.
# init is exempt from this as there are character devices that only it uses.
# ueventd is exempt from this, as it is managing these devices.
neverallow { domain -init -ueventd } device:chr_file { open read write };

아래와 같이 처리.

device.te

1
type spi_device, dev_type;

file_contexts

1
/dev/spidev[0-9.]*  u:object_r:spi_device:s0

casper.te

1
allow casper spi_device:chr_file { open read write ioctl};

File

debugfs denial log

1
2
type=1400 audit(1234567897.280:8): avc: denied { read } for pid=187 comm="casper" name="devices" dev="debugfs" ino=24 scontext=u:r:casper:s0 tcontext=u:object_r:debugfs:s0 tclass=file permissive=1
avc: denied { getattr } for pid=187 comm="casper" path="/sys/kernel/debug/usb/devices" dev="debugfs" ino=24 scontext=u:r:casper:s0 tcontext=u:object_r:debugfs:s0 tclass=file permissive=1

neverallow rule 위배

1
allow capser debugfs:file { r_file_perms };

(관련 neverallow rule)

1
2
3
4
5
# Do not allow access to the generic debugfs label. This is too broad.
# Instead, if access to part of debugfs is desired, it should have a
# more specific label.
# TODO: fix system_server and dumpstate
neverallow { domain -init -system_server -dumpstate } debugfs:file no_rw_file_perms;

아래와 같이 처리.

file.te

1
type debugfs_devices, fs_type, debugfs_type;

file_contexts

1
/sys/kernel/debug/usb/devices   u:object_r:debugfs_devices:s0

casper.te

1
allow capser debugfs_devices:file { r_file_perms };