Following the example given in this post, I added these lines to /init.rc:
on property:dev.bootcomplete=1
start boot_handler
service boot_handler /system/bin/bc_handler.sh
class main
user root
group root
disabled
oneshot
And this /system/bin/bc_handler.sh:
#!/system/bin/sh
echo hi > /data/local/hi.txt
I'm building Android 8.0 for the emulator. When the system starts, I can see that the script didn't run, and this message is seen in the logs:
[ 217.280853] init: service boot_handler does not have a SELinux domain defined
I tried changing my service to look like this:
service boot_handler /system/bin/sh /system/bin/bc_handler.sh
class main
user root
group root
disabled
oneshot
seclabel u:r:shell:s0
and now the error is
init: Service 'boot_handler' (pid 1729) killed by signal 1
Is there any documentation on how one adds a new service to Android under SELinux? Or documentation on how to disable SELinux on Android? I've been googling for hours, and all of the information I'm finding seems to be obsolete.
You can disable SELinux by setting permissive mode on your running platform
In permissive mode, selinux will only dump warning message
By default, it's in enforcing mode, where any SELinux violation will be denied.
To add a service, you should add file context in file_context, and write a .te file for your service
Here is a basic example and you can dig into more about SELinux
Related
I am getting my android's logcat spammed with these warnings.(rooted with magisk)
10-15 22:02:29.039 12944 12944 W kworker/0:4: type=1400 audit(0.0:87190): avc: denied { read write } for name="sde73" dev="tmpfs" ino=28978 scontext=u:r:kernel:s0 tcontext=u:object_r:oem_device:s0 tclass=blk_file permissive=0
I was looking into the following doc to see how could i fix this issue, but cannot figure it out.
https://source.android.com/security/selinux/device-policy
https://source.android.com/security/selinux/validate
https://source.android.com/security/selinux/concepts
https://source.android.com/security/selinux/implement
https://gist.github.com/msfjarvis/ec52b48eb2df1688b7cbe32bcd39ee5f
https://android.stackexchange.com/questions/207484/how-to-fix-selinux-avc-denied-errors-when-launching-dnscrypt-as-init-d-script
https://source.android.com/security/selinux/customize#android-o
https://android.stackexchange.com/questions/218911/how-to-add-selinux-policy-on-a-user-debug-rom-that-has-split-policy-scheme
https://android.stackexchange.com/questions/214839/how-to-run-an-android-init-service-with-superuser-selinux-context
https://topjohnwu.github.io/Magisk/tools.html#magiskpolicy
https://topjohnwu.github.io/Magisk/details.html#magisk-booting-process
https://topjohnwu.github.io/Magisk/guides.html#boot-scripts
I looked in /dev, but i do not have anything similar.
android# ls -l /dev/ | grep sd
#returns nothing
The inode resolves to this file:
find /sys -xdev -inum 28978
/sys/firmware/devicetree/base/__symbols__/sb_7_tx
However on next reboot resolves to other file but the errors are always related to one single inode.
I suppose i should add this rule in a .te file
allow kernel oem_device:blk_file {read write};
adb pull /sys/fs/selinux/policy
adb logcat -b all -d | audit2allow -p policy
#this confirms the rule
I found some related files to selinux in this dump:
https://git.rip/dumps/oneplus/oneplus7tpro/-/find_file/hotdog-user-10-QKQ1.190716.003-2009281542-release-keys
but i am not very sure where should i add the rule..possibly somewhere in /vendor/etc/selinux..
Does anyone know which are the steps to fix these warnings and maybe further dig into the investigation why they occur in the first place?
Thanks
The reason why it shows is straightforward from the error. kernel is trying to read/write a blk_file labeled with oem_device type.
At this point you have couple of options:
Add allow rule if you want to allow the access to happen.
Add dontaudit rule, if you want to just suppres the log. See
here
The rule should be added into kernel.te.
Usually these custom things go into device/XXXXXX, depending on the vendor. For example in my tree, for a rockchip device, I'd modify /device/rockchip/common/sepolicy/vendor/kernel.te
To rebuild policies you would:
source build/envsetup.sh
lunch-yourTarget
mmm system/sepolicy
And to flash them into the system ( if you're userdebug and can remount it ):
adb root
adb remount
adb push out/target/product/YOUR_DEVICE/vendor/etc/selinux /vendor/etc/
adb push out/target/product/YOUR_DEVICE/system/etc/selinux /system/etc/
adb shell sync
adb reboot
If you can't push them, you'll need to rebuild and flash the system
I managed to fix the warnings with this command:
magiskpolicy --live 'allow kernel oem_device blk_file {read write open}'
'open' right was also granted because another warning related to it would appear after allowing only read/write.
Still I cannot understand:
why is kernel trying to access this
what exactly is trying to access
shouldn't magisk take care of the selinux policies related to such low level grants such as kernel
not sure how can i make this fix permanent (to persist upon reboot). From my research it looks like i have to modify a certain file in boot.img, repack it and push it back to android.
On this page:
https://topjohnwu.github.io/Magisk/tools.html
it's specified a tool magiskboot which should be used for such patching but I do not have it.
A tool to unpack / repack boot images, parse / patch / extract cpio, patch dtb, hex patch binaries, and compress / decompress files with multiple algorithms.
I will come back with any findings..
UPDATE:
I managed to permanently add the fixes at boottime with a post-fs-data script that runs during booting process. It might not be 100% fix because, the boot image should be patched instead so that magiskinit loads the policies even before init is executed, but it still however fixes the warnings in logcat after the boot process ended
REF:
https://topjohnwu.github.io/Magisk/details.html#magisk-booting-process
https://topjohnwu.github.io/Magisk/guides.html#boot-scripts
su -
cd /data/adb/post-fs-data.d
touch fix_selinux.sh
chmod +x fix_selinux.sh
vi fix_selinux.sh #add this line (and any other rules you need):
/sbin/magiskpolicy --live 'allow kernel oem_device blk_file {read write open}'
I am trying to add a native service written in C++ to the AOSP build.
The first thing I did was to create a native service and client to the AOSP build.
This worked as expected. I could start the service within an adb shell and call it via binder on a adb shell.
The trouble started when I wanted to start my service with init.
I added a .rc file to my build
service myp /system/bin/myp_service
class main
This did the the trick so that init tried to start it but it failed because of SELinux policies.
So I added a file_contexts to my device tree and added:
/system/bin/myp_service u:object_r:myp_exec:s0
Next I added a myp.te file and added:
type myp, domain;
type myp_exec, exec_type, file_type;
type myp_service, service_manager_type;
init_daemon_domain(myp)
net_domain(myp)
binder_use(myp)
binder_service(myp)
add_service(myp, myp_service)
binder_call(myp, binderservicedomain)
binder_call(myp, appdomain)
allow myp myp_service:service_manager add;
And finally I added a service_contexts file with:
myp u:object_r:myp_service:s0
This finally made my service successfully start at boot time.
Unfortunalty I cannot use binder against this service. When I try to connect to the service with my client the call
defaultServiceManager()->getService(String16("Demo"))
returns a null pointer.
I cannot find any hints in the dmesg.
So I assume I am still missing something for the SElinux but I have no clue what I am missing.
If I shutdown the SELinux with setenforce and restart the service then it works fine.
Can anyone give me a hint what I am missing for SELinux or where I can get more information about which policy blocked something?
You could see the denials like this:
adb logcat | grep "SELinux : avc" > /tmp/logs
Get sepolicy current file. (Can be taken from device this way adb pull sepolicy.
Using audit2allow (located in AOSP source code: external/selinux/prebuilts/bin/audit2allow or in SDK tools. Do this: cat /tmp/logs | .external/selinux/prebuilts/bin/audit2allow -p sepolicy
The audit2allow tool will tell you what permission you are missing for the logcat extracted and the current sepolicy file, watch-out because you could need to do this several times since fixing some permissions will show the next ones required.
If you have a userdebug kind of build you could get setenforce 0, logcat with it and all the denials will be in logcat even if you will be permited to do the operation desired. This will leave the audit2allow iterations required in 1.
For anyone who came across this problem, please make sure your service_contexts file is successfully merged with stock service_contexts file. If you're building your service for Android O or later, please put this file inside a folder and refer to it in your Makefile by BOARD_PLAT_PRIVATE_SEPOLICY_DIR1. And you don't need to add allow myp default_android_service:service_manager add if the build system does pick up your service_contexts.
Also, about the domain.te violation problem, you probably want to attach one of the coredomain or appdomain attribute to your domain 2 with typeattribute <your_domain> <attribute>;.
Finally, please double check the following built files to make sure you don't leave any sepolicy configurations out in the final build:
$(AOSP_ROOT)/out/target/product//obj/ETC/file_contexts.bin_intermediates/file_contexts.*
$(AOSP_ROOT)/out/target/product/potter/obj/ETC/plat_service_contexts_intermediates/service_contexts.*
$(AOSP_ROOT)/out/target/product/potter/obj/ETC/sepolicy_neverallows_intermediates/policy.conf
After playing around with the latest build of CM for my device (12.1), I decided to try and build my first ROM. So I got Linux, synced sources for 13, etc. (My device tree is here.)
I had to grapple with a few audio-related build errors before I finally got it to build. (If it makes any difference, all the commits I had to revert were related to PCM audio offloading.)
Now, when I try to boot the ROM, it immediately reboots to recovery without even displaying the boot animation. Looking at /proc/last_kmsg, the problem seems to be about SELinux:
...
[ 4.340084] init: (Initializing SELinux enforcing took 0.51s.)
[ 4.349071] type=1400 audit(1468237723.015:4): avc: denied { fowner } for pid=1 comm="init" capability=3 scontext=u:r:kernel:s0 tcontext=u:r:kernel:s0 tclass=capability permissive=0
[ 4.349387] init: SELinux: Could not set context for /init: Operation not permitted
[ 4.349506] init: restorecon failed: Operation not permitted
[ 4.349699] init: Security failure; rebooting into recovery mode...
[ 4.350353] SysRq : Emergency Remount R/O (triggered by init:1)
[ 4.350581] Emergency Remount complete
[ 4.350889] reboot - triggered with task: init (1:1)
...
I'm not familiar with SELinux apart from the fact that it makes system modifications a lot harder, but from what I've seen, both the device-specific and general init.te files in the Android source allow init to use the fowner capability.
I've tried:
Modifying the sepolicy file by making the init domain permissive
Rebuilding the entire ROM with permissive init; in init.te
Commenting out restorecon /adb_keys and restorecon_recursive /mnt in init.rc
Rebuilding the device kernel with EXTRA_CFLAGS += -DCONFIG_ALWAYS_ENFORCE=true
Searching for a solution on Google - a person on XDA had the exact same problem as me but subsequent posts from him/her did not yield any progress or solutions on the matter
None of them made any difference, so basically, I'm fresh out of ideas.
What am I doing wrong?
I am currently trying to insmod a kernel module during the end of the boot process, and so I've created the following entries in init.rc:
on post_late_start
start myscript
on nonencrypted
class_start late_start
trigger post_late_start
on property:void.decrypt=trigger_restart_framework
class_start main
class_start late_start
trigger post_late_start
service myscript /data/my_sh.sh
disabled
oneshot
Then in my /data directory my_sh.sh has the following:
#!/system/bin/sh
log -t mytag -p V "Hello World!"
insmod mymodule.ko mod_parameter=arg
But when I run -- sometimes I do not see the "Hello World" tag when I logcat -s "mytag" and of course, the insmodded module is not installed either.
What is the proper way of late-inserting a kernel module (it needs to go in after network is up and /data is mounted). And further -- how do I get the output of insmod into the log so that I can debug? Any help is appreciated and I can post more details if necessary.
At least since Froyo and still in Lollipop, Android init implements insmod in system/core/init/buildin.c. It is supposed to work directly in an init*.rc file:
on boot
insmod /system/lib/modules/your-module.ko.
However, at least in Lollipop 5.1, it no longer works, as SELinux rules are enforced. init does not have the required sys_module permission. Therefore the underlying init_module system call returns EPERM. This is never reported to anywhere. The only symptom is that insmod commands now fail to load the module, always.
I opened an AOSP issue on this. According to Google, this works as intended. If you want to use kernel modules when SELinux is enforced (which they strongly advice against), you must yourself add the required SELinux permission to init.
I am not sure about your log, but to insmod you need to give the exact path to the module, because I dont think you will be having mymodule.ko residing in the same place as init.rc is there. So try to give the full path of your ko file.
Generally it resides in /lib/modules/youdrivername.ko
so check it here first.
Sometimes I see the following logcat output such as that below:
<3>[ 283.152845] init: untracked pid 4217 exited
<3>[ 283.162185] init: untracked pid 4078 exited
<3>[ 283.173691] init: untracked pid 1504 exited
<3>[ 283.177018] init: untracked pid 1468 exited
What is the meaning of the log of init: untracked pid xxxx exited?
use logcat and read the huge log carefully. You might find the program that crashes all the time.
There may be many different reasons, one of them is that android init trying to
initialize services specified by init.rc failed.
You can try to bisect the services started from init.rc first, and once you find
the errornous service, then try to fix the specific service start up errors, which
may be the kernel driver error, or android hal driver error, library fault, or
sometimes android framework error.
Technically, this message (modern version of which is "Untracked pid XXX exited with status YY") means that Android init sees a child process exit (that is, receives SIGCHLD signal and then gets its pid with waitpid()), but it can't associate that process with any of configured services (see this question on Android init service configuration).
This in turn opens up a question of what can daemonize itself in Android environment and how to find it. But I don't think that I can answer that, the only suggestion that I have is getting root access and checking processes.