Plugins without shared UID
This adds a bound service plugins without a shared UID can use.
closes #2654
How it works:
- Plugins can connect to the service
- After connecting, they have to register themselves as a client by providing a Binder for callbacks (and for Termux to watch when the plugin process dies, so resources can be released)
- After that, the plugin can call the other methods of the service
As an alternative to providing a Binder, clients can also specify a bound service Termux will then bind to to call the callback methods. Plugins can use this prevent themselves from getting killed in the background without having to clutter the notification area with another foreground service notification.
Security Model:
- From the Termux side:
- The bound service is protected with a new dangerous permission for plugins, so only apps the user granted the permission can use the service
- All file methods check if the path is in the plugin directory, so no arbitrary file read/write can occur
- The runTask method is additionally secured with the RUN_COMMAND permission
- The service keeps track of which plugin started which task, and plugins can only send signals to their own tasks
- From the plugin side:
- I made a library that abstracts away the lower level communication with the service a bit and adds security checks
- Before connecting to the service, it checks if the signature for the Termux app matches one of the google play, github or fdroid signatures.
- The callback binder checks if the calling app is Termux on the first transaction, and also checks the Termux app signature
- Callback services can be secured with a new signature permission Termux defines. This ties the signature into the Android permission system. After getting called, the plugin also has to verify the signature of the Termux app, to tie the permission to the actual signature. This is done in the callback binder by default.
- I made a library that abstracts away the lower level communication with the service a bit and adds security checks
I tested the security aspects, paths outside the plugin directory are rejected, absolute paths are interpreted with the plugin directory as the root. Limiting runTask to apps that have the RUN_COMMAND permission also works. Plugins refuse to connect to Termux if the signature doesn't match.
Features:
- Each plugin gets a directory with its package name under /data/data/com.termux/files/apps/plugins and some methods to manage it
- Opening files for reading and/or writing
- Creating and listening on socket files
- If the plugin has the RUN_COMMAND permission: A new way to run tasks, using pipes for arbitrarily long input and output
- A way to send signals to the task
- A callback for when the task exits/is killed
The features are deliberately minimal and designed to work with programs in Termux to use the sockets and files.
Client Perspective
- The client checks if the filesystem socket exists and is connectable.
- If not, activate the plugin with
amortermux-ambroadcast and wait until connection succeeds.
- If not, activate the plugin with
- Communicate with the plugin however you want through the socket and files in the plugin dir.
Plugin Perspective
- Plugin is activated through any means, possibly a broadcast by a client package in Termux.
- Plugin connects to the plugin service in Termux.
- Plugin specifies a callback binder: The plugin has to manage not getting killed on its own, likely with a foreground service.
- Plugin specifies callback service: The plugin can specify the binding priority Termux will use to control how likely it it to be killed by Android.
- The plugin can now set up filesystem sockets to listen to and manipulate files in its plugin directory.
- If the plugin also has the
RUN_COMMANDpermission, it can also run commands through the plugin service, with piped std* streams.
Termux Perspective
- Termux acts as a broker between the plugins and client packages.
- It manages the filesystem sockets for the plugin (because you can't pass a filesystem server socket to other apps) and forwards connected clients to the plugin.
- It also provides a new task type for plugins that gets displayed as a task in the UI, with streams forwarded to the plugin, only if the
RUN_COMMANDpermission is held by a plugin. - Care is taken to keep the list of active plugins valid, plugins are removed when the callback binder/service dies, and filesystem sockets are stopped.
Why hasn't this been merged already? @agnostic-apollo isn't even needed.

@agnostic-apollo isn't even needed.
Things specially like this with security issues don't get merged without proper review and testing.
I did review it couple of weeks back and even with a quick look I did, it had quite a few issues, which I need to fix before this can be merged. I also have to push my local changes first, some of which are required by this pull, which I will do in next few days, mostly done with what I had to do, but lot of testing is required due to tonne of changes and some docs updates.
bruh 💀 ig that's my bad on not knowing how PR properly work.
I thought if it's bad, then it just gets rejected.
I thought if it's bad, then it just gets rejected.
This pull request is not bad that it gets rejected/closed. The design should likely work and overall good work by @tareksander, but needs a deeper look. There are just issues that need to be fixed, initial implementations usually do have issues.
Is this still being considered?
It would be very nice to be able to use termux-gui for my scripts without having to switch from F-Droid. Especially since then I wouldn't need to worry about termux-dialog and the termux/termux-api#297 issue anymore.
This is planned to be available in next major app release.
@agnostic-apollo @tareksander is this still happening?
was this fix committed in another PR?
according to https://github.com/termux/termux-gui/issues/4#issuecomment-1635968056 this should fix https://github.com/termux/termux-gui/issues/4
Read my comment above. And no, not merged elsewhere.
There are quite a few other issues, but I do not have time to get into them now, and cannot get distracted with this anyways. Will look into it all after the pre release, this should be there for the main release, I think this design should work, but have to give a deeper look.