A quick search reveals that there exist similar unanswered questions (this, this and this). Let me try to demystify it, starting with brief history.
WHAT IS .android_secure
DIRECTORY?
In order to solve the problem of space shortage in internal storage, app2sd
(Move to SD Card) was Android's native feature up to Lollipop. With this method .apk
files (or whole /data/app/<pkg>/
directories) are moved as encrypted .asec
files to .android_secure
folder on external SD card or internal sdcard
partition (mounted at /mnt/sdcard/
or /mnt/media_rw/sdcard[N]/
). On every boot .android_secure
is bind mounted to /mnt/secure/asec/
and the (ext4
) filesystem containers (.asec
) are decrypted (using dm-crypt
) and mounted to individual directories (named after package names) in a temporary filesystem mounted at /mnt/asec/
by vold
. Symlinks from /data/app/<pkg>/
and possibly /data/data/<pkg>/lib/
are pointing towards /mnt/asec/<pkg>/
and /mnt/asec/<pkg>/lib/
.
WHY ACCESS TO .android_secure
IS RESTRICTED?
From the early days of Android, access to android_secure
folder (which later became .android_secure
) was restricted. The commit states:
In order to protect the /android_secure
directory on VFAT removable media from being mucked with by 3rd party applications on the device, we hide the directory with a read-only, zero-sized tmpfs
mounted on-top.
Later in Android 4.4 when FUSE was started being used for emulating SD cards from original mount point (/mnt/media_rw/sdcard1
) to user accessible path (/storage/sdcard1/
), the zero-sized tmpfs
functionality (Ignore attempts to access security sensitive files) was shifted to sdcard
daemon which was used to mount FUSE. In Android 6 the app2sd
method was abandoned in favor of Adoptable Storage (also filesystem UUID was included in mount points).
In Android 7 sdcardfs
support was added in parallel to FUSE and the "Always block security-sensitive files" functionality was added to sdcardfs
in kernel. In Android 9 FUSE was completely removed (from sdcard
daemon) but the sdcardfs
still blocks creation/deletion of .android_secure
directories in the root of emulated filesystem. However as you noticed, it's possible to access the path through original non-emulated mount point i.e. /mnt/media_rw/[UUID]/.android_secure
.
For details on filesystem emulation, see What is /storage/emulated/0/?
WHY ROOT CAN'T ACCESS A DIRECTORY?
How is it ever possible to deny root the ability to list a directory entry?
root
is nothing but kernel's dear user. Kernel doesn't stop UID 0 from doing any harm or good. But there are things which are dearer to kernel than root. It includes SELinux 1, Linux capabilities 2 and obviously the filesystem restrictions like we see with FUSE 3 and sdcardfs
4. And like root cannot delete a file with immutable
attribute 5. It's possible to remove any such restriction or add more by modifying kernel source.
1 See explanation and example.
2 A simple demonstration:
~# setpriv --bounding-set -sys_admin -- sh -c 'id; mount -o ro,remount /'
uid=0(root) gid=0(root) groups=0(root)
mount: permission denied (are you root?)
3 FUSE documentation:
"No other user (including root) can access the contents of the mounted filesystem"
4 UID 0 is checked after filename (.android_secure
) is checked.
5 Why can't I delete this file as root?
RELATED:
------
because the way it is mounted askubuntu.com/questions/429848