Commit Graph

68 Commits

Author SHA1 Message Date
topjohnwu ccb55205e6 Fix pre 21 support 2021-02-20 03:38:39 -08:00
topjohnwu 1f4c595cd3 Revert to old `su -c` behavior 2021-01-16 23:59:31 -08:00
topjohnwu d2acd59ea8 Minor code refactoring 2021-01-12 00:07:48 -08:00
topjohnwu eb21c8b42e Code cleanups 2021-01-11 02:19:10 -08:00
topjohnwu f9bde347bc Convert indentation to spaces
The tab war is lost
2020-12-30 22:11:24 -08:00
topjohnwu 797ba4fbf4 Make sure all logging ends with newline 2020-12-02 00:55:22 -08:00
topjohnwu 30e45f863d Remove unnecessary workaround 2020-09-10 01:01:51 -07:00
topjohnwu 434efec860 Use FIFO for su request communication
Fix #3159
2020-09-10 00:38:29 -07:00
vvb2060 e458215f27 Let isolation namespace base on app namespace 2020-08-08 05:21:03 -07:00
topjohnwu 43146b8316 Update su request process
Due to changes in ec3705f2ed, the app can
no longer communicate with the dameon through a socket opened on the
daemon side due to SELinux restrictions. The workaround here is to have
the daemon decide a socket name, send it to the app, have the app create
the socket server, then finally the daemon connects to the app through
the socket.
2020-06-19 03:52:25 -07:00
topjohnwu 1e2f776b83 Move logging.hpp 2020-06-17 01:17:28 -07:00
topjohnwu ec3705f2ed Redesign of MagiskSU's sepolicy model
Introduce new domain `magisk_client` and new file type `magisk_exec`.

Connection to magiskd's always-on socket is restricted to magisk_client
only. Whitelisted process domains can transit to magisk_client through
executing files labelled magisk_exec. The main magisk binary shall be
the only file labelled as magisk_exec throughout the whole system.
All processes thus are no longer allowed to connect to magiskd directly
without going through the proper magisk binary.

Connection failures are silenced from audit logs with dontaudit rules,
so crazy processes which traverse through all unix domain sockets to try
connection can no longer check logcat to know the actual reason behind
EACCES, leaking the denied process policy (which is u:r:magisk:s0).

This also allows us to remove many rules that open up holes in
untrusted_app domains that were used to make remote shell work properly.
Since all processes establishing the remote shell are now restricted to
the magisk_client domain, all these rules are moved to magisk_client.
This makes Magisk require fewer compromises in Android's security model.

Note: as of this commit, requesting new root access via Magisk Manager
will stop working as Magisk Manager can no longer communicate with
magiskd directly. This will be addressed in a future commit that
involves changes in both native and application side.
2020-06-03 23:29:42 -07:00
topjohnwu 2f824f59dc Better logging system
Use C++ magic to strip out debug logs at compile time
2020-06-01 04:15:37 -07:00
topjohnwu ba7cb47383 Make version reporting consistent 2020-03-23 01:17:13 -07:00
topjohnwu a0998009c1 Small native code reorganization 2020-03-09 01:50:30 -07:00
topjohnwu 1542447822 Reuse buffer 2019-11-13 02:36:45 -05:00
vvb2060 817cdf7113 fix multiuser owner_managed mode 2019-11-11 14:12:26 -05:00
topjohnwu d952cc2327 Properly solve the connection problem 2019-11-07 17:41:59 -05:00
topjohnwu 46447f7cfd Proper string buffer size 2019-11-05 01:46:46 -05:00
topjohnwu 25c557248c Use ContentProvider call method for communication
Previously, we use either BroadcastReceivers or Activities to receive
messages from our native daemon, but both have their own downsides.
Some OEMs blocks broadcasts if the app is not running in the background,
regardless of who the caller is. Activities on the other hand, despite
working 100% of the time, will steal the focus of the current foreground
app, even though we are just doing some logging and showing a toast.
In addition, since stubs for hiding Magisk Manager is introduced, our
only communication method is left with the broadcast option, as
only broadcasting allows targeting a specific package name, not a
component name (which will be obfuscated in the case of stubs).

To make sure root requests will work on all devices, Magisk had to do
some experiments every boot to test whether broadcast is deliverable or
not. This makes the whole thing even more complicated then ever.

So lets take a look at another kind of component in Android apps:
ContentProviders. It is a vital part of Android's ecosystem, and as far
as I know no OEMs will block requests to ContentProviders (or else
tons of functionality will break catastrophically). Starting at API 11,
the system supports calling a specific method in ContentProviders,
optionally sending extra data along with the method call. This is
perfect for the native daemon to start a communication with Magisk
Manager. Another cool thing is that we no longer need to know the
component name of the reciever, as ContentProviders identify themselves
with an "authority" name, which in Magisk Manager's case is tied to the
package name. We already have a mechanism to keep track of our current
manager package name, so this works out of the box.

So yay! No more flaky broadcast tests, no more stupid OEMs blocking
broadcasts for some bizzare reasons. This method should in theory
work on almost all devices and situations.
2019-11-04 14:32:28 -05:00
topjohnwu 0f74e89b44 Introduce component agnostic communication
Usually, the communication between native and the app is done via
sending intents to either broadcast or activity. These communication
channels are for launching root requests dialogs, sending root request
notifications (the toast you see when an app gained root access), and
root request logging.

Sending intents by am (activity manager) usually requires specifying
the component name in the format of <pkg>/<class name>. This means parts
of Magisk Manager cannot be randomized or else the native daemon is
unable to know where to send data to the app.

