termux / proot

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

Can Proot be used to access Linux distribution from external storage such as SD card #50

Open JanuszChmiel opened 6 years ago

JanuszChmiel commented 6 years ago

I Am wondering, if is it possible to use Proot to run Linux distribution not from internal storage but rather from external SD card. I know, that it is not easy, but if is it not possible for now, which are The reasons? My dream is to install Debian not to Android private application Area controlled by Termux, but install it to SD card. It would not require to use phones or tablets with huge internal storage. Which issues can wait for Me if I would like to try this approach? If this system would be usable from SD card at least till Android 6.0 not for never versions, I could be satisfied. Thank you very much for yours advices and answer.

ghost commented 6 years ago

Short answer: no.

File systems like FAT 12/16/32 or exFAT - only they are allowed on Android, don't have support for unix file permissions. They don't support symlinks, sockets, pipes and other special files.

That's why Termux is restricted only to internal storage. Proot, is not an exception.

Which issues can wait for Me if I would like to try this approach?

Ohh, permission denied is waiting for you there...

JanuszChmiel commented 6 years ago

Oh thank you very much for yours founded answer. You are man at The right place. Yours professor who learned you on informatics studies can be really very proud to you.

corbinlc commented 5 years ago

Longer answer...yes, but it is difficult. I developed a PRoot extension in the past that put everything on the sdcard (had to get around FAT naming rules) and would copy down files and their interpreter and libraries as needed. It worked for most cases, but was never stable enough. Also, I wasn't sure whether to A) push files sdcard back right away...there were some issues with this, B) push files only when the user asked to reshrink the filesystem or C) do it at every startup or D) make it a choice. I may resurrect this work since I am working on UserLAnd now and it is still a popular demand. It is a little ways down my list though as there is a lot of low hanging fruit before I get to this. So no promises, but I know that it is possible from how far I got before.

projectextremum commented 5 years ago

@corbinlc copying and re-copying stuff ain't best way out here. I suppose the performance will then be comparable to QEMU, so we can then use QEMU instead, at least for sake of more controls.

There existed programs like ul-exec and now there exist some rewrites of obsolete ulexec which is claimed to work. But none of them are for arm, it requires significant effort to rewrite it for arm. I think @xeffyr can provide some reasoning here.

@JanuszChmiel qemu-system-arm may fit your use case though, despite being little slower and there is a boot time unlike proot which instantly gives root shell.

And just for sake of clarity, why would someone even consider putting these rootfs into an area with write access to all apps?

michalbednarski commented 5 years ago

I've implemented something like that and just pushed to force-exec branch for experimentation. So far I've only tested with single files but appears to work. This is very alpha version of feature, no error checks are performed, parts of code outside of extension were commented out.

Modification affects execve/mmap/mmap2 syscalls. Other syscalls are not currently affected, so for full emulation of execution permissions stat and access probably should be modified as well. That is similar to what UserLAnd does so probably @corbinlc could help if we'd continue with this feature.

@projectextremum What is ul-exec? I cannot find it.

And just for sake of clarity, why would someone even consider putting these rootfs into an area with write access to all apps?

Reason is storage space, as not all devices have /sdcard emulated using same partition as /data, so this feature might be useful for some users.

JanuszChmiel commented 5 years ago

Dear Mr bednarsk, It is also very important to test, if default file system, which is being used by ANdroid formatting routines is compatible with yours approach. Or if is it necessary to format external device by using computer and access it by using modified Proot and other modules, which you have tried to redesign. By The way thank you very much for yours work. Since for example, Samsung Galaxy chat SMG551 contain not too much space inside its internal storage. And it would be ideal, if users would be able to simply store his distribution on SDcart or on external harddisk. Very well done. I have The good will to test it.

ghost commented 5 years ago

Just tested it - works:

