Android insmod kernel object on boot - android

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.

Related

How to solve this valgrind issue?

I'm trying to run valgrind on an android OS but it couldn't start and it shows this errors that i couldn't find how to solve:
valgrind: Startup or configuration error:
Can't create client cmdline file in /tmp/valgrind_proc_87_cmdline_876a7612
valgrind: Unable to start up properly. Giving up.
Thanks in advance !
I tried to change the default path that valgrind use and which is shown on the error log but i couldn't make it
The problem is happening in the code where the Valgrind host is creating a fake /proc/<pid>/cmdline.
This file should be created in the location given by the first valid item in the following list:
The TMPDIR environment variable
The constant VG_TMPDIR that gets baked into the binary via a configure time option. This defaults to /tmp but can be overriden using configure --with-tmpdir=/your/tmp/dir. That would require that you get the Valgrind source and configure and build it. It is possible that you are using a package that was built using this option and is not compatible with your system.
Last resort, "/tmp"
All of the above checks just test that the string is non-null and not empty. They do not test for the existance and accessibility of the directory. That gets determined by the Valgrind version of mkstemp and the error message comes from 'valgrind_main'.
Valgrind needs to create a file TMPDIR/valgrind_proc_PID_cmdline_RAND where TMPDIR is described above, PID is the pid of the Valgrind process and RAND is a random number.
There is at least one other similar files that get created, for auxv.
There are no Valgrind command line options to turn off the creation of these files.

Android Port bootloop due to non updatable apex or boringssl checks

I am building LineageOS 18.1 for tecno kd7. I have system, system_ext, product & vendor paritions. The rom port I built is having a boot loop.
Here is the last_kmsg
What is causing the boot loop?
I am suspecting these lines
[ 1.802608] (0)[354:apexd]apexd: This device does not support updatable APEX. Exiting
[ 2.352523] (0)[1:init]reboot: Restarting system with command 'boringssl-self-check-failed'
I just need direction on what I need to what is causing the phone to bootloop
I also faced the same issue. The boringssl-self-test binary is using incorrect libcrypto.so library.
You can run the boringssl-self-test with strace and check for the issue.
In file : external/boringssl/selftest/boringssl_self_test.rc
service boringssl_self_test64_vendor /system/bin/strace -tt /vendor/bin/boringssl_self_test64
setenv BORINGSSL_SELF_TEST_CREATE_FLAG true # Any nonempty value counts as true
#reboot_on_failure reboot,boringssl-self-check-failed
stdio_to_kmsg
seclabel u:r:vendor_boringssl_self_test:s0

Android's Logcat spammed with selinux avc denials on tmpfs, type 1400 by kworker/kernel

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}'

Add native service to aosp

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

executing static program from android init.rc

I want to start a custom program in the init process. I compiled this program statically that run fine from my booted up android stock ROM.
From the android init.rc docs I read that the exec command is what I need.
BTW all I can see in dmesg is that my program exit with code -1 (I can't return that).
init.rc snippet:
on post-fs-data
write /dev/kmsg "launching test"
exec /data/test
All I see in dmesg is this:
<4>[ 6.336816] launching test
<6>[ 6.336902] init: command 'write' r=0
<6>[ 6.337115] init: command 'exec' r=-1
Here you are the executable source code: http://pastebin.com/Hym1APWx
UPDATE
I tried to statically compile and run this program:
int main(){return 0; }
But the result is always command 'exec' r=-1. Maybe user uselen are right, maybe I cannot run executables from /data in the early-boot phase.
As christian said, it looks like exec isn't even implemented. I'm beginning to think that a lot of features documented for init.rc aren't implemented. Here's a way you can get your program to launch however.
Instead of running this as an "exec" command, set this up as a service instead.
In your init.rc, or another file included by it:
service my_service /data/test
class main
oneshot
If it's in class main, and not disabled, it should run after /data is mounted.
I had the same issue today. In my case the solution was simple: The exec function wasn't implemented yet and contained just a return -1. You should take a look at builtin.c and search for do_exec(). This code is executed when init.rc contains an exec statement.

Categories

Resources