1

I am building Android Pie (tag android-9.0.0_r46, branch android-msm-marlin-3.18-pie-qpr2) from source. I am testing on a Pixel XL (marlin). I want to have a custom shell script run automatically when booting is completed while still having the device in SELinux enforcing mode. I figured I'd add a service for that. My knowledge of SELinux is limited though. This is what I did so far:

  • Create dar_script.sh in my AOSP source:
#!/system/bin/sh

echo "TEST" > /dev/kmsg
  • Add a line in device/google/marlin/device-common.mk to have my script copied to initramfs and thereby make it appear in the root filesystem:
PRODUCT_COPY_FILES += \
    dar_script.sh:system/xbin/dar_script.sh
  • Add a line to system/sepolicy/private/file_contexts to give the script the dar_exec SELinux label:
/system/xbin/dar_script.sh u:object_r:dar_exec:s0
  • Create system/sepolicy/private/dar.te:
typeattribute dar coredomain;

init_daemon_domain(dar)
  • Create system/sepolicy/public/dar.te:
type dar, coredomain, domain;
type dar_exec, exec_type, file_type;

# /system/xbin/dar_script.sh is a shell script,
# so it needs to execute /system/bin/sh
allow dar shell_exec:file rx_file_perms;

# Allow writing to /dev/kmsg
allow dar kmsg_device:chr_file { write };
  • Edit system/core/rootdir/init.rc, add:
# Make the service start after boot
on property:sys.boot_completed=1
    ...
    start dar

# Define my service
service dar /system/xbin/dar_script.sh
    class core
    user root
    group root
    oneshot
    seclabel u:object_r:dar_exec:s0
  • Edit system/sepolicy/public/init.te, add:
allow init dar_exec:process transition;
  • Finally (figured by build error messages this needs to be done, don't know why):
cp system/sepolicy/private/dar.te system/sepolicy/prebuilts/api/26.0/private/dar.te
cp system/sepolicy/private/dar.te system/sepolicy/prebuilts/api/27.0/private/dar.te
cp system/sepolicy/private/dar.te system/sepolicy/prebuilts/api/28.0/private/dar.te
cp system/sepolicy/public/dar.te system/sepolicy/prebuilts/api/26.0/public/dar.te
cp system/sepolicy/public/dar.te system/sepolicy/prebuilts/api/27.0/public/dar.te
cp system/sepolicy/public/dar.te system/sepolicy/prebuilts/api/28.0/public/dar.te
cp system/sepolicy/private/file_contexts system/sepolicy/prebuilts/api/26.0/private/file_contexts
cp system/sepolicy/private/file_contexts system/sepolicy/prebuilts/api/27.0/private/file_contexts
cp system/sepolicy/private/file_contexts system/sepolicy/prebuilts/api/28.0/private/file_contexts
cp system/sepolicy/public/init.te system/sepolicy/prebuilts/api/26.0/public/init.te

However, this is what I find in dmsg after building, flashing and booting:

[   31.729946] init: starting service 'dar'...
[   31.754942] type=1400 audit(11289830.540:6): avc: denied { transition } for pid=691 comm="init" path="/system/xbin/dar_script.sh" dev="dm-0" ino=2720 scontext=u:r:init:s0 tcontext=u:object_r:dar_exec:s0 tclass=process permissive=0
[   31.973168] init: Service 'dar' (pid 691) exited with status 127

I already tried using the audit2allow tool as suggested in the AOSP docs, it gave me the following output:

#============= init ==============
allow init dar_exec:process transition;
allow init proc:file setattr;

#============= untrusted_app ==============
allow untrusted_app vnd_qcril_audio_hwservice:hwservice_manager find;

Of which I think only the first statement is relevant to me, the others are caused by unrelated SELinux issues that are already there in the original source. You see that I added the first statement when you look at the steps I described above, it didn't help.

What's going on? What do I need to change? Thank you very much for any help!

Browse other questions tagged or ask your own question.