$ pwd
/sdcard
$ proot ./busybox
BusyBox v1.29.3 (2018-09-10 22:46:33 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

    BusyBox is a multi-call binary that combines many common Unix
    utilities into a single executable.  Most people will create a
    link to busybox for each function they wish to use and BusyBox
    will act like whatever it was invoked as.

Currently defined functions:
    ar, arp, awk, base64, basename, bbconfig, bunzip2, bzip2, cal, cat,
    chattr, chgrp, chmod, chown, chpst, chrt, cksum, clear, cmp, comm, cp,
....

But anyway, this doesn't allow to create proot'ed environment on sdcard because FS doesn't support symlinks and other kinds of special files.

Ubuntu. Bash is not working due to missing linker symlink:

$ pwd
/sdcard/ubuntu
$ ls
bin    dev    home   media  opt    root   sbin   srv    tmp    var
boot   etc    lib    mnt    proc   run    snap   sys    usr
$ proot -R . /bin/bash
proot error: execve("/bin/bash"): No such file or directory
proot info: possible causes:
  * the program is a script but its interpreter (eg. /bin/sh) was not found;
  * the program is an ELF but its interpreter (eg. ld-linux.so) was not found;
  * the program is a foreign binary but qemu was not specified;
  * qemu does not work correctly (if specified);
  * the loader was not found or doesn't work.
fatal error: see `proot --help`.
proot error: can't chmod '/data/data/com.termux/files/usr/tmp/proot-32608-E7hccJ': No such file or directory
proot error: can't chdir to '/data/data/com.termux/files/usr/tmp': No such file or directory
$

Linker copied manually, but now bash is not working because of missing library symlink:

$ cp ./lib/aarch64-linux-gnu/ld-2.27.so ./lib/ld-linux-aarch64.so.1
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

Okay, library can be renamed/copied. But it is not working anyway:

$ cp ./lib/aarch64-linux-gnu/libtinfo.so.5.9 ./lib/aarch64-linux-gnu/libtinfo.so.5
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: failed to map segment from shared object
corbinlc commented 5 years ago

@michalbednarski it has been a while, but this looks like a cleaner solution to part of the problem, that the sdcard is mounted noexec. There are other parts to the problem...like symlinks and a naming issues on the sdcard which is FAT, but this is much cleaner than how I was copying files to internal storage previously.

corbinlc commented 5 years ago

For those issues, I had to have the rootfs actually be in internal storage, but have it consist of just symbolic links to the real files living on the sdcard. For the file names on the sdcard, I just gave them numeric values, since I couldn't use the actual names. Do you know of a more clever solution to the issues with the sdcard being FAT @michalbednarski? As you have already come up with a better solution for the noexec problem.

ZhymabekRoman commented 4 years ago

Q : is it possible to install a Linux distribution on an SD card ? Answer: Yes, you may need to have root rights on the Android system. Using the App2SD program (http://www.apps2sd.info/) you need to create a second partition on the SD card in the ext4 file system. next, you need to create a mount script and mount it to the system. It is in this program that this is done in one click. Now there are two options : you can move it completely (data, APK, and so on) Termux itself on the SD card, or just install the Linux distribution on the path : /data/sdext2.

I personally have Termux installed on the SD card using App2SD and everything is fine. By the way, do not forget that the SD card does not have very large write and read cycles, and it is possible that after an hour of use, the card will go into "read only" mode. I've already had this happen

Question : can I Move Termux to the SD card using system settings and without root rights? Answer: probably not. System settings do not know how to move the data folder to the SD card because SD cards are formatted in FAT32 according to the standard

My original text Вопрос : Возможно ли установить Linux дистрибутив на SD карте ? Ответь: Да, возможно, для этого нужно иметь Рут права на Android системе. С помощью программы App2SD (http://www.apps2sd.info/) нужно создать второй раздел на SD карте в файловой системе ext4. Далее нужно создать скрипт монтирования и примонтировать к системе. Именно в этой программе это делается в один клик. Теперь тут два варианта : можно переместить полностью (data, APK и тому подобное) сам Termux на SD карту, или же чисто только установить Linux дистрибутив по пути : /data/sdext2. У меня лично Termux установлен на SD карте с помощью App2SD и все отлично. Кстати, не забудьте что у SD карты циклов записи и чтения данных не совсем большие и возможно после часого использования карта уйдёт в режим "read only". У меня уже случилось такое Вопрос : А можно ли переместить Termux в SD карту используя системные настройки и без Рут прав? Ответ: скорее всего - нет. Системные настройки не умеют перемещать data папку в SD карту потому что SD карты по стандарту форматируются в FAT32
ZhymabekRoman commented 4 years ago

@xeffyr I think the question can be closed

ghost commented 4 years ago

@ZhymabekRoman Correct, but this issue is mostly about using proot for executing programs from sdcard. That's possible, see this branch https://github.com/termux/proot/tree/force-exec, it is WIP.

RohitVerma882 commented 3 years ago

Just tested it - works:

$ pwd
/sdcard
$ proot ./busybox
BusyBox v1.29.3 (2018-09-10 22:46:33 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

  BusyBox is a multi-call binary that combines many common Unix
  utilities into a single executable.  Most people will create a
  link to busybox for each function they wish to use and BusyBox
  will act like whatever it was invoked as.

Currently defined functions:
  ar, arp, awk, base64, basename, bbconfig, bunzip2, bzip2, cal, cat,
  chattr, chgrp, chmod, chown, chpst, chrt, cksum, clear, cmp, comm, cp,
....

But anyway, this doesn't allow to create proot'ed environment on sdcard because FS doesn't support symlinks and other kinds of special files.

Ubuntu. Bash is not working due to missing linker symlink:

$ pwd
/sdcard/ubuntu
$ ls
bin    dev    home   media  opt    root   sbin   srv    tmp    var
boot   etc    lib    mnt    proc   run    snap   sys    usr
$ proot -R . /bin/bash
proot error: execve("/bin/bash"): No such file or directory
proot info: possible causes:
  * the program is a script but its interpreter (eg. /bin/sh) was not found;
  * the program is an ELF but its interpreter (eg. ld-linux.so) was not found;
  * the program is a foreign binary but qemu was not specified;
  * qemu does not work correctly (if specified);
  * the loader was not found or doesn't work.
fatal error: see `proot --help`.
proot error: can't chmod '/data/data/com.termux/files/usr/tmp/proot-32608-E7hccJ': No such file or directory
proot error: can't chdir to '/data/data/com.termux/files/usr/tmp': No such file or directory
$

Linker copied manually, but now bash is not working because of missing library symlink:

$ cp ./lib/aarch64-linux-gnu/ld-2.27.so ./lib/ld-linux-aarch64.so.1
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

Okay, library can be renamed/copied. But it is not working anyway:

$ cp ./lib/aarch64-linux-gnu/libtinfo.so.5.9 ./lib/aarch64-linux-gnu/libtinfo.so.5
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: failed to map segment from shared object

How you excuted?

xloem commented 3 years ago

@xeffyr I think the question can be closed

Most people do not have rooted phones ...

xloem commented 3 years ago

Bumped into this issue again. I infer the path forward is for people to contribute work so that this feature is met.

It looks like basically this means hooking system calls to provide for the needed features: making or reusing a filesystem norm to pretend the disk is fully featured. Luckily proot is already based around hooking system calls.

It might be possible to multitask here or reuse existing work by doing something like loading a loopback or other flat image or porting FUSE, or that might end up being more unnecessary work.

The branch linked above contains only one commit which adds some demonstration hooks.

There are various bounty services, as well, that could be used to pay more developers to work on this issue. We can also work on it slowly by consolidating helpful information.

EDIT: The best investment here (although not necessarily the quickest path) might be FUSE support. FUSE filesystems communicate with a pipe-like block device, "/dev/fuse" by default, that could likely be provided by something like a named pipe in a local folder. FUSE is designed to be provided by user-space kernel-emulation daemons if they are built.

The fuse protocol is simple c-struct based messaging. The kernel emulator sends calls composed of an "in" header and following data, and fuse replies with a different "out" header and following data. The headers are at https://github.com/libfuse/libfuse/blob/d709c24cbd9e1041264c551c2a4445e654eaf429/include/fuse_kernel.h#L739 and there is a struct for each message data there as well.

An implementation would hook system calls to send messages from that header to a fuse ipc channel, and in termux likely provide a fuse library that opened the ipc channel by default.

The implementations of each message handler are in https://github.com/libfuse/libfuse/blob/d709c24cbd9e1041264c551c2a4445e654eaf429/lib/fuse_lowlevel.c#L2462 but all they do are read the data, forward the call to the filesystem, and serialize and write the reply if there is one.

It would make sense to contribute work to proot or fuse upstream.

j-romchain commented 2 years ago

Has anyone tried mounting multiple img files to make the root filesystem? .img to allow symlinks etc, and multiple to allow > 4gb ?

Austcool-Walker commented 1 year ago

Just tested it - works:


$ pwd
/sdcard
$ proot ./busybox
BusyBox v1.29.3 (2018-09-10 22:46:33 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...] or: busybox --list[-full] or: busybox --install [-s] [DIR] or: function [arguments]...

BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable.  Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as.

Currently defined functions: ar, arp, awk, base64, basename, bbconfig, bunzip2, bzip2, cal, cat, chattr, chgrp, chmod, chown, chpst, chrt, cksum, clear, cmp, comm, cp, .... But anyway, this doesn't allow to create proot'ed environment on sdcard because FS doesn't support symlinks and other kinds of special files.

Ubuntu. Bash is not working due to missing linker symlink:

$ pwd /sdcard/ubuntu $ ls bin dev home media opt root sbin srv tmp var boot etc lib mnt proc run snap sys usr $ proot -R . /bin/bash proot error: execve("/bin/bash"): No such file or directory proot info: possible causes:

$ cp ./lib/aarch64-linux-gnu/ld-2.27.so ./lib/ld-linux-aarch64.so.1 $ proot -R . /bin/bash /bin/bash: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory Okay, library can be renamed/copied. But it is not working anyway:

$ cp ./lib/aarch64-linux-gnu/libtinfo.so.5.9 ./lib/aarch64-linux-gnu/libtinfo.so.5 $ proot -R . /bin/bash /bin/bash: error while loading shared libraries: libtinfo.so.5: failed to map segment from shared object


What is the armhf equivalent of those code blocks you posted? I'm wanting to try that on my old galaxy tab a 8.0
@RohitVerma882 
ZhymabekRoman commented 1 year ago

Has anyone tried mounting multiple img files to make the root filesystem? .img to allow symlinks etc, and multiple to allow > 4gb ?

If you have root permissions you can try it

Austcool-Walker commented 1 year ago

Has anyone tried mounting multiple img files to make the root filesystem? .img to allow symlinks etc, and multiple to allow > 4gb ?

If you have root permissions you can try it

How Can we create an ext4 for formatted img with a custom size with root and mount it? I want a big ext4 img because I have a 1TB sdcard so like a 100GB ext4 .img for example mounted on a path /storage/external_sd/ubuntu ? @ZhymabekRoman Can I use fallocate -l 100G bionic.img ?

xloem commented 1 year ago

To clarify, you presently need to perform new systems-style software development to do this without root.

The example block was made by building a proot branch from source. Are you saying the code is x86 only?

If you find other resources that help with this, such as when the user already has root, or associated with UserLAnd or with another non-Termux distribution, or can try out App2SD, posting your experience here could help visitors.

Austcool-Walker commented 1 year ago

To clarify, you presently need to perform new systems-style software development to do this without root.

The example block was made by building a proot branch from source. Are you saying the code is x86 only?

If you find other resources that help with this, such as when the user already has root, or associated with UserLAnd or with another non-Termux distribution, or can try out App2SD, posting your experience here could help visitors.

I have root mounting an img if it works I don't mind tbh

Austcool-Walker commented 1 year ago

With busybox root and truncate or in my case fallocate mkfs.ext4 /storage/external_sd/bionic.img then tsu busybox mount -oloop /storage/external_sd/bionic /storage/external_sd/ubuntu it mounts a ext4 filesystem. then resize2fs -d -s -p ./bionic.img 100G is attempting to resize the image to the size I need for my ubuntu install.

Austcool-Walker commented 1 year ago

I have no idea if I can proot or in my case busybox chroot there tho.

Austcool-Walker commented 1 year ago

I got the img method working with root! Proot! So yeah it can be done using a img mount all on external_sd