termux / termux-app

Termux - a terminal emulator application for Android OS extendible by variety of packages.
https://f-droid.org/en/packages/com.termux
Other
36.94k stars 3.88k forks source link

[Bug]: Termux proceeses lose ability to read files after entering a pivot_root jail from shell (?) #4130

Closed maakiono closed 3 months ago

maakiono commented 3 months ago

Problem description

Termux loses the ability to read any files after I use unshare and pivot_root to shell into a ubuntu chroot Which somehow causes termux-x11 to crash and termux to not be able to open any new sessions than already open

Steps to reproduce the behavior.

On a device rooted with kernelSU, run (might work with magisk aswell)

# Setup a mini root for pivot_root 
wget "https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/aarch64/alpine-minirootfs-3.20.2-aarch64.tar.gz"
mkdir chroot
tar xvf "alpine-minirootfs-3.20.2-aarch64.tar.gz" -C chroot

# create a namespace and pivot_root into the chroot directory
su -c unshare -p -m -f sh -c \
    "echo noop;\
    mkdir -p chroot/old_root;\
    mount --bind chroot chroot;\
    busybox pivot_root chroot chroot/old_root;\
    /bin/mount proc -t proc /proc;\
    /bin/mount sys -t sysfs /sys;\
    /bin/mount --bind /old_root/dev /dev;\
    /bin/mount --bind /old_root/dev/pts /dev/pts;\
    /bin/mount --bind /old_root/storage/emulated/0 /sdcard;\
    /bin/mount --bind /old_root$PREFIX/tmp/ /tmp/;\
    /bin/su -l"

Script for convenience repro.sh.txt

What is the expected behavior?

No crash of termux-x11 and other termux proceeses

System information

maakiono commented 3 months ago

Video of me doing the same

https://github.com/user-attachments/assets/e7618038-b803-4119-bbac-1faa6d8e3925

Logcats

28_08-23-26-35_679.log

sylirre commented 3 months ago

That's not a bug.

termux-x11 depends on Android OS mount points and certain environment variables. However your script creates isolated rootfs which can't satisfy dependencies.

You can look what proot-distro (https://github.com/termux/proot-distro) to let Termux utilities run inside distribution environment without issues and adjust your script accordingly.

maakiono commented 3 months ago

Im not entirely sure termux should even be affected by this, the isolated rootfs is created in a completely different namespace in a different mount namespace than what termux is running on

twaik commented 3 months ago

Exactly. Termux:X11 requires Android JVM to work.

maakiono commented 3 months ago

proot-distro uses chroot and user namespaces do not work in chroots and return a EPERM

With user namespaces now being a requirement for even steam to run i cant use proot

maakiono commented 3 months ago

Exactly. Termux:X11 requires Android JVM to work.

The issue affects all termux services i cant open any new sessions either

maakiono commented 3 months ago

I also would like inform that the x11 socket is exposed to termux-x11 using a bind mount and should be completely unaffected by this

sylirre commented 3 months ago

@maakiono Whether you trying to start termux-x11 outside of chroot or not, this is not issue of Termux app.

Termux app is not any different from other Android OS applications. It does not manage or affect namespaces usage. However the su binary provided by KernelSU or whatever are you using can.

sylirre commented 3 months ago

Most likely the problem is in "su -c unshare -p -m -f sh -c "*. Normal su implementations do not accept arguments for "-c" in such format.

su -c <command> is supposed to be equivalent of sh -c <command>.

Termux provides a sudo command in tsu package. Try it for your task.

maakiono commented 3 months ago

I will try to investigate into the flag situation later today

410 was the reason i chose to avoid running it with sudo

Screenshot_20240830-063044_Termux

su -c runs it under the selinux context of ksud

sylirre commented 3 months ago

Try this:

su -c "unshare -p -m -f sh -c \
    \"echo noop;\
    mkdir -p chroot/old_root;\
    mount --bind chroot chroot;\
    busybox pivot_root chroot chroot/old_root;\
    /bin/mount proc -t proc /proc;\
    /bin/mount sys -t sysfs /sys;\
    /bin/mount --bind /old_root/dev /dev;\
    /bin/mount --bind /old_root/dev/pts /dev/pts;\
    /bin/mount --bind /old_root/storage/emulated/0 /sdcard;\
    /bin/mount --bind /old_root$PREFIX/tmp/ /tmp/;\
    /bin/su -l\""

I did not test it on mobile device as none from what I have are rooted. But on my Ubuntu laptop this variant worked.

maakiono commented 3 months ago

I have verified that flags are being passed to the unshare binary by looking at /proc/pid/cmdline of the unshare process,

I have a feeling that a mount namespace isn't being created and is being inherited from termux process, which upon pivot_root overrides termux's root directory

maakiono commented 3 months ago

This might just be a issue with Android kernel