KernelSU icon indicating copy to clipboard operation
KernelSU copied to clipboard

overlay.d support

Open Pierre2324 opened this issue 2 years ago • 27 comments

Issue Hi, I'm a custom android kernel developer and I've been using Magisk in the past with its MAGISKTMP functionality. With magisk, when kernel is flashed the content of ramdisk/overlay.d gets extracted to MAGISKTMP (/sbin on older android and a randomly named folder in /dev for newer android versions). Every .rc files in there is also appended to ROM's init to run on boot.

Feature Request Would it be possible to mimic Magisk's overlay.d with kernelsu?

Alternatives I've tried pushing files in anykernel/modules to /data/adb/modules with do.systemless=1 and do.modules=1 and removing the magisk check in update-binary so that ak3-helper gets created but that didn't work

I've also tried pushing files manually using terminal commands like cp to copy files from the anykernel to /data/adb/modules manually but that didn't work neither

Pierre2324 avatar Jul 03 '23 02:07 Pierre2324

I'm not very familiar with Magisk's overlay.d mechanism, nor do I know its use cases; KernelSU only modifies the kernel and does not touch the ramdisk, so I think it would be quite troublesome to support this feature.

However, I will keep this issue open, in case someone is willing to provide a PR for it.

Also, I wanted to ask, can't the module's post-fs-data satisfy the requirements?

tiann avatar Jul 03 '23 03:07 tiann

Also, I wanted to ask, can't the module's post-fs-data satisfy the requirements?

overlay.d is usually used for init.rc modifications

HuskyDG avatar Jul 03 '23 08:07 HuskyDG

What things can be done in init.rc but not in post-fs-data?

tiann avatar Jul 03 '23 09:07 tiann

Kernel modules loading (depends on which modules, and which device; some work fine in post-fs-data), and other features that can require on init and early init for setup.

osm0sis avatar Jul 03 '23 09:07 osm0sis

I'm not very familiar with Magisk's overlay.d mechanism, nor do I know its use cases; KernelSU only modifies the kernel and does not touch the ramdisk, so I think it would be quite troublesome to support this feature.

However, I will keep this issue open, in case someone is willing to provide a PR for it.

Also, I wanted to ask, can't the module's post-fs-data satisfy the requirements?

