termux / proot

An chroot-like implementation using ptrace.

Home Page:https://wiki.termux.com/wiki/PRoot

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SEGV running binary - how to debug further?

tmm1 opened this issue · comments

I'm trying to run headless chromium via proot. It works on arm64-v8a devices, but on armeabi-v7a I'm getting a segfault:

# uname -a
Linux localhost 4.9.113 #1 SMP PREEMPT Fri Apr 17 19:28:59 CST 2020 armv8l Android
# PROOT_NO_SECCOMP=1 LD_PRELOAD= proot --link2symlink -0 -r $PREFIX/share/TermuxAlpine/ -b /dev -b /sys -b /proc -w / /usr/lib/chromium/chrome --version
proot info: vpid 1: terminated with signal 11
# startalpine
[root@localhost home]# /usr/lib/chromium/chrome --version
Segmentation fault
proot info: exe = /usr/lib/chromium/chrome
proot info: argv = /usr/lib/chromium/chrome --version
proot info: initial cwd = /
proot info: verbose level = 999
proot info: pid 28492: access to "/dev/pts/3" (fd 0) won't be translated until closed
proot info: pid 28492: access to "/dev/pts/3" (fd 1) won't be translated until closed
proot info: pid 28492: access to "/dev/pts/3" (fd 2) won't be translated until closed
proot info: pid 28492: access to "/proc/28492/fd" (fd 3) won't be translated until closed
proot info: vpid 1: sysenter start: execve(0xec91d0d0, 0xff820660, 0xff82066c, 0x2f, 0xec910030, 0xff820660) = 0xec91d0d0 [0xff81e550, 0]
proot info: vpid 1: translate("/" + "/usr/lib/chromium/chrome")
proot info: vpid 1:          -> "/data/data/com.termux/files/usr/share/TermuxAlpine/usr/lib/chromium/chrome"
proot info: vpid 1: translate("/" + "/lib/ld-musl-armhf.so.1")
proot info: vpid 1:          -> "/data/data/com.termux/files/usr/share/TermuxAlpine/lib/ld-musl-armhf.so.1"
proot info: vpid 1: sysenter end: execve(0xff81e51b, 0xff820660, 0xff82066c, 0x2f, 0xec910030, 0xff820660) = 0xff81e51b [0xff81e51b, 0]
proot info: vpid 1: sysexit start: restart_syscall(0x0, 0x0, 0x0, 0x0, 0x0, 0x0) = 0x0 [0xff8143f0, 0]
proot info: vpid 1: sysexit end: restart_syscall(0xff8142fc, 0x0, 0x0, 0x0, 0x0, 0x0) = 0xff8142fc [0xff8142fc, 0]
proot info: vpid 1: sysenter start: open(0xff8143bc, 0x0, 0x0, 0x0, 0x0, 0x0) = 0xff8143bc [0xff8142f8, 0]
proot info: vpid 1: translate("/" + "/usr/lib/chromium/chrome")
proot info: vpid 1:          -> "/data/data/com.termux/files/usr/share/TermuxAlpine/usr/lib/chromium/chrome"
proot info: vpid 1: sysenter end: open(0xff8142ad, 0x0, 0x0, 0x0, 0x0, 0x0) = 0xff8142ad [0xff8142ad, 0]
proot info: vpid 1: sysexit start: open(0x3, 0x0, 0x0, 0x0, 0x0, 0x0) = 0x3 [0xff8142ad, 0]
proot info: vpid 1: sysexit end: open(0x3, 0x0, 0x0, 0x0, 0x0, 0x0) = 0x3 [0xff8142f8, 0]
proot info: vpid 1: sysenter start: mmap2(0xf000000, 0x595e000, 0x5, 0x12, 0x3, 0x0) = 0xf000000 [0xff8142f8, 0]
proot info: vpid 1: sysenter end: mmap2(0xf000000, 0x595e000, 0x5, 0x12, 0x3, 0x0) = 0xf000000 [0xff8142f8, 0]
proot info: vpid 1: sysexit start: mmap2(0xf000000, 0x595e000, 0x5, 0x12, 0x3, 0x0) = 0xf000000 [0xff8142f8, 0]
proot info: vpid 1: sysexit end: mmap2(0xf000000, 0x595e000, 0x5, 0x12, 0x3, 0x0) = 0xf000000 [0xff8142f8, 0]
proot info: vpid 1: translate("/" + "/usr/lib/chromium/chrome")
proot info: vpid 1:          -> "/data/data/com.termux/files/usr/share/TermuxAlpine/usr/lib/chromium/chrome"
proot info: vpid 1: terminated with signal 11

Looks like loaded binary mapping has clashed with loader (loader address is defined in arch.h, this value is referenced from GNUMakefile).

Probably either LOADER_ADDRESS should be raised or EXEC_PIC_ADDRESS should be lowered, but I don't know what these values should actually be.

Thanks! Really appreciate the pointer.

I see the EXEC_PIC_ADDRESS being mmap'd in the verbose output above, but no indication of LOADER_ADDRESS. Did you see something in there that suggested overlap, or just a hunch based on the segv that the binary was being corrupted?

Either way, you were correct and the following works for me now:

--- a/src/arch.h
+++ b/src/arch.h
@@ -101,7 +101,7 @@ typedef unsigned char byte_t;
     #define OFFSETOF_STAT_GID_32 0
     #define EM_ARM 40

-    #define LOADER_ADDRESS 0x10000000
+    #define LOADER_ADDRESS 0x20000000

     #define EXEC_PIC_ADDRESS   0x0f000000
     #define INTERP_PIC_ADDRESS 0x1f000000

Not sure if this is something that should be merged, or if there would be other unintended consequences. Now that the binary runs maybe I can look at /proc/pid/maps and see where the overlap was and how much extra space is actually needed..

I discovered there is an old WIP branch upstream that tries to remove LOADER_ADDRESS: https://github.com/proot-me/proot/compare/position_independant

Hi, i pointed to this issue where i needed to run Chromium on 32-bit environment, and it got segfaults, somehow running chromium works by setting LOADER_ADDRESS to 0x20000000 in proot's source, so far i didn't get any strange side effects from time to time when using armhf distro and it only fixes chromium segfaults after using armhf distro for like a month now

I guess it's time that LOADER_ADDRESS should be set to 0x20000000?

@wmcb-tech, may be best to apply changes from the position_independant branch to the Termux proot repository?

just to be safe then probably yes