Commit Graph

157 Commits

Author SHA1 Message Date
topjohnwu
5f1174de27 Introduce new boot flow to handle SAR 2SI
The existing method for handling legacy SAR is:
1. Mount /sbin tmpfs overlay
2. Dump all patched/new files into /sbin
3. Magic mount root dir and re-exec patched stock init

With Android 11 removing the /sbin folder, it is quite obvious that
things completely break down right in step 1.

To overcome this issue, we have to find a way to swap out the init
binary AFTER we re-exec stock init. This is where 2SI comes to rescue!

2SI normal boot procedure is:
1st stage -> Load sepolicy -> 2nd stage -> boot continue...

2SI Magisk boot procedure is:
MagiskInit 1st stage -> Stock 1st stage -> MagiskInit 2nd Stage ->
-> Stock init load sepolicy -> Stock 2nd stage -> boot continue...

As you can see, the trick is to make stock 1st stage init re-exec back
into MagiskInit so we can do our setup. This is possible by manipulating
some ramdisk files on initramfs based 2SI devices (old ass non SAR
devices AND super modern devices like Pixel 3/4), but not possible
on device that are stuck using legacy SAR (device that are not that
modern but not too old, like Pixel 1/2. Fucking Google logic!!)

This commit introduces a new way to intercept stock init re-exec flow:
ptrace init with forked tracer, monitor PTRACE_EVENT_EXEC, then swap
out the init file with bind mounts right before execv returns!

Going through this flow however will lose some necessary backup files,
so some bookkeeping has to be done by making the tracer hold these
files in memory and act as a daemon. 2nd stage MagiskInit will ack the
daemon to release these files at the correct time.

It just works™  ¯\_(ツ)_/¯
2020-04-01 04:39:28 -07:00
topjohnwu
a0998009c1 Small native code reorganization 2020-03-09 01:50:30 -07:00
topjohnwu
0d229dac3b Support Android 11 SELinux paths
This is NOT proper Android 11 support
2020-02-21 00:49:33 -08:00
topjohnwu
84e4bd3d41 Move readlinkat fix into xwrap 2020-02-03 13:24:02 +08:00
topjohnwu
af060b3132 General QoL changes 2019-12-13 00:37:06 -05:00
topjohnwu
11b7076a43 Fix broken getxattr calls 2019-12-05 17:34:50 -05:00
topjohnwu
8cc5f096a2 Some minor changes 2019-12-05 17:20:32 -05:00
topjohnwu
34bb18448c Fix compile errors 2019-11-23 17:18:55 -05:00
topjohnwu
01253f050a Use smart pointers 2019-11-23 04:57:52 -05:00
topjohnwu
5bee1c56a9 Properly use RAII to reduce complication 2019-11-22 03:01:49 -05:00
topjohnwu
bffdedddb4 Fix fwrite/fread params 2019-11-21 17:43:31 -05:00
topjohnwu
d3b5cf82d8 Small adjustments 2019-11-21 06:17:28 -05:00
topjohnwu
d26d804cc2 Migrate to generic stream implementation 2019-11-21 06:08:02 -05:00
topjohnwu
4f9a25ee89 Create generic streams on top of stdio
WIP
2019-11-20 21:48:49 -05:00
topjohnwu
bb9ce0e897 Make sepolicy dump more efficient 2019-11-20 03:47:15 -05:00
topjohnwu
9aff1a57d3 Cleanup headers 2019-11-19 02:04:47 -05:00
topjohnwu
7681fde4d0 Record mounts to be cleaned up in a vector 2019-11-19 00:16:20 -05:00
topjohnwu
d952cc2327 Properly solve the connection problem 2019-11-07 17:41:59 -05:00
topjohnwu
8277896ca1 Make sure uninstall.sh is executed on remove 2019-11-01 03:07:12 -04:00
topjohnwu
75306f658f Revert "Drop API 17 (Android 4.2) support"
Turns out that we cannot use AndroidKeystore anyways, so we don't
actually need to drop API 17. Revert this change.
2019-10-20 07:13:03 -04:00
topjohnwu
9c27d691dd Drop API 17 (Android 4.2) support 2019-10-19 03:11:54 -04:00
topjohnwu
e0927cd763 Add support to patch QCDT
Old Qualcomn devices have their own special QC table of DTB to
store device trees. Since patching fstab is now mandatory on Android 10,
and for older devices all early mount devices have to be included into
the fstab in DTBs, patching QCDT is crucial for rooting Android 10
on legacy devices.

