Unexpected file permission denied - Magisk

My device is a Xiaomi Mi A2 / Android 8.1, rooted with Magisk v16.0. I am running Termux. Now, look at this:
Code:
$ whoami
u0_a88
$ su
# echo foo >bar
# ls -l bar
-rw-r--r-- 1 root root 4 2018-08-21 22:08 bar
# chown u0_a88.u0_a88 bar
# exit
$ ls -l bar
-rw-r--r-- 1 u0_a88 u0_a88 4 2018-08-21 22:08 bar
$ echo baz >bar
bash: bar: Permission denied
A reboot does not help. The file remains inaccessible to user u0_a88 despites having been made the owner.
What is going on here?

feklee said:
What is going on here?
Click to expand...
Click to collapse
SELinux is going on:
Code:
$ su
# getenforce
Enforcing
To get permissions to bar:
Code:
$ su
# restorecon bar
# exit
$ echo baz >bar

Related

Is there a .bashrc equivalent for android?

See title. Mostly I just want to have some aliases set every time I open terminal emulator or adb shell. Does anyone know if this is possible?
Just dig /init.rc then you may find the way.
biAji said:
Just dig /init.rc then you may find the way.
Click to expand...
Click to collapse
I don't think that works, init.rc looks like it's executed on boot... I'm looking for a file that executes every time a shell is started.
Hi there,
I'm wondering the same thing.
I've tried to create a bashrc
(/.bashrc ; /system/etc/bash.bashrc ; /root/.bashrc ) But none is working.
I'm about to try a different way,
I've cp /system/bin/sh to /system/bin/sh1
then I'll try to replace /system/bin/sh by a shell script that will launch my aliases then sh1
Something like:
Code:
#!/system/bin/sh1
alias lsa='ls -Alh '
[...]
/system/bin/sh1
But i'm not pretty sure It could work properly. Firstly because I remember a gain-super-user manipulation that requires to copy and modify rights on sh. (but it could be ok if the script and the copy of sh have the same rights).
Secondly, because I'm not really OK with this; When I'll remove /system/bin/sh in order to replace it, I'll have no shell for a time (if it crashes, I'll not be able to use sh anymore, even with adb).
So if anybody have an other solution it could be damn cool
Thank you all
EDIT: I've just tried this. It's ok, I've not lost my shell, but the modifications (one alias, and a path export), are not applied.
There is no such file. In fact, the default shell is sh, not bash.
However, there is a solution. Read my post in this thread: http://forum.xda-developers.com/showthread.php?t=518959
lbcoder said:
There is no such file. In fact, the default shell is sh, not bash.
However, there is a solution. Read my post in this thread: http://forum.xda-developers.com/showthread.php?t=518959
Click to expand...
Click to collapse
That is interesting. I'll have to try it. I assume it won't work with ADB? Or am I wrong (please say yes)?
I would have thought that it would work with adb, but when I try this:
adb shell /path/to/bash --rcfile /path/to/bashrc
it seems that its a 1-way shell...
well you can always run bash after connecting....
adb shell
/path/to/bash --rcfile /path/to/bashrc
Alternatively, with a little bit of craftiness, you may be able to replace the sh binary with a script that runs bash.
Sweet, can't wait until I get home.
The best way, and what a lot of the ROM devs are doing now is putting a check/call to /system/init.rc and /data/init.rc so we can add our own customizations. This would include boot time chmod/chowns or aliases if need be. Hell we could put a call to /etc/.profile if we wanted and put all our aliases in there. But we can't do any of that till ROM devs put that call in boot.img->boot.ramdisk->init.rc
Android's default shell /system/bin/sh is a link to mksh in the same directory. It reads /system/etc/mkshrc & ~/.mkshrc
I think it also reads ~/.profile & /etc/profile but I'm not sure & I don't know what order.
See https://www.mirbsd.org/mksh.htm for the documentation.
Also worth noting is that most, if not all, shells read /etc/profile & ~/.profile so anything in there should be very general.
Yes there is
lbcoder said:
There is no such file. In fact, the default shell is sh, not bash.
However, there is a solution. Read my post in this thread: http://forum.xda-developers.com/showthread.php?t=518959
Click to expand...
Click to collapse
Edit /system/etc/mkshrc. You can add your aliases there after the defaults. Type 'alias' from the terminal to see the default aliases that are defined in this file. I believe this file is the master, and when a shell is envoked, the mksh command pipes a hidden copy of this file into the users home directory as .mkshrc for the terminal session.
Also, this is the file to edit to append to your $PATH.
alanthehat said:
Android's default shell /system/bin/sh is a link to mksh in the same directory. It reads /system/etc/mkshrc & ~/.mkshrc
I think it also reads ~/.profile & /etc/profile but I'm not sure & I don't know what order.
See https://www.mirbsd.org/mksh.htm for the documentation.
Also worth noting is that most, if not all, shells read /etc/profile & ~/.profile so anything in there should be very general.
Click to expand...
Click to collapse
/system/etc/mkshrc & ~/.mkshrc
You had the answer right here but you didn't know it
smasraum said:
That is interesting. I'll have to try it. I assume it won't work with ADB?
Click to expand...
Click to collapse
curiously enough my bash aliases work when in the adb shell. I'm running bash on my mac. I guess the alias get expanded by bash before there are sent to adb shell.
Code:
mac $ alias ll
alias ll='\ls -albhFG'
mac $
Code:
mac $ adb shell
[email protected]_a11chl:/ $ ll
drwxr-xr-x root root 2016-10-03 13:10 acct
lrwxrwxrwx root root 2016-10-03 13:24 busybox -> /data/data/com.jrummy.app.managerfree/files/busybox
drwxrwx--- system cache 2016-10-03 14:37 cache
drwxrwx--x system carrier 2016-09-02 15:24 carrier
dr-x------ root root 2016-10-03 13:10 config
Please note this does not work:
Code:
mac $ adb shell ll
/system/bin/sh: ll: not found
On my side, here is what I did :
Code:
adb root
Code:
adb remount
Code:
adb shell
Code:
vim /etc/mkshrc
I added the following line :
Code:
alias ls='ls --color=auto'
Results attached, now I may play with the PS1 to get colors in the prompt....
In nougat, there is a bashrc in
"/system/etc/bash/bashrc"
idk about other versions check and tell me
Code:
uname -a: Linux debian 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u5 (2018-09-30) x86_64 GNU/Linux
[email protected]:/# adb root #restart adb with root permissions
[email protected]:/# adb remount #remount partitions on device read-write
remount succeeded
[email protected]:/# adb shell #run remote, interactive shell
device:/ # test0 #execute command test0
/system/bin/sh: test0: not found
127|device:/ # alias test0='date'
device:/ # test0
Wed Oct 10 15:06:16 +00 2018 #SUCCESS
[email protected]:/# adb root
adbd is already running as root
[email protected]:/# adb remount
remount succeeded
[email protected]:/# adb shell
klteusc:/ # test1
/system/bin/sh: test1: not found
127|klteusc:/ # echo "alias test1='date'">>/system/etc/mkshrc
klteusc:/ # test1
/system/bin/sh: test1: not found
127|klteusc:/ # exit
[email protected]:/# adb shell
klteusc:/ # test1
Wed Oct 10 15:10:41 +00 2018
klteusc:/ # exit
[email protected]:/# adb root
adbd is already running as root
[email protected]:/# adb remount
remount succeeded
[email protected]:/# adb shell
klteusc:/ # test2
/system/bin/sh: test2: not found
127|klteusc:/ # echo "alias test2='date'">>/system/etc/bash/bashrc
klteusc:/ # test2
/system/bin/sh: test2: not found
127|klteusc:/ # exit
[email protected]:/# adb shell
klteusc:/ # test2
/system/bin/sh: test2: not found
dirtygardner said:
Code:
uname -a: Linux debian 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u5 (2018-09-30) x86_64 GNU/Linux
[email protected]:/# adb root #restart adb with root permissions
[email protected]:/# adb remount #remount partitions on device read-write
remount succeeded
[email protected]:/# adb shell #run remote, interactive shell
device:/ # test0 #execute command test0
/system/bin/sh: test0: not found
127|device:/ # alias test0='date'
device:/ # test0
Wed Oct 10 15:06:16 +00 2018 #SUCCESS
[email protected]:/# adb root
adbd is already running as root
[email protected]:/# adb remount
remount succeeded
[email protected]:/# adb shell
klteusc:/ # test1
/system/bin/sh: test1: not found
127|klteusc:/ # echo "alias test1='date'">>/system/etc/mkshrc
klteusc:/ # test1
/system/bin/sh: test1: not found
127|klteusc:/ # exit
[email protected]:/# adb shell
klteusc:/ # test1
Wed Oct 10 15:10:41 +00 2018
klteusc:/ # exit
[email protected]:/# adb root
adbd is already running as root
[email protected]:/# adb remount
remount succeeded
[email protected]:/# adb shell
klteusc:/ # test2
/system/bin/sh: test2: not found
127|klteusc:/ # echo "alias test2='date'">>/system/etc/bash/bashrc
klteusc:/ # test2
/system/bin/sh: test2: not found
127|klteusc:/ # exit
[email protected]:/# adb shell
klteusc:/ # test2
/system/bin/sh: test2: not found
Click to expand...
Click to collapse
You need to manually edit the mksh file and add your command in for it to persistently work.
Just running the command below will work but will be wiped on reboot.
Code:
alias test1='date'
If you need it to stay persistent over reboots manually edit /system/etc/mkshrc
Code:
## Adding the test0 alias via file editing:
taimen:/ # test0
Wed Aug 5 13:09:46 GMT 2020
## Adding test1 alias via command line:
taimen:/ # alias test1='date'
taimen:/ # test1
Wed Aug 5 13:10:06 GMT 2020
## Reboot Device
taimen:/ # reboot
## Check for persistant changes:
taimen:/ # test0
Wed Aug 5 13:04:24 GMT 2020
taimen:/ # test1
/system/bin/sh: test1: not found
Example file that I used:
Code:
# Copyright (c) 2010, 2012, 2013, 2014
# Thorsten Glaser <[email protected]>
# This file is provided under the same terms as mksh.
#-
# Minimal /system/etc/mkshrc for Android
#
# Support: https://launchpad.net/mksh
: ${HOSTNAME:=$(getprop ro.product.device)}
: ${HOSTNAME:=android}
: ${TMPDIR:=/data/local/tmp}
export HOSTNAME TMPDIR
alias test0="date"
if (( USER_ID )); then PS1='$'; else PS1='#'; fi
PS4='[$EPOCHREALTIME] '; PS1='${|
local e=$?
(( e )) && REPLY+="$e|"
return $e
}$HOSTNAME:${PWD:-?} '"$PS1 "
This will stay persistent on reboot.

