{"record":{"id":"4c60b726411d39c6","repo":"MuntashirAkon/AppManager","slug":"current-su-does-not-allow-binder-communication","errorCode":null,"errorMessage":"Current su does not allow Binder communication.","messagePattern":"Current su does not allow Binder communication\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"server/src/main/java/io/github/muntashirakon/AppManager/server/RootServiceMain.java","lineNumber":154,"sourceCode":"    }\n\n    private final int uid;\n    private final boolean isDaemon;\n\n    @Override\n    public Object[] call() {\n        Object[] objs = new Object[2];\n        objs[0] = uid;\n        objs[1] = isDaemon;\n        return objs;\n    }\n\n    @SuppressLint(\"DiscouragedPrivateApi\")\n    public RootServiceMain(String[] args) throws Exception {\n        super(null);\n\n        if (Process.myUid() == 0 && !allowBinderCommunication()) {\n            throw new IOException(\"Current su does not allow Binder communication.\");\n        }\n\n        ComponentName name = ComponentName.unflattenFromString(args[0]);\n        uid = Integer.parseInt(args[1]);\n        String action = args[2];\n        boolean stop = false;\n\n        switch (action) {\n            case CMDLINE_STOP_SERVICE:\n                stop = true;\n                // fallthrough\n            case CMDLINE_START_DAEMON:\n                isDaemon = true;\n                break;\n            case CMDLINE_START_SERVICE:\n                isDaemon = false;\n                break;\n            default:","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/server/src/main/java/io/github/muntashirakon/AppManager/server/RootServiceMain.java#L136-L172","documentation":"RootServiceMain runs as root (uid 0) and needs Binder IPC to talk back to the app. Some su implementations run root shells in isolated contexts where seapp/domain policy blocks Binder; if Process.myUid()==0 and allowBinderCommunication() (a selinux context check) fails, the constructor throws IOException('Current su does not allow Binder communication.') because the root service could never communicate with the client process.","triggerScenarios":"Starting the root service under a su that runs it in an SELinux domain/context without binder access — e.g. Magisk su with restrictive context, KernelSU, or vendor su variants — when Process.myUid()==0 and allowBinderCommunication() returns false; also when args[0] (component) is launched from an unsuitable context.","commonSituations":"Devices with unusual SELinux policies or non-Magisk su implementations; running the server from a shell context (u:r:magisk:s0 variants lacking binder) instead of the expected domain; custom ROMs with hardened sepolicy; KernelSU or partially rooted setups.","solutions":["Use a su implementation that grants Binder access to its root context (Magisk is the reference; update it to latest).","Check the resulting SELinux context with `su -c id -Z`; if it lacks binder perms, adjust the sepolicy/domain or use `su -mm` / mount-namespace options that permit binder.","On custom ROMs, add/patch a sepolicy rule allowing the su domain's binder uses, or launch the service through a supported mechanism (e.g. AppManager's own root request path).","Verify with a simple `su -c 'service list'` whether Binder works at all under the device's root before assuming an app bug."],"exampleFix":"// before (device shell)\nsu -c 'sh /path/to/start_server.sh'\n// after (force a magisk context that allows binder / mount master namespace)\nsu -mm -c 'sh /path/to/start_server.sh'\n","handlingStrategy":"validation","validationCode":"// on device, before launching the root service:\nString ctx = runSuCommand(\"id -Z\");\nif (ctx == null || !ctx.contains(\"magisk\")) { // expected binder-capable domain\n    throw new UnsupportedOperationException(\"su context \" + ctx + \" does not allow Binder; use Magisk su\");\n}\n","typeGuard":null,"tryCatchPattern":"try {\n    new RootServiceMain(args);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Binder\")) {\n        // fall back to non-Binder mode (adb/shell API surface) or show setup instructions\n    }\n}\n","preventionTips":["Standardize on Magisk (latest) as the root provider; test `su -c 'service list'` during device provisioning.","Check `id -Z` under su before starting Binder-dependent services.","Provide a non-Binder fallback path for rooted devices with hardened sepolicy.","Document required SELinux domains in setup docs for custom-ROM users."],"tags":["binder","selinux","root","android"],"backgroundTag":"unsupported-platform","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}