termux-app
termux-app copied to clipboard
[Feature]: Multi-user support
Feature description
Multiuser is still essential for maintaining privacy, as Android 12 has no way to stop apps from seeing what other apps you have installed. I can run Termux on my primary user as the app I'm hiding from has DRM protection that disables features, and Multi-user trips the DRM.
It would also be useful to have separate termux environments.
Additional information
Nix-on-droid also doesn't work. I'll use termius instead.
Duplicate of #2291
as Android 12 has no way to stop apps from seeing what other apps you have installed.
Since android 11, if an app uses targetSdkVersion
30
(Android 11
), it cannot see any other apps that have been installed, other than a few. The app runs in an isolated environment in which /data/data/<package_name>
directories of other apps do not exist in its mount namespace, so it can't fingerprint other apps. The QUERY_ALL_PACKAGES
permission can bypass the visibility though. So best use apps that target latest sdk or don't have QUERY_ALL_PACKAGES
if you want hiding.
https://cs.android.com/android/platform/superproject/+/android-11.0.0_r48:frameworks/base/core/jni/com_android_internal_os_Zygote.cpp;l=1280
https://developer.android.com/about/versions/11/privacy/storage#other-private-dirs
https://developer.android.com/training/basics/intents/package-visibility#package-name
Why are you trying to hide termux?
has DRM protection that disables features...
@rayfoss What feature(s) are you needing that are missing?
There maybe exists a work-around for your use case.
... I'm not trying to hide Termux at all... I just don't use the owner account for anything but... work. 99% of the time i'm in a slave account, even Google Pay works in it.
I used the following app to findout that other work apps CAN see what other apps I have installed, zero permissions needed: https://play.google.com/store/apps/details?id=com.ytheekshana.deviceinfo&hl=en_US&gl=US Even without an API, they could always open a port and conspire to correlate, deanonymize and connect my accounts. The effect is fairly immediate... try installing an app exclusive to India/Japan App and watch Tiktok start showing you Indian content/ad's.
Unfortunately I can't even switch to the owner account and install Termux there, as that might tip my employer know I don't live in the country I'm pretending to be in. I only have apps that are common in the area on that account.
I have installed, zero permissions needed: https://play.google.com/store/apps/details?id=com.ytheekshana.deviceinfo&hl=en_US&gl=US
The app has requested QUERY_ALL_PACKAGES
and its automatically granted.
Lolz, you seem to have a lot of problems ;)
But termux prefix limitation has existed since the start. If you use limited packages, you can compile those packages for your secondary user prefix and termux should work, will of course require removing check in app, I may do that them myself in near future for a refactor required. Or maybe look into hacks mentioned in #2734, since you have the more motivation needed for secondary user support ;)
Does a work profile works for you?
Hi,
Could be a solution a new script for the compilation environment supporting this?
- Compile Termux with a different "name" and "$PREFIX".
- Recompile a list of user selected packages for this "new" Termux.
- Recompile some Termux-plugins (example Termux-GUI) for this new target.
- Add some user files and installation scripts.
- Package all inside one <name.>APK
In this case the new App will be independent of the regular Termux, right? Then this will solve https://github.com/termux/termux-packages/discussions/11253 too. 😉
https://github.com/termux/termux-app#Forking
Make sure to change sharedUserId
. Also I don't know about Termux:GUI forkability.
Hi @agnostic-apollo ,
https://github.com/termux/termux-app#Forking Make sure to change
sharedUserId
. Also I don't know about Termux:GUI forkability.
It seems then that the forking option (create a fork package with a new package name) is a viable solution. Using this technique anyone can create a totally isolated environment. However, I feel this requires to be more user-friendly. Do you think it's a good idea to develop one script to complete all the tasks? So instead of manually execute all steps, execute one command only. One side advantage of this is the option to execute this inside a testing tool to check if all the environment+plugins+packages are compatible with the TermuxConstants
. And then this functionality will be mainstream in the Termux project.
My objective is to "package" custom user Apps (linux binaries+Termux-GUI scripts) inside an APK to use them as standalone Android Apps. I hope you want to support this. Regards.
It seems then that the forking option (create a fork package with a new package name) is a viable solution. Using this technique anyone can create a totally isolated environment. However, I feel this requires to be more user-friendly. Do you think it's a good idea to develop one script to complete all the tasks?
PRs are welcome. For testing purposes such a script might be useful, but I suspect that a real fork would anyways want to customise things like which packages to include in bootstrap, or which addon apps to include, so not sure how helpful it would be for forkers
Real forks would also make other changes to TermuxConstants
, like app name, url changes, etc and would use Android Studio to make changes and not scripts. Changes would also be required in build.gradle
and strings.xml
and other files. And like grimler said, desired packages would also be custom to forker. The desired package manager would also require config. So this would be lot of work to automate. You are free to create a script and see how it goes.
Hi @agnostic-apollo ,
https://github.com/termux/termux-app#Forking Make sure to change
sharedUserId
. Also I don't know about Termux:GUI forkability.It seems then that the forking option (create a fork package with a new package name) is a viable solution. Using this technique anyone can create a totally isolated environment. However, I feel this requires to be more user-friendly. Do you think it's a good idea to develop one script to complete all the tasks? So instead of manually execute all steps, execute one command only. One side advantage of this is the option to execute this inside a testing tool to check if all the environment+plugins+packages are compatible with the
TermuxConstants
. And then this functionality will be mainstream in the Termux project.My objective is to "package" custom user Apps (linux binaries+Termux-GUI scripts) inside an APK to use them as standalone Android Apps. I hope you want to support this. Regards.
For forking Termux:GUI you just need to change the package name, and replace the package name accordingly in the am
calls in the libraries, requiring you to fork them, too. Termux:GUI supports the same Android version range as Termux, but Android 5 will probably not work.
?Any updates about the issue? I have not been able to use termux because of that! Thankz
?Any updates about the issue? I have not been able to use termux because of that! Thankz
@kdrag0n 's NestBox requires Developer Mode and wireless debugging... I couldn't set it up, so it also has similar problems.
For people with rooted devices, it should be possible to mount secondary user private app data directory assigned to termux at /data/data/com.termux
at app init as discussed in https://github.com/termux/termux-app/issues/2168#issuecomment-877621546
I have added support locally to run commands at app init, not sure if I will have time to add in-built support to do mounting before this release, already got too many things. Can at least ignore the secondary user check if prefix is accessible.
No plans for other ways.
Have seen NestBox updates on twitter by @kdrag0n, looks pretty interesting, if termux ever goes away, there is at least some hope if non-root support is maintained by google in future.
Is there any solution to this yet cause I'm also I'm need of it
Next version should have multi user support for termux on secondary user and if users want to install termux on adoptable storage, assuming root access has been granted to termux. Tested on A11 and A13. I still need to finalize this like add docs and add settings toggle, etc.
Secondary User
Adoptable Storage
Next version should have multi user support for termux on secondary user and if users want to install termux on adoptable storage,
@agnostic-apollo Hi, are there any actions builds that allow multi-user? I've tried getting the latest one but it still errors about hardcoded bootstrap prefix
Or is there another way to get multi-user (like recompiling the app manually from source)? I've read there is but theres no good guide on how to modify the source and bootstrap generation scripts to properly support it, I'd appreciate some help
@RealEthanPlayzDev did you try proot? https://www.reddit.com/r/termux/comments/10h2bmn/how_to_run_termux_environment_through_proot_from/
AFAIK agnostic-apollo works in a local fork, so there is no way to try it until it's released.
Haven't pushed changes yet. And it will require root as I said. Compiling app with different prefix won't do much, you would need to recompile all termux packages as well.
did you try proot? https://www.reddit.com/r/termux/comments/10h2bmn/how_to_run_termux_environment_through_proot_from/
@romanovj I don't plan on using Termux from adb, I need the app to run literally on a different uid
Haven't pushed changes yet. And it will require root as I said. Compiling app with different prefix won't do much, you would need to recompile all termux packages as well.
@agnostic-apollo Ah, I didn't catch the root requirement part (I can't root the device in question unfortunately). I think I'll be fine with recompiling the packages and bootstrap
I probably can work mostly from proot-distro (and in fact, 90% of the time I'm inside a archlinux proot, the only times I needed to exit proot was just updating termux packages), so technically all I need is probably ssh and proot-distro on the app, nothing else (not even pkg or apt)
@RealEthanPlayzDev what's the difference? just start fail safe session and run script in order to proot into termux environment
ofc you will need to change some lines
also, you can proot into anything, just unpack rootfs and write your own script
all you need is to patch proot binary with patchelf, and couple of libraries like here (I used this files in order to proot into homeassistant docker container from adb shell)
what's the difference? just start fail safe session and run script in order to proot into termux environment
@romanovj
/data/data/com.android.shell
isn't accessible unless you're on adb, and I'm not fond with Android's internal structuring
@RealEthanPlayzDev ofc you need to change path to whatever you have
@romanovj
I've tried following that Reddit post's instructions along with changing the paths it needs, currently I'm stuck here:
I've confirmed that
libandroid-support.so
does indeed exist within usr/lib
I believe talking about this here would be off-topic, do you have Discord perhaps?
@agnostic-apollo what do you think about hexpatching? /data/data/com.termux to /data/local/tmp/termu or /data/user/10/com.ter
I tried with /data/local/tmp/termu for adb and had no major problems. It's definitely easier than recompiling everything
Check https://github.com/termux/termux-app/issues/2734 for more generic solution for secondary users. It might be doable, but the prefix may also be used in other non binary files or in scripts and without the full /data/data/com.termux/files/*
paths.
I have a dumb idea about this issue. (I edited this message before being aware of #2734)
-TERMUX_BASE_DIR="/data/data/${TERMUX_APP_PACKAGE}/files"
-TERMUX_CACHE_DIR="/data/data/${TERMUX_APP_PACKAGE}/cache"
+TERMUX_BASE_DIR="/data/user/0/${TERMUX_APP_PACKAGE}/files/21473"
+TERMUX_CACHE_DIR="/data/user/0/${TERMUX_APP_PACKAGE}/cache"
TERMUX_ANDROID_HOME="${TERMUX_BASE_DIR}/home"
TERMUX_APPS_DIR="${TERMUX_BASE_DIR}/apps"
TERMUX_PREFIX="${TERMUX_BASE_DIR}/usr"
When in bootstrap
or apt
install, after unpacking/decompressing files, the unpacked files can be binary-patched, replacing /data/user/0/com.termux/files/21473
with actual userId
, like /data/user/10/com.termux/files/2147
.
Because binary-patch does not tolerate string length changes, ~~21474~~ 21473
is meant for reserving some more bytes for actual userId
which could be longer than 1-byte (like 0
).
However it might not be trivial to handle cases like encoded/compressed text, or the string itself is in some multi-byte non-ASCII encoding. (ah there could be other situations like checksummed files etc, as mentioned in #2734)
As for what 21473
means, it's the maximum allowed userId
, in other words, the (currently) longest possible userId
.
I looked up Android source code and then found that Android OS defined MAX_USER_ID
as:
// We need to keep process uid within Integer.MAX_VALUE.
@VisibleForTesting
static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE;
https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-13.0.0_r63/services/core/java/com/android/server/pm/UserManagerService.java#253
where Integer.MAX_VALUE
is known to be 2147383647, and UserHandle.PER_USER_RANGE
is defined to be:
/**
* @hide Range of uids allocated for a user.
*/
@UnsupportedAppUsage
public static final int PER_USER_RANGE = 100000;
https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-13.0.0_r63/core/java/android/os/UserHandle.java#46
Besides, the maximum allowed userId
does not reach 21474, only 21473 is allowd:
@GuardedBy("mUsersLock")
private int scanNextAvailableIdLocked() {
for (int i = MIN_USER_ID; i < MAX_USER_ID; i++) {
if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) {
return i;
}
}
return -1;
}
https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-13.0.0_r63/services/core/java/com/android/server/pm/UserManagerService.java#5505
It also seems somewhat hilarious that my Android 7 AVD actually threw out Error: java.lang.IllegalStateException: No user id available!
when executing pm create-user test
after userId
had reached 21473.
@agnostic-apollo Oh it seems that I'm not the first person who has once came up with similar idea.
~~However I actually tried /./././
and the ~~wrapper shell script~~ env
shebang of npm
does not seem to work. PS1
prompt also printed out all the lengthy path. Maybe realpath
has something to do with this? I don't know.~~
Edit after reply: it's simply because of lack of execute permission. chmod +x ../usr/lib/node_modules/npm/bin/*
fixes this.
- Are other packages working?
- What errors are you getting? ("does not seem to work" is not an error and nor can anyone suggest fixes based on it.
- Are you exporting that in
$PATH
? - Are
DT_RUNPATH
entries being properly replaced? ExportingLD_LIBRARY_PATH
may help.
https://stackoverflow.com/questions/13769141/can-i-change-rpath-in-an-already-compiled-binary
https://github.com/NixOS/patchelf
http://blog.tremily.us/posts/rpath/
You may not have understood the suggestion in https://github.com/termux/termux-app/issues/2734
Packages must be compiled with for example /data/data/com.termux//.
and then path replaced with /data/user/10/com.termux
so that both match length 24
. To support all user ids would require more logic and thinking.
realpath
will not care for /.