A quick search reveals that there exist similar unanswered questions (this, this and this). Let me try to demystify it, starting with brief history.
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/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
vold. Symlinks from
/data/app/<pkg>/ and possibly
/data/data/<pkg>/lib/ are pointing towards
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.
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?
- Android's Storage Journey
- How to save files to external SD card?