B07b: Inspect SELinux Actions During Runtime
SELinux error messages are rate-limited after boot complete to avoid swamping the logs.
To make sure you see all the relevant messages you can disable this by running:
adb shell auditctl -r 0
https://source.android.com/docs/security/features/selinux/validate
logcat | grep avc adb shell su root dmesg | grep 'avc: '
Info
AVC stands for Access Vector Cache in SELinux context. It contains cached decisions to increase performance by not re-evaluating the policy rules for every call.
Note
If the output of the above command is empty, restart your device. When your device runs without activity for a long time, there are no SELinux errors.
# Switch adb to root powers adb root # Switch to permissive mode adb shell setenforce 0 # Get current mode adb shell getenforce # Use audit2allow adb pull /sys/fs/selinux/policy adb logcat -b events -d | audit2allow -p policy # To use audit2allow you may have to install it first: apt install policycoreutils-python-utils
SELinux and Native Service
In case you attempted the optional step 5 of the native service exercise, you may have encountered this error message:
Control message: Could not ctl.start for 'demo_service' from pid: 2592 (start demo_service): File /system/bin/demo(labeled "u:object_r:system_file:s0") has incorrect label or no domain transition from u:r:init:s0 to another SELinux domain defined. Have you configured your service correctly? https://source.android.com/security/selinux/device-policy#label_new_services_and_address_denials. Note: this error shows up even in permissive mode in order to make auditing denials possible.
As the error message suggests, setenforce 0 will not save us here. So let's add some rules to allow the service to run with SELinux in enforcing mode. Add or alter the following files in this directory: device/google/cuttlefish/shared/sepolicy/system_ext/private
demo.te contains the rules for our service:
type demo_service_server, domain; type demo_service_server_exec, system_file_type, exec_type, file_type; # Service on system partition: typeattribute demo_service_server coredomain; init_daemon_domain(demo_service_server) # Allow it to add itself as the system service: add_service(demo_service_server, demo_service); # Register the system service with the service manager: type demo_service, app_api_service, ephemeral_app_api_service, service_manager_type; # Allow it to be a binder service: binder_use(demo_service_server) binder_service(demo_service_server)
file_contexts tells SELinux which context the executable we install for our service belongs to. Add the following line to the already existing file:
/system_ext/bin/demo u:object_r:demo_service_server_exec:s0
And service_contexts maps the service name our demo service provides to a context. Add the following line to the already existing file:
demoservice u:object_r:demo_service:s0
If you have not added it previously in the optional Step 5 of the native service exercise, also add the line PRODUCT_PACKAGES += demo demo-client.
If you have not attempted Step 5, here is a demo.rc init file for our service:
service demo_service /system_ext/bin/demo
interface aidl demoservice
class main
user root
And to include it in the build, add the line init_rc: [ "demo.rc" ], in the cc_binary section for the demo executable in Android.bp
Then rebuild the system images and reboot. The demo service should now be started automatically and you can use demo-client hello without having to start it manually.