I actually wanted to push files from my anykernel zip to /data/adb/modules (doesn't have to be ramdisk).

That would prevent users to having to flash a separate module after flashing my kernel and on my side doing a separate module for every device I maintain since those files are already in anykernel so I thought it would be better to be able to push them to /data/adb/modules directly.

Things like spectrum profiles, bootup tweaks (init.xxx.rc) and .sh scripts so they are ran on boot and available there when I change profiles in my app using /data/adb/modules when the user is using kernelsu instead of magisktmp path.

I guess post-fs-data would work for that part, but having the possibility from anykernel to push files to a place like /data/adb/modules directly without having magisk requirements would be beneficial.

But if the use of flashing a separate module.zip in kernelsu app is required to push the same files that are already used in my kernel.zip when magisk is there, then I'll make one.

Sorry if I'm not clear on what I need, hope it's not too bad.

Pierre2324 avatar Jul 03 '23 13:07 Pierre2324

I'll look into expanding the checks in AK3 to allow KernelSU for the helper module, but it sounded like you were saying the module wasn't created for KernelSU when you push those files manually. And if that's the case then I'm not sure what's missing, since it works fine with Magisk.

osm0sis avatar Jul 03 '23 13:07 osm0sis

I'll look into expanding the checks in AK3 to allow KernelSU for the helper module, but it sounded like you were saying the module wasn't created for KernelSU when you push those files manually. And if that's the case then I'm not sure what's missing, since it works fine with Magisk.

What I did: -Add files to a folder named modules in anykernel -Made sure do.systemless and do.modules were set to 1 in anykernel.sh -Commented out the check for magisk (because magisk isn't there) in update-binary do_modules() function so it can create a kernel helper module in /data/adb/modules anyway.

But nothing was created.

Pierre2324 avatar Jul 03 '23 17:07 Pierre2324

What I did: -Add files to a folder named modules in anykernel -Made sure do.systemless and do.modules were set to 1 in anykernel.sh -Commented out the check for magisk (because magisk isn't there) in update-binary do_modules() function so it can create a kernel helper module in /data/adb/modules anyway.

But nothing was created.

Okay, well that's an AK3 thing probably. Without a log I can't be sure, but if you correctly commented out the check then the files should get created.

Let's address that in the AK3 xda thread so we don't derail this overlay.d feature request thread (which is still a good request for parity of a powerful feature, if possible) any further.

osm0sis avatar Jul 03 '23 18:07 osm0sis

Commented out the check for magisk (because magisk isn't there) in update-binary do_modules() function so it can create a kernel helper module in /data/adb/modules anyway.

In KernelSU, /data/adb/modules is a mount point, where an ext4 image will be mounted after the Android system starts up, and the original content of this directory will be covered (overlayfs cannot directly use the /data partition). Therefore, if you are operating this directory in recovery, you will not be able to see it after entering the Android system. You can try to use /data/adb/ksu module install <ZIP> to install the module; but please note: KernelSU has never supported installing modules in Recovery, and this behavior may change in the future.

tiann avatar Jul 04 '23 05:07 tiann

Ahah! So there is something different.. Pierre didn't have any other modules installed so the mount point thing wasn't obvious.

I used to support SuperSU in the su.img days and Magisk in the magisk.img/magisk_merge.img days, and still do in my other projects, so I'll take a look at something similar so KernelSU can have recovery support in AK3 too once I update the checks.

Then that'll just leave overlay.d as the difference support-wise. 👍

osm0sis avatar Jul 04 '23 14:07 osm0sis

What things can be done in init.rc but not in post-fs-data?

Actually, init mechanism of android is a great way to launch your own services with "right" users and selinux contexts and perform watchdog monitoring on them.

Avbroot allows for a mechanism to "cook" such init modifications using Magisk's init injection mechanisms and it is very comfy

https://github.com/chenxiaolong/avbroot/issues/90

I've just used the above described methodology to add an automatically monitored dnscrypt and Cloak services to my magisk-rooted phone, it is much more comfortable than alternatives for launching persistent services and relaunching them when they crash (dnscrypt tends to misbehave for me occasionally)

I do love the idea of kernelsu very much though (especially the root profile / app profile approach) and would love to see init.rc injection implemented in kernelsu EDIT it appears something like that already exists in kernelsu ?!

nad0vs avatar Jul 23 '23 00:07 nad0vs

hey @Pierre2324 would this kind of thing https://kernelsu.org/guide/hidden-features.html allow to do what you want to do by using a custom initrc ?

(I have not tested this and the wording is slightly ambiguous as to whether it is supposed to load ksurc as a custom android init.rc and also whether it appends records to the init.rc or replaces it wholesale)

nad0vs avatar Jul 23 '23 00:07 nad0vs

hey @Pierre2324 would this kind of thing https://kernelsu.org/guide/hidden-features.html allow to do what you want to do by using a custom initrc ?

(I have not tested this and the wording is slightly ambiguous as to whether it is supposed to load ksurc as a custom android init.rc and also whether it appends records to the init.rc or replaces it wholesale)

Hmm interesting, ambiguous but seems like it would run it just like any other init file 🤔

Pierre2324 avatar Jul 23 '23 01:07 Pierre2324

The fact that /data/adb/ksu/.ksurc is in /data means it is run at least after post-fs-data, whereas overlay.d can be whole init.rc files, .sh and binaries, with triggers running I believe by at least early-init, since it seems to concatenate any .rc files to init.rc pre-init.

https://topjohnwu.github.io/Magisk/guides.html#root-directory-overlay-system

osm0sis avatar Jul 23 '23 02:07 osm0sis

Maybe we can make a modified version of magiskinit that can only load custom init.rc and without magisk 🤔

HuskyDG avatar Jul 23 '23 06:07 HuskyDG

Presumably the kernel has access to rootfs pre-init and should be able to do all the overlay.d stuff before executing init, so no ramdisk hacking necessary.

osm0sis avatar Jul 23 '23 10:07 osm0sis

well, yeah @osm0sis is right the thing does not look like it is injecting into init.rc a-la what magisk overlay is doing. Is there any hope to see init.rc injection in a future version of kernelsu, @tiann ?

I'm growing addicted to how nice things are going with custom services for me, but otherwise want too migrate to kernelsu

nad0vs avatar Jul 23 '23 22:07 nad0vs

Upon some barely literate prodding and searching on my part, it would appear that KernelSU already does an .rc file injection through atrace.rc

https://github.com/tiann/KernelSU/blob/978178afc0928cac179e8f23a3407f9d27ab1f01/kernel/ksud.c#L255

So only a mechanism for a user to provide additional user.rc to concatenate to the injected stuff would need to be invented and implemented to make it happen

nad0vs avatar Jul 23 '23 23:07 nad0vs

KernelSU does inject init.rc at the kernel level, but that's just a small piece of code (less than 1024 in length), and there's a lot more work to be done if you want to inject an arbitrary rc:

  1. where to put this rc file? /data is definitely not an option, maybe directly in the /boot partition? I'm not sure.
  2. we need to intercept a series of system calls to make init think that the rc file exists; this is a lot of work in different kernel versions.

Personally, I wouldn't add this feature because it's more complicated to implement than you think, and I don't have a need for it.

I think @HuskyDG 's approach is more pragmatic and feasible. There is no need to implement everything in the kernel, and it can be implemented as simple as possible.

tiann avatar Jul 24 '23 09:07 tiann

Probably somewhere that could be mounted pre-init that doesn't require decryption would be the other option to hold the KSU overlay.d files, similar to Magisk's PREINITDEVICE location for sepolicy rules files, etc. So like /metadata, /persist or /cache.

Patching boot/init_boot ramdisk would of course work, and be cross-compatible with Magisk's implementation. I wonder if the overlay.d function could be handled by the kernel itself after the ramdisk is unpacked, instead of needing to hijack/replace the init binary. If so then that'd be pretty brilliant, and arguably a bit cleaner than Magisk's.

osm0sis avatar Jul 24 '23 11:07 osm0sis

PREINITDEVICE is for sepolicy.rule on Android but in KernelSU, i think it is unnecessary

HuskyDG avatar Jul 24 '23 12:07 HuskyDG

For overlay.d, reading custom .rc script and appending to init.rc could be easy in kernel, but we also need to mount tmpfs on random directory inside /dev to store files from overlay.d/sbin which is used for custom init.rc.

HuskyDG avatar Jul 24 '23 12:07 HuskyDG

For overlay.d, reading custom .rc script and appending to init.rc could be easy in kernel, but we also need to mount tmpfs on random directory inside /dev to store files from overlay.d/sbin which is used for custom init.rc.

why can't that be implemented (when necessary, e.g. I don't even need the overlay.d/sbin part, just custom init services ;-) I only need init's feature as a "built in unstoppable watchdog" ) in a custom service itself?

e.g.

kernelsu would implement two features

  1. custom init.rc injector (which could be basically an option during install specifying path to custom .rc file the contents of which would be appended to the init injection Kernelsu already does) and
  2. "folder to ramdisk" which is basically an option to take a specified folder and add it wholesale to ramdisk, available to root and init via appropriate selinux context/labels and not much anyone else.

If these files need to be moved/mounted to some path inside /dev or something like that, a service with proper powers can be specified in the injected init.rc and triggered to run via appropriately early init trigger. But it's up to the person making the custom early service to write that service / script etc.

Am I significantly underestimating the gnarliness of android early filesystem / service manipulation?

nad0vs avatar Jul 31 '23 21:07 nad0vs

  • where to put this rc file? /data is definitely not an option, maybe directly in the /boot partition? I'm not sure.

@tiann is there something about android boot process and/or AVB and/or some later consideration (tricking SafetyNet?) that precludes one from placing the "user.rc to be injected" and additional tooling (overlay.d folder with a handful of binaries) into generic ramdisk (the one that got moved to init_boot separate image in 13-native devices if memory serves)?

nad0vs avatar Jul 31 '23 21:07 nad0vs

  • where to put this rc file? /data is definitely not an option, maybe directly in the /boot partition? I'm not sure.

@tiann is there something about android boot process and/or AVB and/or some later consideration (tricking SafetyNet?) that precludes one from placing the "user.rc to be injected" and additional tooling (overlay.d folder with a handful of binaries) into generic ramdisk (the one that got moved to init_boot separate image in 13-native devices if memory serves)?

AVB will verify boot / init_boot, whether you change it to kernel or ramdisk, but this is not a problem for us.

tiann avatar Aug 01 '23 02:08 tiann

I think using init service is a bad idea, because any app can find out all running or stopped services by getprop | grep init.svc, random name is also useless, because only one reboot of the device will do it Find the service whose name has changed.

KernelSU deliberately did not use service but directly used exec. Magisk's former daemon used service as a daemon to run, but it also adopted this method later.

If you just want a watchdog, there are many other options, such as: https://github.com/ochinchina/supervisord

tiann avatar Aug 01 '23 02:08 tiann

@tiann Upon some thought I don't think that if it is user configurable (at installation/preparation time) that apps detecting an anomalous service with name like "myservcustom2" is a huge detection risk, people who want to carefully pass as mainstream ROM to all apps (presumably for safetynet/banking apps/gaming shenanigans) probably don't have "persistently run modified shadowsocks daemon" as their hugest concern. Supervisord is a good idea tho. Seems pretty robust so maybe launching it from a script as root and having it "take over from there" is a better idea than homebrewing monster init services. Still monster init services are a nice option using a powerful built-in android mechanism ;-)

nad0vs avatar Dec 12 '23 12:12 nad0vs

closed since no developers are willing to add support, if anyone sees this issue, please feel free to PR

tiann avatar Jan 31 '24 05:01 tiann

Just looking here and it seems no developers are willing to add support ( I have small knowledge so I can't ).

With Magisk I can inject init.rc file

on charger
  reboot

Is it possible to do like this while in KernelSU ?

Thankyou.

anasfanani avatar Jun 08 '24 23:06 anasfanani