termux-app icon indicating copy to clipboard operation
termux-app copied to clipboard

[Feature]: Multi-user support

Open FossPrime opened this issue 2 years ago • 35 comments

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.

Screenshot_20220509-232949

Additional information

Nix-on-droid also doesn't work. I'll use termius instead.

FossPrime avatar May 09 '22 14:05 FossPrime

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?

agnostic-apollo avatar May 09 '22 23:05 agnostic-apollo

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.

ChiefMikeK avatar May 11 '22 04:05 ChiefMikeK

... 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.

FossPrime avatar May 11 '22 20:05 FossPrime

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 ;)

agnostic-apollo avatar May 12 '22 04:05 agnostic-apollo

Does a work profile works for you?

Anonymous2716 avatar Jul 02 '22 17:07 Anonymous2716

Hi,

Could be a solution a new script for the compilation environment supporting this?

  1. Compile Termux with a different "name" and "$PREFIX".
  2. Recompile a list of user selected packages for this "new" Termux.
  3. Recompile some Termux-plugins (example Termux-GUI) for this new target.
  4. Add some user files and installation scripts.
  5. 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. 😉

lars18th avatar Jul 15 '22 08:07 lars18th

https://github.com/termux/termux-app#Forking

Make sure to change sharedUserId. Also I don't know about Termux:GUI forkability.

agnostic-apollo avatar Jul 15 '22 08:07 agnostic-apollo

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.

lars18th avatar Jul 18 '22 07:07 lars18th

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

Grimler91 avatar Jul 18 '22 07:07 Grimler91

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.

agnostic-apollo avatar Jul 18 '22 18:07 agnostic-apollo

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.

tareksander avatar Oct 04 '22 22:10 tareksander

?Any updates about the issue? I have not been able to use termux because of that! Thankz

Pxys-io avatar Nov 18 '22 19:11 Pxys-io

?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.

FossPrime avatar Nov 18 '22 21:11 FossPrime

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.

agnostic-apollo avatar Nov 18 '22 22:11 agnostic-apollo

Is there any solution to this yet cause I'm also I'm need of it

n1lby73 avatar Dec 27 '22 07:12 n1lby73

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

termux-secondary-user

Adoptable Storage

termux-adoptable-storage

agnostic-apollo avatar Dec 28 '22 17:12 agnostic-apollo

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 avatar Jul 05 '23 17:07 RealEthanPlayzDev

@RealEthanPlayzDev did you try proot? https://www.reddit.com/r/termux/comments/10h2bmn/how_to_run_termux_environment_through_proot_from/

romanovj avatar Jul 05 '23 19:07 romanovj

AFAIK agnostic-apollo works in a local fork, so there is no way to try it until it's released.

tareksander avatar Jul 05 '23 19:07 tareksander

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 avatar Jul 05 '23 20:07 agnostic-apollo

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 avatar Jul 06 '23 02:07 RealEthanPlayzDev

@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)

proot.zip

romanovj avatar Jul 06 '23 04:07 romanovj

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 avatar Jul 06 '23 06:07 RealEthanPlayzDev

@RealEthanPlayzDev ofc you need to change path to whatever you have

romanovj avatar Jul 06 '23 06:07 romanovj

@romanovj

I've tried following that Reddit post's instructions along with changing the paths it needs, currently I'm stuck here: Screenshot_20230706_161251_Termux 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?

RealEthanPlayzDev avatar Jul 06 '23 09:07 RealEthanPlayzDev

@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

romanovj avatar Jul 10 '23 14:07 romanovj

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.

agnostic-apollo avatar Jul 10 '23 15:07 agnostic-apollo

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.

segfault-bilibili avatar Jul 11 '23 01:07 segfault-bilibili

@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.

segfault-bilibili avatar Jul 11 '23 01:07 segfault-bilibili

  • 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? Exporting LD_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 /.

agnostic-apollo avatar Jul 11 '23 01:07 agnostic-apollo