On modern Android (not sure which API is it introduced), it is possible
to send broadcasts to a package, not a specific component. Which
component will receive the intent depends on the intent filter declared
in AndroidManifest.xml. Since we already have a mechanism in native code
to keep track of the package name of Magisk Manager, this makes it
perfect to pass intents to Magisk Manager that have components being
randomly obfuscated (stub APKs).

There are a few caveats though. Although this broadcasting method works
perfectly fine on AOSP and most systems, there are OEMs out there
shipping ROMs blocking broadcasts unexpectedly. In order to make sure
Magisk works in all kinds of scenarios, we run actual tests every boot
to determine which communication method should be used.

We have 3 methods in total, ordered in preference:
1. Broadcasting to a package
2. Broadcasting to a specific component
3. Starting a specific activity component

Method 3 will always work on any device, but the downside is anytime
a communication happens, Magisk Manager will steal foreground focus
regardless of whether UI is drawn. Method 1 is the only way to support
obfuscated stub APKs. The communication test will test method 1 and 2,
and if Magisk Manager is able to receive the messages, it will then
update the daemon configuration to use whichever is preferable. If none
of the broadcasts can be delivered, then the fallback method 3 will be
used.
2019-10-21 13:59:04 -04:00
topjohnwu b763b81f56 Use mutex_guard to lock su_info 2019-09-26 01:49:50 -04:00
topjohnwu 947dae4900 Rename classes and small adjustments 2019-09-25 23:55:39 -04:00
topjohnwu ef1b928532 LD_LIBRARY_PATH patch for apex should not propagate
Fix #1832
2019-09-13 15:22:49 -04:00
topjohnwu 6e46d394b1 Fix su_info cache yet again... 2019-09-13 14:05:28 -04:00
topjohnwu cdb53ca049 Fix su_info cache bug 2019-09-04 11:04:59 -04:00
topjohnwu 51ff724691 Unblock all signals in root shell process
Fix #1563
2019-07-07 12:30:57 -07:00
topjohnwu 291bf93f9d Proper timing 2019-07-07 12:20:47 -07:00
topjohnwu 5fcd629f16 Rearrange su daemon routine 2019-07-07 12:20:19 -07:00
topjohnwu ab90901793 Use C++ smart pointer for caching su_info 2019-07-07 00:31:49 -07:00
topjohnwu ff3710de66 Minor code changes across all sources 2019-06-30 19:09:31 -07:00
topjohnwu 9f8d4e1022 Properly isolate mount namespace 2019-06-04 21:21:27 -07:00
topjohnwu 80cd85b061 Try to use broadcast for su logging and notify
In commit 8d4c407, native Magisk always launches an activity for
communicating with Magisk Manager. While this works extremely well,
since it also workaround stupid OEMs that blocks broadcasts, it has a
problem: launching an activity will claim the focus of the device,
which could be super annoying in some circumstances.

This commit adds a new feature to run a broadcast test on boot complete.
If Magisk Manager successfully receives the broadcast, it will toggle
a setting in magiskd so all future su loggings and notifies will always
use broadcasts instead of launching activities.

Fix #1412
2019-05-13 02:01:10 -07:00
topjohnwu 00a9f18a1e Build with -Wall 2019-04-29 21:26:43 -04:00
topjohnwu 8d4c407201 Directly communicate with Activity
Since Android Q does not allow launching activities from the background
(Services/BroadcastReceivers) and our native process is root, directly
launch activities and use it for communication between native and app.

The target activity is not exported, so non-root apps cannot send an
intent to fool Magisk Manager. This is as safe as the previous
implementation, which uses protected system broadcasts.

This also workaround broadcast limitations in many ROMs (especially
in Chinese ROMs) which blocks the su request dialog if the app is
frozen/force stopped by the system.

Close #1326
2019-04-10 23:35:31 -04:00
topjohnwu d2cb638fcd Use our own function to parse int 2019-03-07 20:31:35 -05:00
topjohnwu 370015a853 Modernize database code (again) 2019-03-06 08:16:12 -05:00
John Wu 54a8a05dae Small adjustments in connect.cpp 2019-02-27 16:44:27 -05:00
vvb2060 0eef4eacd6 Use REBOOT foreground broadcast 2019-02-27 16:44:27 -05:00
topjohnwu ed027ec3ee Refactor build flags 2019-02-12 05:17:02 -05:00
topjohnwu 71ecbb3af3 Clean/refactor includes 2019-02-10 03:57:51 -05:00
vvb2060 2cf33d635d Setuid after read proc 2019-02-01 15:55:29 -05:00
topjohnwu 1c61feb368 Update native su connect broadcast code
Use -p <pkg> for supported platforms
2019-01-26 14:53:49 -05:00
topjohnwu 0be158afa1 Official KitKat support 2018-12-28 16:03:23 +08:00
topjohnwu 523e66294b Simpler su_info caching system 2018-12-26 11:56:49 +08:00
topjohnwu 762b678d24 Prevent any SELinux issues of root shell streams 2018-11-23 21:08:06 -05:00
topjohnwu de0064af47 Fix SIGWINCH never followed
Close #786
2018-11-20 04:40:42 -05:00
topjohnwu 2ab999f4ca Fix bug in DB query wrapper 2018-11-20 02:20:49 -05:00
topjohnwu c9f390d6e0 Abort upon any error occurred 2018-11-20 02:20:49 -05:00
topjohnwu ab5fedda0b Prevent Magisk database race condition
The database should only be accessed by a single process, which is magiskd.
This means 'magisk --sqlite [SQL]' has to be updated to pass the SQL command to the daemon.
In addition, open the database connection with SQLITE_OPEN_FULLMUTEX to support multithread in magiskd.
2018-11-16 03:20:30 -05:00