termux / proot

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

[Feature]: Is there any approch to have read-only access to kernel parameters ralated to sysctl? #218

Open metorm opened 2 years ago

metorm commented 2 years ago

Feature description

I am not sure this is a bug, a feature request, or a device-specific issue.

I am trying to run some Qt applications with termux on my cell phone.

However, it seems any Qt app having qtwebengine module requires to read /proc/sys/fs/inotify/max_user_watches property. The property is unavailable with termux:

~ $ sysctl -a
sysctl: cannot stat /proc/sys/abi/cp15_barrier: Permission denied
sysctl: cannot stat /proc/sys/abi/setend: Permission denied
sysctl: cannot stat /proc/sys/abi/swp: Permission denied
sysctl: cannot stat /proc/sys/abi/tagged_addr_disabled: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/enable: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/options: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/per_thresh: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/phyerr_thresh: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/sack_thr: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/size: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/tail_length: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/thruput_thresh: Permission denied
sysctl: cannot stat /proc/sys/ath_pktlog/cld/trigger_interval: Permission denied
sysctl: cannot stat /proc/sys/debug/exception-trace: Permission denied
sysctl: cannot stat /proc/sys/dev/scsi/logging_level: Permission denied
sysctl: cannot stat /proc/sys/dev/tty/ldisc_autoload: Permission denied
sysctl: cannot stat /proc/sys/fs/aio-max-nr: Permission denied
sysctl: cannot stat /proc/sys/fs/aio-nr: Permission denied
sysctl: cannot stat /proc/sys/fs/dentry-state: Permission denied
sysctl: cannot stat /proc/sys/fs/epoll/max_user_watches: Permission denied
......

I've tested two cell phones and it's all the same. I tested my qt application, the qtcreator (crashes when I open the UI editor and edit the UI file having a qtwebengine widget), and the falkon browser. All the crash message were alike:

[28643:28886:0222/200331.527402:ERROR:file_path_watcher_linux.cc(71)] Failed to read /proc/sys/fs/inotify/max_user_watches

The Qt applications were ran inside a proot-distro ubuntu, but the sysctl -a command was ran in termux directly. All tests show that we do not have ready access to /proc/sys/fs/inotify/max_user_watches, which shall be available in normal linux environment.

Is it possible to overcome this problem?

Additional information

Is there any other emulator to run ubuntu on my cell phone?

Grimler91 commented 2 years ago

Getting actual access is only possible with root.

You can create a fake entry for max_user_watches, proot-distro currently does this for a bunch of entries: https://github.com/termux/proot-distro/blob/d008ceb9a83821fe5b660697619bdb3c393aaff5/proot-distro.sh#L577

metorm commented 2 years ago

@Grimler91 Thanks for the rapid help. I tried to add the below lines to the setup_fake_proc() function but got no fortune.

        if [ ! -d "${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify" ]; then
                mkdir -p "${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify"
                #touch "${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify/.max_user_watches"
                cat <<- EOF > "${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify/.max_user_watches"
                8192
                EOF
        fi

Would you please give more detailed suggestions about the hack?

Grimler91 commented 2 years ago

Add a corresponding entry in command_login() as well and it should hopefully work.

If it solves your issues (partially or fully) we can incorporate it in proot-distro

metorm commented 2 years ago

Well, the following hack indeed eliminates the error about /proc/sys/fs/inotify/max_user_watches, and cat /proc/sys/fs/inotify/max_user_watches runs normally now.

In setup_fake_proc():

        if [ ! -d "${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify" ]; then
                mkdir -p "${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify"
                chmod 700 "${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify"
                cat <<- EOF > "${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify/.max_user_watches"
                8192
                EOF
        fi

In [command_login():

                # Fake /proc/vmstat if necessary.
                if ! cat /proc/vmstat > /dev/null 2>&1; then
                        set -- "--bind=${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/.vmstat:/proc/vmstat" "$@"
                fi

                # Fix inotify/max_user_watches
                if ! cat /proc/sys/fs/inotify/max_user_watches > /dev/null 2>&1; then
                        set -- "--bind=${INSTALLED_ROOTFS_DIR}/${distro_name}/proc/sys/fs/inotify/.max_user_watches:/proc/sys/fs/inotify/max_user_watches" "$@"
                fi

However, those Qt applications still won't run. The error message is now:

[26210:26466:0222/231917.605308:ERROR:udev_watcher.cc(51)] Failed to initialize a udev monitor.
pcilib: Cannot open /proc/bus/pci/devices
segment fault

Maybe there is a long way to go running qtwebengine without root ...

Grimler91 commented 2 years ago

I'm not really familiar with qtwebengine, so no idea why it needs to access /proc/bus/pci/devices, but android doesn't use udev so a similar hack will probably not work in this case. Better strategy would be to disable the udev-using part of qtwebengine, if possible

metorm commented 2 years ago

I think I found a workaround, which is not exciting but acceptable.

I guessed that qtwebengine is doing that for hardware acceleration, so I passed a command-line --disable-gpu to these applications, turned out my Qt app and the falkon browser would run normally. The qtcreator wouldn't accept this command-line option, but we have much more choices to edit a *.ui file containing a qtwebengine widget.

Then I tried the original version of proot-distro. A depressing fact is that the max_user_watches error is not the reason for the apps to crash. The following message is still there, but the app runs well.

[31057:31074:0222/235041.686332:ERROR:file_path_watcher_linux.cc(71)] Failed to read /proc/sys/fs/inotify/max_user_watches
ghost commented 2 years ago

I guessed that qtwebengine is doing that for hardware acceleration, so I passed a command-line --disable-gpu to these applications, turned out my Qt app and the falkon browser would run normally. The qtcreator wouldn't accept this command-line option, but we have much more choices to edit a *.ui file containing a qtwebengine widget.

Falkon actually uses chromium engine. while command line arguments isn't well-parsed to chromium. you may try disabling sandbox with environment variable env QTWEBENGINE_DISABLE_SANDBOX=1 qtcreator. likely default chrome sandbox is enabled while qt creator embeds web engine widget. chrome's sandbox would normally fail in proot

but the app runs well.

if falkon app runs well while receives an error reading restricted filesystem. you may as well ignore it

metorm commented 2 years ago

@wmcbtech30 Following your advice, I tried a few environment variables.

Turned out QTWEBENGINE_DISABLE_SANDBOX=1 doesn't help, but QTWEBENGINE_CHROMIUM_FLAGS="--disable-gpu" does the trick. With this flag, qtcreator now safely opens the *.ui file having qtwebengine widgets, and Falkon also works well. No other tricks are required.

So this workaround is 80% perfect, I think.