B07b: Inspect SELinux Actions During Runtime

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.