Busybox not root ?

Hello everybody,
I rooted my dream phone with :
Code:
fastboot boot boot.img
# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
# cd system
# cd bin
# cat sh > su
# chmod 4755 su
All work fine !
I tried to install busybox like this :
Code:
adb push busybox /data/local/tmp
cat /data/local/tmp/busybox > /system/bin/busybox
chmod 4755 /system/bin/busybox
No problem with this step, but now if I type :
Code:
$su
#busybox ls /data
I have a permission denied
If I type
Code:
$su
#ls /data
all work fine
(ls is an symbolic link to toolbox)
ls -l /system/bin
Code:
-rwsr-xr-x root root 1745016 2009-07-28 11:01 busybox
-rwsr-xr-x root root 86936 2009-07-28 11:11 su
-rwxr-xr-x root shell 68472 2009-03-03 22:31 toolbox
...
I think busybox is not launch with root permission.. why?
I tried : ln -s busybox ls
but same problem !
What is wrong ?
Thanks.
Any particular reason why you setuid busybox? Try chmod 0755 busybox; chown root:shell busybox

[HOWTO] Root Nexus One 2.2.1 FRG83D without OEM unlock

This guide is for people who want root but want to keep their stock rom, not breaking the warranty, unlocking bootloader etc.
A proud ubuntu user, I am writing this in a new thread purely because the manual rageagainstthecage method and SuperOneClick method did not not work for me, see link to my conclusion below if you care
http://forum.xda-developers.com/showpost.php?p=11305312&postcount=2526
What did work however was via adb shell using psneuter and its fairly simple if you follow the following commands.
This guide assumes you know how to get access to the shell via adb, if you dont then search elsewhere for a useful guide
OK lets get to business!
1. Download the attached nexus_one_softroot.tar from the bottom of this post and extract contents to the same folder as adb
2. Open up your terminal, cd to the same folder as adb and the extracted files
3. Enter the following commands:
Code:
sudo ./adb push psneuter /data/local/tmp/psneuter
sudo ./adb push busybox /data/local/tmp/busybox
sudo ./adb push su /data/local/tmp/su
sudo ./adb shell chmod 755 /data/local/tmp/psneuter
sudo ./adb shell chmod 755 /data/local/tmp/busybox
sudo ./adb shell chmod 755 /data/local/tmp/su
sudo ./adb shell
After this you should see only a $ which tells us that we at the android command line with user privileges only, lets continue
Code:
$ cd /data/local/tmp
$ ls
busybox
su
psneuter
$ ./psneuter
property service neutered.
killing adbd. (should restart in a second or two)
You will now be kicked out of android shell, lets go back in
Code:
sudo ./adb shell
After this you should see only a # which tells us that we root baby! If you want to double check issue this command
Code:
# id
uid=0(root) gid=0(root)
Lets continue on. From this point we will install busybox and su which will make root permanent
Code:
# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
# cd /data/local/tmp
# ./busybox cp busybox /system/bin
# chmod 4755 /system/bin/busybox
# busybox cp su /system/bin
# chmod 4755 /system/bin/su
# exit
For some reason I sometimes have to enter exit twice to leave the android shell. Again, re-access the android shell
Code:
sudo ./adb shell
Now in the android shell we can finish up
Code:
# su
# mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system
# exit
# exit
Lastly we must install Superuser, and I did this from the android market so I knew its the latest version, its simple to get, less command input etc.
Now you have root! I hope this was simple enough to follow, I have not really written a guide before but from lots of searching I just could not find a solution for my Nexus One 2.2.1 FRG83D, especially any guide that uses psneuter.
Anyway, glad to contribute
EDIT - also, being new to starting threads, this may not quite be in the right section of the forum, sorry if thats the case mods
Added link to the thread from Wiki.
upgraded to gingerbread 2.3.3. after copying and setting permissions, got this:
PHP:
$ cd /data/local/tmp
$ ls -l
-rwxr-xr-x shell shell 26248 2010-07-22 10:20 su
-rwxr-xr-x shell shell 1062992 2010-10-16 22:29 busybox
-rwxr-xr-x shell shell 585731 2011-01-08 18:02 psneuter
su
busybox
psneuter
$ ./psneuter
Failed to set prot mask (Inappropriate ioctl for device)
second time threw me out of shell. again adb shell gives this:
PHP:
$ id
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)
mfkr said:
upgraded to gingerbread 2.3.3. after copying and setting permissions, got this:
Code:
$ ./psneuter
Failed to set prot mask (Inappropriate ioctl for device)
Click to expand...
Click to collapse
I believe this is due to a change in the kernel as it is upgraded into gingerbread, the input/output controls have changed, leaving psneuter out of date with the current kernel.
However if an exploit is found with the kernel used in 2.3.3, you can use it in place of psneuter with the above method.