Close #1876 (Thanks for getting me aware of this issue!)
2019-10-07 00:38:02 -04:00
topjohnwu
64113a69b4 Remove unused warnings 2019-09-26 13:54:40 -04:00
topjohnwu
947dae4900 Rename classes and small adjustments 2019-09-25 23:55:39 -04:00
topjohnwu
f109038d12 Hardcode shell uid to 2000 2019-09-13 03:14:58 -04:00
topjohnwu
7ba8202af5 Introduce new root overlay system 2019-07-16 01:08:28 -07:00
topjohnwu
d7b691cf59 Move libutil internal headers out of include path 2019-07-14 23:55:52 -07:00
topjohnwu
52fd508fea Do not use std::random_device
Directly read from urandom instead of using std::random_device.
libc++ will use iostream under-the-hood, which brings significant
binary size increase that is not welcomed, especially in magiskinit.
2019-07-14 21:56:21 -07:00
topjohnwu
41045b62dc Introduce more randomness
- Use C++ random generator instead of old and broken rand()
- Randomize string length to piss off stupid detectors
2019-07-14 17:42:49 -07:00
topjohnwu
a92e039363 Split util headers 2019-07-01 22:58:19 -07:00
topjohnwu
ff3710de66 Minor code changes across all sources 2019-06-30 19:09:31 -07:00
topjohnwu
e29b712108 Start Magisk in SAR 2019-06-25 23:31:59 -07:00
topjohnwu
a1a1ac0bbb Add sbin overlay to system-as-root 2019-06-24 01:21:33 -07:00
topjohnwu
28cd6a75e7 Add missing functions in bionic 2019-06-23 14:54:48 -07:00
topjohnwu
4cc7aced15 Add new util function 2019-06-23 03:53:41 -07:00
topjohnwu
5d357bc41f Remove unused function 2019-05-26 22:01:42 -07:00
topjohnwu
23d3e56967 Add new util function 2019-05-25 21:42:51 -07:00
topjohnwu
003e44fb84 Remove requirement to use early-init daemon
We used to construct /sbin tmpfs overlay in early-init stage after
SELinux is properly initialized. However the way it is implemented
(forking daemon from magiskinit with complicated file waiting triggers)
is extremely complicated and error prone.

This commit moves the construction of the sbin overlay to pre-init
stage. The catch is that since SELinux is not present at that point,
proper selabel has to be reconstructed afterwards. Some additional
SEPolicy rules are added to make sure init can access magisk binaries,
and the secontext relabeling task is assigned to the main Magisk daemon.
2019-04-24 00:13:48 -04:00
topjohnwu
24f5bc98d8 Add boot_complete trigger back
Samsung does not like running cmd before system services are started.
Instead of failing, it will enter an infinite wait on binder.
Move APK installation to boot complete to make sure pm can be run
without blocking process.
2019-04-05 07:00:30 -04:00
topjohnwu
0149b1368d Several improvements 2019-03-31 06:32:33 -04:00
topjohnwu
f0240b1f06 Support Android Q new split sepolicy setup 2019-03-15 06:17:37 -04:00
topjohnwu
da0a72e8b0 Improve builtin selinux implementation 2019-03-14 06:34:22 -04:00
topjohnwu
f24a5dfd45 More efficient xml parsing 2019-03-09 04:27:04 -05:00
topjohnwu
c345633d80 Fix build error
Close #1182
2019-03-08 01:01:42 -05:00
topjohnwu
d2cb638fcd Use our own function to parse int 2019-03-07 20:31:35 -05:00
topjohnwu
04ef1e6405 Make parse prop file a util function 2019-03-05 20:27:09 -05:00
topjohnwu
dee3c3e7ba Workaround seccomp on MagiskBoot
Close #1150
2019-03-02 05:46:15 -05:00
topjohnwu
d8cd2031c7 SIGSTOP any possible process ASAP
Shut down any UID matching process and resume if it turns out not to
be our target. Since we will record every single process we have ever
paused, this means that the same process will not be paused erroneously
for another time.

This is an optimization to hijack the app as soon as possible.
2019-03-02 04:24:41 -05:00
topjohnwu
b1afd554fc Application Component Granularity MagiskHide
Before switching to the new MagiskHide implementation (APK inotify),
logcat parsing provides us lots of information to target a process.
We were targeting components so that apps with multi-processes
can still be hidden properly.

After switching to the new implementation, our granularity is limited
to the UID of the process. This is especially dangerous since Android
allow apps signed with the same signature to share UIDs, and many system
apps utilize this for elevated permissions for some services.

This commit introduces process name matching. We could not blanketly
target an UID, so the workaround is to verify its process name before
unmounting.

The tricky thing is that any app developer is allowed to name the
process of its component to whatever they want; there is no 'one
rule to catch them all' to target a specific package. As a result,
Magisk Manager is updated to scan through all components of all apps,
and show different processes of the same app, each as a separate
hide target in the list.

The hide target database also has to be updated accordingly.
Each hide target is now a <package name, process name> pair. The
magiskhide CLI and Magisk Manager is updated to support this new
target format.
2019-03-01 17:08:08 -05:00
topjohnwu
e72c6685ed Support A only System-as-root Devices
Most Chinese devices (and supposedly Galaxy S10) running Android Pie
is using system-as-root without A/B partition.

https://source.android.com/devices/bootloader/system-as-root#about-system-as-root

According to the docs above, these devices will have a ramdisk block
with size 0 in their boot images. Since magiskinit can run independently
on system-as-root devices, we simply just create an empty ramdisk with
magiskinit added as init.

Huge thanks to @vvb2060 for the heads up and original PR.
Close #980, close #1102
2019-02-28 05:46:36 -05:00