In previous implementations, proc_monitor checks whether the mount namespace of an app is actually separated from zygote using a list generated at startup.
However, for some unknown reason, some devices (e.g. Samsung) has multiple zygote servers running in the background.
This means that app processes spawned from the unlisted zygotes are not checked whether the separation is done or not, causing MagiskHide unmount stuffs in the namespace of zygote, and since zygote is the "mother" of all apps, all apps will no longer have root access.
Since I'm not sure of the reason why multiple zygotes exists, so instead of checking the namespace against a list, compare the current namespace against the parent process's namespace.
This will make sure the namespace is NOT the same as the parent process, which is supposed to be the zygote server.
Starting from the next Magisk release, it will no longer prefer the package name com.topjohnwu.magisk over a hidden manager; it will always be aware whether the hidden manager exists, so when a package named com.topjohnwu.magisk is installed alongside with the hidden manager, com.topjohnwu.magisk will not have root access by default.
This will prevent malware from using the package name com.topjohnwu.magisk to gain root access when a user is using a hidden manager.
To support this new behavior, several changes has to be done:
- Never grant com.topjohnwu.magisk in Magisk Manager (if it IS the actual manager, MagiskSU will grant it by default)
- While hidden, remove com.topjohnwu.magisk if exists
- Restore Magisk Manager (unhide) has to be done with root
- Upgrading Magisk Manager should preserve package name (implemented in a949641)
The previous implementation is great if multiple different requesters call su rapidly in a very short period of time, however in the real world this is nearly impossible to happen. This comes with quite a big overhead, since it requires two lists and also an everlasting background thread to constantly maintain the lists.
The new implementation will spawn a collector thread for each cache miss, and the thread will terminate itself once the data is invalidated.
It's not important to check the return value of unlink(2) or even verify
that the file exists. If this code is running, it means the system has
rebooted, and thus the update file, if any, should be removed so that
MagiskManager doesn't keep displaying the same message. We also handle
this before we handle "disable" so that disabled modules don't keep
requesting a reboot to update.