Skip to content

Open an installed manager directly, and survive an unshare without --propagation - #1005

Open
hhhbwc wants to merge 1 commit into
JingMatrix:masterfrom
hhhbwc:manager-entry-and-daemon-startup-fallbacks
Open

hhhbwc wants to merge 1 commit into
JingMatrix:masterfrom
hhhbwc:manager-entry-and-daemon-startup-fallbacks

Conversation

@hhhbwc

@hhhbwc hhhbwc commented Oct 12, 2026

Copy link
Copy Markdown

What

Two robustness fixes in the Magisk module scripts, both for environments that are not a conventional phone. Each keeps today's behaviour as the first choice and only falls back when the environment cannot support it.

zygisk/module/action.sh — prefer the installed manager

The action button currently only knows the injection path: hand the intent to ${INJECTED_PACKAGE_NAME} and let the Zygisk-injected manager answer it. That needs the shell process to host a 2D activity and to receive the injected manager dex. Neither is guaranteed everywhere: some systems never let the shell host an activity at all, and dynamic code loading restrictions can block the dex (#805 fixed one such case on GrapheneOS). Where the injection path cannot work, the action button is a dead end — even though manager.apk ships inside the module and #809 added a standalone install for exactly this situation.

When the manager has been installed as a regular package, launch its activity directly instead. If it has not, the injection path runs unchanged.

zygisk/module/service.sh — start the daemon where unshare is poorer

unshare --propagation slave -m is GNU util-linux syntax. Android ships toybox, and toybox builds that implement only a subset of util-linux reject the flag outright:

$ unshare --propagation slave -m true
unshare: Unknown option propagation

The daemon then never starts, and nothing says so: service.sh has no error path, and the failure only shows up as every Xposed module silently doing nothing. Probe the flag with a throwaway true and fall back to unshare -m, then to running the daemon without a namespace. The full invocation still runs first wherever it is supported.

Testing

Verified on a PICO 4 (Android 10) VR headset, where unshare --propagation is rejected and the shell cannot host the manager:

  • unshare --propagation slave -m true exits 1 with Unknown option propagation; unshare -m true exits 0. Killed vectord, ran the new service.sh, and the daemon came back (VectorDaemon: Successfully injected Vector IPC binder for applications).
  • With manager.apk installed from the module, the action opens org.matrix.vector.manager/.ui.MainActivity directly (force-stopped the manager, ran the action, the process returned). Without the package installed, the injection path still runs.

Notes

…orer

action.sh: the injection path needs ${INJECTED_PACKAGE_NAME} to host a 2D
activity and to receive the injected manager dex, neither of which holds in
every environment. When the manager has been installed as a regular package
-- manager.apk ships inside the module for exactly that -- launch its
activity directly and leave the injection path as the fallback.

service.sh: "unshare --propagation slave -m" is GNU util-linux syntax;
toybox builds that implement only a subset reject the flag outright, which
leaves the daemon dead with nothing anywhere to say so. Probe the flag with
a throwaway command and fall back to "unshare -m", then to running the
daemon without a namespace at all.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant