termux / proot

An chroot-like implementation using ptrace.
https://wiki.termux.com/wiki/PRoot
Other
794 stars 163 forks source link

[Feature request] Termux's shm support. #271

Open twaik opened 1 year ago

twaik commented 1 year ago

Hi. I am writing new termux-x11 version which will use embedded X server. That means it will be impossible to use Xvfb or Xwayland in proot container so proot-distro users will not be able to use any program which requires MIT-SHM support.

MIT-SHM requires both server (which will run in android's JVM) and clients (in our case in proot'ed environment) to have the same sysv ipc mechanisms. I know that it is complicated because of syscall chaining, but maybe there is some way to make proot use termux's ipc implementation?

For some reason termux-x11 can not be started in proot (for some reason app_process can not find required files) so I can not start it in container.

Thank you for your hard work.

sylirre commented 1 year ago

for some reason app_process can not find required files

Used to run Termux:API and am inside PRoot.

If you run PRoot Distro and not using --ieolated options, then perhaps your device uses some additional paths besides currently bound. This usually can be detected through logcat. If that's the case, I can fix it.

twaik commented 1 year ago

It simply prints Killed to stderr.

logcat ``` 04-21 10:21:21.459 29632 29632 D AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<< 04-21 10:21:22.199 29632 29632 I AndroidRuntime: Using default boot image 04-21 10:21:22.203 29632 29632 I AndroidRuntime: Leaving lock profiling enabled 04-21 10:21:22.215 29632 29632 W libc : Access denied finding property "odsign.verification.success" 04-21 10:21:22.248 29632 29632 D AndroidRuntime: addProductProperty: pBrand1 is not null 04-21 10:21:22.253 29632 29632 D AndroidRuntime: addProductProperty: not brand or 7 04-21 10:21:22.425 29632 29632 W app_process: ART APEX data files are untrusted. 04-21 10:21:22.444 29632 29632 I app_process: Using CollectorTypeCC GC. 04-21 10:21:31.464 29632 29632 D app_process: Time zone APEX ICU file found: /apex/com.android.tzdata/etc/icu/icu_tzdata.dat 04-21 10:21:31.478 29632 29632 D app_process: I18n APEX ICU file found: /apex/com.android.i18n/etc/icu/icudt70l.dat 04-21 10:21:31.888 29632 29632 W ziparchive: Unable to open '/data/data/com.termux/files/usr/libexec/termux-x11/loader.dm': No such file or directory 04-21 10:21:32.274 29632 29632 E SemDvfsManager_JNI: SemDvfsManager: registerfunction enter 04-21 10:21:32.285 29632 29632 E SemAffinityControl: SemAffinityControl: registerfunction enter 04-21 10:21:32.988 29632 29632 D AndroidRuntime: Calling main entry com.termux.x11.Loader 04-21 10:21:33.013 29632 29632 I Termux:X11 loader: started 04-21 10:21:33.058 29632 29632 W libc : Access denied finding property "qemu.sf.lcd_density" 04-21 10:21:33.068 29632 29632 W libc : Access denied finding property "qemu.sf.lcd_density" 04-21 10:21:34.904 29632 29632 W app_process: unable to execute idmap2: Permission denied 04-21 10:21:34.908 29632 29632 W OverlayConfig: 'idmap2 create-multiple' failed: no mutable="false" overlays targeting "android" will be loaded 04-21 10:21:34.918 29632 29632 W libc : Access denied finding property "ro.vendor.mtk_model" 04-21 10:21:35.115 29632 29632 I SemTelecomManager: hasSamsungTelecomSystemFeature : true 04-21 10:21:35.272 29632 29632 E SystemServiceRegistry: systemservice inputdev:true 04-21 10:21:36.535 29632 29632 D SecIpmManagerFrameworkInitializer: initial 04-21 10:21:36.648 29632 29632 I Typeface: Preloading /system/fonts/Roboto-Regular.ttf 04-21 10:21:36.669 29632 29632 I Typeface: Preloading /system/fonts/RobotoStatic-Regular.ttf 04-21 10:21:38.773 29632 29632 I Termux:X11 loader: loading /data/app/~~-yZV8Mu0AEhjsqToRXO0iw==/com.termux.x11-Htmzwd08R78w6ClHfGDhTA==/base.apk of com.termux.x11 application 04-21 10:21:38.781 29632 29632 W System : ClassLoader referenced unknown path: /data/app/~~-yZV8Mu0AEhjsqToRXO0iw==/com.termux.x11-Htmzwd08R78w6ClHfGDhTA==/base.apk 04-21 10:21:38.806 29632 29632 D AndroidRuntime: Shutting down VM 04-21 10:21:38.815 29632 29632 E AndroidRuntime: FATAL EXCEPTION: main 04-21 10:21:38.815 29632 29632 E AndroidRuntime: PID: 29632 04-21 10:21:38.815 29632 29632 E AndroidRuntime: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.termux.x11.CmdEntryPoint 04-21 10:21:38.815 29632 29632 E AndroidRuntime: at com.termux.x11.Loader.main(Loader.java:63) 04-21 10:21:38.815 29632 29632 E AndroidRuntime: at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) 04-21 10:21:38.815 29632 29632 E AndroidRuntime: at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:378) 04-21 10:21:38.815 29632 29632 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: com.termux.x11.CmdEntryPoint 04-21 10:21:38.815 29632 29632 E AndroidRuntime: at java.lang.Class.classForName(Native Method) 04-21 10:21:38.815 29632 29632 E AndroidRuntime: at java.lang.Class.forName(Class.java:454) 04-21 10:21:38.815 29632 29632 E AndroidRuntime: at com.termux.x11.Loader.main(Loader.java:59) 04-21 10:21:38.815 29632 29632 E AndroidRuntime: ... 2 more 04-21 10:21:38.815 29632 29632 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: com.termux.x11.CmdEntryPoint 04-21 10:21:38.815 29632 29632 E AndroidRuntime: ... 5 more 04-21 10:21:38.827 29632 29632 E AndroidRuntime: Error reporting crash 04-21 10:21:38.827 29632 29632 E AndroidRuntime: java.lang.RuntimeException: Bad file descriptor 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.os.BinderProxy.transactNative(Native Method) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.os.BinderProxy.transact(BinderProxy.java:653) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.os.IServiceManager$Stub$Proxy.checkService(IServiceManager.java:421) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.os.ServiceManagerProxy.getService(ServiceManagerNative.java:63) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.os.ServiceManager.rawGetService(ServiceManager.java:427) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.os.ServiceManager.getService(ServiceManager.java:202) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.app.ActivityManager$1.create(ActivityManager.java:5212) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.app.ActivityManager$1.create(ActivityManager.java:5209) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.util.Singleton.get(Singleton.java:43) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at android.app.ActivityManager.getService(ActivityManager.java:5200) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at com.android.internal.os.RuntimeInit$KillApplicationHandler.uncaughtException(RuntimeInit.java:176) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1073) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068) 04-21 10:21:38.827 29632 29632 E AndroidRuntime: at java.lang.Thread.dispatchUncaughtException(Thread.java:2306) 04-21 10:21:38.834 29632 29632 I Process : Sending signal. PID: 29632 SIG: 9 ```

strace_log.txt

It looks like it simply can not access path to apk (in /data/app) it gets from PackageManager API.

twaik commented 1 year ago

Is there a way to detect proot? When I tried to use syscall(SYS_shmat) my application was killed by seccomp so I think I need somehow detect proot to enable using sysvipc syscalls only in proot.

twaik commented 1 year ago

And there is one more question. How to make proot use single namespace for all the invocations of proot (mentioned here)?

sylirre commented 1 year ago

It looks like it simply can not access path to apk (in /data/app) it gets from PackageManager API.

I was able to bind that path (/data/app) under proot-distro, so the fix should be trivial.

michalbednarski commented 1 year ago

When I tried to use syscall(SYS_shmat) my application was killed by seccomp

In that case you can detect that by registering signal handler for SIGSYS or checking in child process

Another way is used by systemd-detect-virt, which detects proot by looking for TracerPid in /proc/self/status and checking if that process with name starting with "proot"

Note that you can also be under proot without --sysvipc, in which case syscall(SYS_shmat) will return -ENOSYS without raising signal

make proot use single namespace for all the invocations of proot

There currently isn't such option as this namespacing behaviour is just effect of that shm status is stored within proot process, there isn't client-server (The proot --shm-helper process stores shared memory file descriptors, however all bookkeeping is in main proot process)

Probably it'd make more sense to use libandroid-shmem's server (or do you use something else?), than attempting to make my implementation start own server, although for that probably I'd need additional helper binary from libandroid-shmem side (as currently with libandroid-shmem runs server in whatever process requested allocation and I would like to avoid pulling libandroid-shmem server into proot and also I'd need something that would provide shm metadata and file descriptors instead of directly mapping them)

Also in that case sem and msg would still be separate namespaces

It might also be possible to just use libandroid-shmem inside proot, although don't really know if current ports work