Android 使用安全增強型 Linux (SELinux) 對所有程序強制執行強制訪問控制 (MAC),其中包括以 Root/超級使用者許可權執行的程序(Linux 功能)。
工作模式
寬容模式 - 僅記錄但不強制執行 SELinux 安全政策。
強制模式 - 強制執行並記錄安全政策。如果失敗,則顯示為 EPERM 錯誤。
可以透過getenfoce來獲取當前工作模式:
還可以透過setenforce 0來設定當前模式為Permissive:
也可以透過setenforce 1來設定當前模式為Enforcing:
SELinux安全上下文
SELinux 管理過程中,程序是否可以正確地訪問檔案資源,取決於它們的安全上下文。程序和檔案都有自己的安全上下文,SELinux 會為程序和檔案新增安全資訊標籤,安全上下文的格式為:user:role:type:sensitivity[:categories],通常可以忽略上下文的 user、role 和 sensitivity 欄位。當執行 SELinux 後,所有這些資訊都將作為訪問控制的依據。
1、檢視檔案和目錄的安全上下文,執行命令如下:
1|console:/ # ls -Z
u:object_r:cgroup:s0 acct u:object_r:tmpfs:s0 mnt
u:object_r:apex_mnt_dir:s0 apex u:object_r:vendor_file:s0 odm
u:object_r:rootfs:s0 bin u:object_r:vendor_file:s0 odm_dlkm
u:object_r:rootfs:s0 bugreports u:object_r:oemfs:s0 oem
u:object_r:cache_file:s0 cache u:object_r:postinstall_mnt_dir:s0 postinstall
u:object_r:configfs:s0 config u:object_r:proc:s0 proc
u:object_r:rootfs:s0 d u:object_r:system_file:s0 product
u:object_r:system_data_root_file:s0 data u:object_r:rootfs:s0 sdcard
u:object_r:mirror_data_file:s0 data_mirror u:object_r:tmpfs:s0 second_stage_resources
u:object_r:tmpfs:s0 debug_ramdisk u:object_r:mnt_user_file:s0 storage
u:object_r:device:s0 dev u:object_r:sysfs:s0 sys
u:object_r:rootfs:s0 etc u:object_r:system_file:s0 system
u:object_r:init_exec:s0 init u:object_r:system_dlkm_file:s0 system_dlkm
u:object_r:rootfs:s0 init.environ.rc u:object_r:system_file:s0 system_ext
u:object_r:linkerconfig_file:s0 linkerconfig u:object_r:vendor_file:s0 vendor
u:object_r:metadata_file:s0 metadata u:object_r:vendor_file:s0
2、檢視程序的安全上下文,執行命令如下
console:/ # ps -Z -e |grep smartdevice
u:r:mt_platform_app:s0 system 1512 384 1232712 75756 do_epoll_wait 0 S com.smartdevice.global.service
u:r:system_app:s0 system 2081 384 1330484 186356 do_epoll_wait 0 S com.smartdevice.dailyshortcut
u:r:system_app:s0 system 2123 384 1193112 55872 do_epoll_wait 0 S com.smartdevice.leanbacklauncher.customizer
u:r:system_app:s0 system 3157 384 1302756 119640 do_epoll_wait 0 S com.smartdevice.dtv.icast
u:r:untrusted_app_32:s0:c54,c256,c512,c768 u0_a54 3186 384 1883096 63176 do_epoll_wait 0 S com.smartdevice.tv.aircast
u:r:mt_platform_app:s0 system 4268 384 1230384 94636 do_epoll_wait 0 S com.smartdevice.factory
u:r:system_app:s0 system 8659 384 1195700 57920 do_epoll_wait 0 S com.smartdevice.bleconnectservice
u:r:system_app:s0 system 11512 384 1262884 129512 do_epoll_wait 0 S com.smartdevice.ipcontrol
程序SContext的type欄位代表該程序所屬的Domain。
3、檢視屬性的安全上下文,執行命令如下:
console:/mnt/vendor # getprop -Z persist.sys.locale
u:object_r:locale_prop:s0
安全策略
SELinux安全機制又稱為是基於TE(Type Enforcement)策略的安全機制。所有安全策略都存放在.te結尾的檔案中,一般放在 /system/sepolicy/private/,廠商定製的一般放在/device/xxx/sepolicy/下。
語句格式為:
allow source target:class permissions;
//source - 規則主題的型別(或屬性),即程序的組,也就是程序的domain。
//目標 - 物件的型別(或屬性),即程序所要操作的檔案的type。
//類 - 要訪問的物件(例如,檔案、套接字)的型別,system/sepolicy/private/security_classes中有class的定義,常見的有file,dir等。
//許可權 - 要執行的操作(或一組操作,例如讀取、寫入),常見的有read , write, ioctrol, create, getattr, getattr等。
示例:
allow system_app vendor_configs_file:file { read getattr open };
get_prop(system_app, vendor_default_prop) 其實是一個宏,展開如下:
allow system_app vendor_default_prop:file r_file_perms;
錯誤修改
常見錯誤
出現違反SELinux安全策略的錯誤時一般會有如下log輸出:
type=1400 audit(0.0:16187): avc: denied { read getattr open } for name="vendor" dev="tmpfs" ino=2 scontext=u:r:system_app:s0 tcontext=u:object_r:vendor_configs_file:s0 tclass=file permissive=0
按照規則 allow scontex tcontex:tclass action 來改即可:
allow system_app vendor_configs_file:file { read getattr open };
違反規則的同時又neverallow問題修改
Google 在system/sepolicy中有使用相關neverallow 規則, 對SELinux Policy 的更新進行了限制, 以防止開發者過度開放許可權,從而引發安全問題。並且透過CTS Test 檢測開發者是否有違反相關的規則.
如:
type=1400 audit(0.0:2928): avc: denied { search } for name="vendor" dev="tmpfs" ino=2 scontext=u:r:system_app:s0 tcontext=u:object_r:mnt_vendor_file:s0 tclass=dir permissive=0
按照之前規則配置:
allow system_app mnt_vendor_file:dir { search };
編譯出現報錯:
FAILED: out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy
out/host/linux-x86/bin/secilc -m -M true -G -c 30 out/soong/.intermediates/system/sepolicy/recovery_sepolicy.cil/android_common/recovery_sepolicy.cil -o out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy_policy -f /dev/null && cp -f out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy_policy out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy && rm -f out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy_policy # hash of input list: 187605db6ee3f7580bafd9adbd0101d2c2a0d02f423bb7efa74ee537c43d35ce
neverallow check failed at out/soong/.intermediates/system/sepolicy/recovery_sepolicy.cil/android_common/recovery_sepolicy.cil:11171 from system/sepolicy/public/domain.te:1233
(neverallow base_typeattr_281 mnt_vendor_file (dir (ioctl read write create getattr setattr lock relabelfrom relabelto append map unlink link rename execute quotaon mounton audit_access open execmod watch watch_mount watch_sb watch_with_perm watch_reads add_name remove_name reparent search rmdir)))
<root>
allow at out/soong/.intermediates/system/sepolicy/recovery_sepolicy.cil/android_common/recovery_sepolicy.cil:33799
(allow system_app mnt_vendor_file (dir (search)))
Failed to generate binary
Failed to build policydb
透過檢視system/sepolicy/public/domain.te:
# Platform must not have access to /mnt/vendor.
neverallow {
coredomain
-init
-ueventd
-vold
-system_writes_mnt_vendor_violators
} mnt_vendor_file:dir *;
domain.te檔案中,明確domain中是沒有對mnt_vendor_file的讀寫許可權。
方法一:將 system_app 新增到上述neverallow的domain例外中,但後續可能會有cts問題,不建議使用。
方法二:將要操作的檔案定義為其他type,然後允許system_app來讀寫這個新type的檔案。
1、file.te新增mt_config_file SELinux type:
type mt_config_file, file_type;
2、繫結檔案到SELinux type, file_contexts檔案新增:
/mnt/vendor/config(/.*)? u:object_r:mt_config_file:s0
//這個含義代表/mnt/vendor/config下所有的檔案或者目錄的標籤都是mt_config_file,
//如果在mnt/vendor/config的子目錄下,建立一個目錄或者檔案,並不給它打標籤的話,那麼這個新建立的檔案或者目錄會和父目錄的標籤一致
3、申請許可權:
allow system_app mt_config_file:dir search;
4、發現還是無法訪問,再修改許可權域,seapp_contexts新建許可權域:
user=system seinfo=platform name=pkgNmae domain=mt_platform_app type=mt_tvapk_app_data_file
5、最後新建mt_platform_app.te,申請許可權:
allow mt_platform_app mt_config_file:dir search;
自定義Prop 錯誤
在mk中增加Prop,
PRODUCT_PRODUCT_PROPERTIES += \
ro.vendor.firmware.version=1.0.0
透過SystemProperties去獲取時發現出現Access denied finding property "ro.vendor.firmware.version"問題。
對於vendor下property許可權,類似file許可權
1、attributes.te定義type:
attribute mtk_core_property_type;
2、在property.te 中新增:
vendor_public_prop(vendor_fw_version_prop)
typeattribute vendor_fw_version_prop mtk_core_property_type;
3、在property_contexts中新增:
ro.vendor.firmware.version u:object_r:vendor_fw_version_prop:s0
4、system_app.te新增許可權
allow system_app vendor_fw_version_prop:file { map getattr open };
get_prop(system_app, vendor_fw_version_prop)