BUG REPORT: SuperSU v2.65 doesn’t know how to cd /sdcard/Download/

SU v2.65 doesn’t know how to cd /sdcard/Download/ - it apparently doesn’t know how to resolve the sdcard symbolic link. The work-around is you have to either
cd /sdcard/Download/ ​before​ you su
exit from su so you can cd /sdcard/Download/ then re-run su
[email protected]:/ # cd /sdcard/Download/
tmp-mksh: cd: /sdcard/Download: No such file or directory
[email protected]:/ # exit
[email protected]:/ $ cd /sdcard/Download/
[email protected]:/sdcard/Download $ pwd
/sdcard/Download
[email protected]:/sdcard/Download $ su
[email protected]:/mnt/shell/emulated/0/Download #
​
This did not happen prior to updating SuperSU.
Environment: Samsung Tab-S (SM-T800), Android 5.0.2, Kernel version 3.4.39-5941801

How To Guide How to temporary change a file on a read-only filesystem in the Android OS

I've mentioned this elsewhere in some of my howtos, but I think this feature is important and useful enough to get its own howto.
Nowadays in the current Android OS version a lot filesystems are mounted read-only and remounting the filesystem read-write does not work anymore. Therefor the files in these filesystems can not be changed anymore.
That's pretty good from a safety standpoint, but sometimes a real showstopper.
But fortunately Android is a Linux based system and therefor there is a solution for this problem called bind mounts. bind mounts are some kind of symbolic links that only exist in memory and are therefor also supported for read-only mounted filesystems. Of course, this is a very simple description for this Linux feature but it should be enough here -- for more in depth details I recommend the Linux documentation.
bind mounts are used by Magisk but they can also be used manually without an installed Magisk - the only requirement for using it manually is root access to the phone.
Here is an example to replace the file /system/etc/hosts with a writable file using a bind mount:
Spoiler: replace the file /system/etc/hosts with a changed version of the file
Code:
#
# use a filesystem that supports all necessary permissions and attributes for the new file
#
# Therefor files in /sdcard/<something> can not be used to replace most of the files in the read-only filesystems
#
# Make sure that the file used to replace the other file is readable by all user that can also read the original file
#
ASUS_I006D:/ # cp -a /system/etc/hosts /data/local/tmp/my_hosts
ASUS_I006D:/ #
# add some additional data to the new file
#
ASUS_I006D:/ # echo "127.0.0.1 www.heise.de" >>/data/local/tmp/my_hosts
ASUS_I006D:/ #
# check the result
#
ASUS_I006D:/ # cat /data/local/tmp/my_hosts
127.0.0.1 localhost
::1 ip6-localhost
127.0.0.1 www.heise.de
ASUS_I006D:/ #
ASUS_I006D:/ # ls -l /system/etc/hosts /data/local/tmp/my_hosts
-rw-r--r-- 1 root root 80 2023-06-11 14:57 /data/local/tmp/my_hosts
-rw-r--r-- 1 root root 56 2009-01-01 01:00 /system/etc/hosts
ASUS_I006D:/ #
# "replace" the file /system/etc/hosts now
#
ASUS_I006D:/ # su - -c mount -o bind /data/local/tmp/my_hosts /system/etc/hosts
ASUS_I006D:/ #
# check the results
#
ASUS_I006D:/ # cat /system/etc/hosts
127.0.0.1 localhost
::1 ip6-localhost
127.0.0.1 www.heise.de
ASUS_I006D:/ #
# add some more data to the file
#
ASUS_I006D:/ # echo "127.0.0.1 www.spiegle.de" >>/system/etc/hosts
ASUS_I006D:/ #
# check the result
#
ASUS_I006D:/ # cat /system/etc/hosts
127.0.0.1 localhost
::1 ip6-localhost
127.0.0.1 www.heise.de
127.0.0.1 www.spiegle.de
ASUS_I006D:/ #
bind mounts are only possible for existing files - bind mounts for non-existent files will fail, e.g:
Spoiler: Example for a bind mount for an non-existent file
Code:
ASUS_I006D:/ $ ls /system/bin/bash
ls: /system/bin/bash: No such file or directory
1|ASUS_I006D:/ $
1|ASUS_I006D:/ $ su - -c mount -o bind /system/bin/sh /system/bin/bash
mount: '/system/bin/sh'->'/system/bin/bash': No such file or directory
1|ASUS_I006D:/ $
bind mounts are also allowed for directories therefor to "create" a new file just copy the directory, create the new file in that new directory, and then do a bind mount for the existing directory.
Example:
Spoiler: create the executable bash by copying the executable sh
Code:
#
# "create" the executable "bash" by copying the executable "sh"
#
# This is only an example that should work on every phone! In real life you should copy a real bash executable to the new directory
#
#
# check for a bash executable in the PATH
#
ASUS_I006D:/ $ which bash
1|ASUS_I006D:/ $
# -> bash does currently not exist on the phone
# create a new directory to be used for the bind mount /system/xbin
#
# Note that this directory must be on a filesystem supporting the standard linux file permissions therefor a directory in /sdcard/<something> is not possible here
# And again the directory used must be readable by all uesrs.
#
ASUS_I006D:/ $ mkdir /data/local/tmp/xbin
ASUS_I006D:/ $
# copy all files from /system/xbin to the new directory
#
ASUS_I006D:/ $ su - -c cp -a -r /system/xbin/* /data/local/tmp/xbin
ASUS_I006D:/ $
ASUS_I006D:/ $ ls -l /data/local/tmp/xbin
total 1772
lrwxrwxrwx 1 root shell 3 2009-01-01 01:00 vi -> vim
-rwxr-xr-x 1 root shell 1813848 2009-01-01 01:00 vim
ASUS_I006D:/ $
# create fake "bash" executable in the new directory
#
ASUS_I006D:/ $ cp /system/bin/sh /data/local/tmp/xbin/bash
ASUS_I006D:/ $
ASUS_I006D:/ $ ls -l /data/local/tmp/xbin
total 2080
-rwxr-xr-x 1 shell shell 312024 2023-06-11 13:56 bash
lrwxrwxrwx 1 root shell 3 2009-01-01 01:00 vi -> vim
-rwxr-xr-x 1 root shell 1813848 2009-01-01 01:00 vim
ASUS_I006D:/ $
# bind mount the directory /system/xbin on the new directory
#
ASUS_I006D:/ $ su - -c mount -o bind /data/local/tmp/xbin /system/xbin
ASUS_I006D:/ $
# and now there is "bash" executable in /system/xbin available
#
ASUS_I006D:/ $ ls -l /system/xbin
total 2080
-rwxr-xr-x 1 shell shell 312024 2023-06-11 13:56 bash
lrwxrwxrwx 1 root shell 3 2009-01-01 01:00 vi -> vim
-rwxr-xr-x 1 root shell 1813848 2009-01-01 01:00 vim
ASUS_I006D:/ $ which bash
/system/xbin/bash
# You can now even copy additional files to the bind mounted directory, e.g.:
ASUS_I006D:/ $ cp /sdcard/Download/zip /system/xbin
ASUS_I006D:/ $
ASUS_I006D:/ $ chmod 755 /system/xbin/zip
ASUS_I006D:/ $
ASUS_I006D:/ $ ls -ltr /system/xbin
total 2576
-rwxr-xr-x 1 root shell 1813848 2009-01-01 01:00 vim
lrwxrwxrwx 1 root shell 3 2009-01-01 01:00 vi -> vim
-rwxr-xr-x 1 shell shell 312024 2023-06-11 13:56 bash
-rwxr-xr-x 1 shell shell 503992 2023-06-11 14:03 zip
ASUS_I006D:/ $
ASUS_I006D:/ $ zip -h
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Usage:
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]
The default action is to add or replace zipfile entries from list, which
can include the special name - to compress standard input.
If zipfile and list are omitted, zip compresses stdin to stdout.
-f freshen: only changed files -u update: only changed or new files
-d delete entries in zipfile -m move into zipfile (delete OS files)
-r recurse into directories -j junk (don't record) directory names
-0 store only -l convert LF to CR LF (-ll CR LF to LF)
-1 compress faster -9 compress better
-q quiet operation -v verbose operation/print version info
-c add one-line comments -z add zipfile comment
[email protected] read names from stdin -o make zipfile as old as latest entry
-x exclude the following names -i include only the following names
-F fix zipfile (-FF try harder) -D do not add directory entries
-A adjust self-extracting exe -J junk zipfile prefix (unzipsfx)
-T test zipfile integrity -X eXclude eXtra file attributes
-y store symbolic links as the link instead of the referenced file
-e encrypt -n don't compress these suffixes
-h2 show more help
Hints
bind mounts are supported by the filesystems ext4, vfat, f2fs. and most probably a lot of other filesystems used on machines running Android.
Be careful when replacing executables, especially when replacing an important file like /system/bin/sh. And you should never replace a file that is just a symbolic link for toybox or busybox.
bind mounts created while the OS is running are only useful for files that are dynamically read by the OS. It does not make sense to replace for example one of the *.rc files using a bind mount because these files are only read once while booting the OS.
The filesystems used for source and target for a bind mount should support the same set of attributes and permissions or the result may not be like expected. E.g. you can not bind mount an executable with a file in the directory /sdcard/<something> because that filesystem for /sdcard does not support the executable permission:
Spoiler: Example for bind mount an executable in /sdcard/Download
Code:
ASUS_I006D:/ $ ls -l /bin/ziptool
-rwxr-xr-x 1 root shell 28688 2009-01-01 01:00 /bin/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ cp -a /bin/ziptool /sdcard/Download/
ASUS_I006D:/ $
ASUS_I006D:/ $ chmod 755 /sdcard/Download/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ ls -l /bin/ziptool /sdcard/Download/ziptool
-rwxr-xr-x 1 root shell 28688 2009-01-01 01:00 /bin/ziptool
-rw-rw---- 1 u0_a121 media_rw 28688 2023-06-11 18:09 /sdcard/Download/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ su - -c mount -o bind /sdcard/Download/ziptool /bin/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ ziptool
/system/bin/sh: ziptool: can't execute: Permission denied
126|ASUS_I006D:/ $ /bin/ziptool
/system/bin/sh: /bin/ziptool: can't execute: Permission denied
126|ASUS_I006D:/ $ ls -l /bin/ziptool
-rw-rw---- 1 u0_a121 media_rw 28688 2023-06-11 18:09 /bin/ziptool
ASUS_I006D:/ $
The source for the bind mount must be in a directory that is readable for all user that use the bind mounted file, e.g.
Spoiler: Example for bind mount an executable in a directory not accessable by all user
Code:
ASUS_I006D:/ $ su - -c cp -a /bin/ziptool /data/adb/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ su - -c ls -l /data/adb/ziptool
-rwxr-xr-x 1 root shell 28688 2009-01-01 01:00 /data/adb/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ su - -c mount -o bind /data/adb/ziptool /bin/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ ziptool
/system/bin/sh: ziptool: inaccessible or not found
127|ASUS_I006D:/ $
127|ASUS_I006D:/ $ file /bin/ziptool
/bin/ziptool: cannot open: Permission denied
ASUS_I006D:/ $
Use the mount command to check if a file is bind mounted. e.g.
Spoiler: Check if a file is bind mounted
Code:
|ASUS_I006D:/ # mount | grep /system/etc/hosts
1|ASUS_I006D:/ #
1|ASUS_I006D:/ # mount -o bind /data/local/tmp/hosts /system/etc/hosts
ASUS_I006D:/ #
ASUS_I006D:/ # mount | grep /system/etc/hosts
/dev/block/dm-33 on /system/etc/hosts type f2fs (rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,fsync_mode=nobarrier)
ASUS_I006D:/ #
To remove a bind mount just do a umount, e.g:
Spoiler: Example for remove a bind mount
Code:
#
# remove the bind mount
#
ASUS_I006D:/ $ su - -c umount /bin/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ which ziptool
/system/bin/ziptool
ASUS_I006D:/ $ ziptool
ziptool: run as ziptool with unzip or zipinfo as the first argument, or symlink
1|ASUS_I006D:/ $
Another method to remove all bind mounts is a reboot of the phone
It's recommended to use a sub directory in the directory /data/local/tmp for executables used in bind mounts, example:
Spoiler: Example for bind mount an executable in /data/local/tmp/
Code:
ASUS_I006D:/ $ mkdir /data/local/tmp/bind_mounts
ASUS_I006D:/ $
ASUS_I006D:/ $ cp -a /bin/ziptool /data/local/tmp/bind_mounts
ASUS_I006D:/ $
ASUS_I006D:/ $ ls -l /data/local/tmp/bind_mounts/ziptool
-rwxr-xr-x 1 shell shell 28688 2009-01-01 01:00 /data/local/tmp/bind_mounts/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ su - -c mount -o bind /data/local/tmp/bind_mounts/ziptool /bin/ziptool
ASUS_I006D:/ $
ASUS_I006D:/ $ ziptool
ziptool: run as ziptool with unzip or zipinfo as the first argument, or symlink
1|ASUS_I006D:/ $
bind mounts are also useful for writable files to be able to revert the changes to a file. Example:
Spoiler: Example for using bind mount for a writable file
Code:
ASUS_I006D:/ $ cat /data/local/tmp/testfile.txt
This is a test file
ASUS_I006D:/ $
#
# create a copy of the writable file
#
ASUS_I006D:/ $ cat /data/local/tmp/testfile_for_tests.txt
This is another test file
#
# bind mount the file with the copy of the file
#
ASUS_I006D:/ $ su - -c mount -o bind /data/local/tmp/testfile_for_tests.txt /data/local/tmp/testfile.txt
ASUS_I006D:/ $
#
# check the result
#
ASUS_I006D:/ $ cat /data/local/tmp/testfile.txt
This is another test file
ASUS_I006D:/ $
#
# add some data to the bind mounted file now
#
ASUS_I006D:/ $ echo "This text will not change the original file" >> /data/local/tmp/testfile.txt
ASUS_I006D:/ $
ASUS_I006D:/ $ cat /data/local/tmp/testfile.txt
This is another test file
This text will not change the original file
ASUS_I006D:/ $
#
# remove the bind mount to restore the original file contents
#
ASUS_I006D:/ $ su - -c umount /data/local/tmp/testfile.txt
ASUS_I006D:/ $
ASUS_I006D:/ $ cat /data/local/tmp/testfile.txt
This is a test file
ASUS_I006D:/ $
Of course, this can also be done by creating a backup copy of the file and restoring the backup copy if necessary. But if the changes to the file make the phone unusable or cause it to crash, it is more difficult to restore the file. If you use a bind mount, the file will be restored "automatically" at the next reboot.
Notes
see the forum entry How to upgrade the OS with another Android "distribution" for an example usage for this method
See the forum entry How To change any file or directory using Magisk for how to use this method in Magisk module for persisent changes
See the forum entry How to make files in /system writable for another exampe how to use this feature in Magisk
Up to version 25.x of Magisk (at least in Magisk v24.x and v25.x) Magisk mounted the /system/bin directory read-write, so that temporary changes for the files in /system/bin were possible. But because of the more or less not existent free space in the filesystem used for /system the use of this feature was very limited. And this feature does not exist in Magisk v26.x or newer anymore.
(see also this forum message: https://forum.xda-developers.com/t/magisk-general-support-discussion.3432382/page-2815#post-88617909 )

Categories

Resources