Open cbonet-sw opened 2 years ago
Try accessing through Termux storage directory like ls $HOME/storage/external-1/
.
Thanks for the suggestion, but I did try that with the same result. After rebuilding the links by running termux-setup-storage again, I also verified that the symlink it created at $HOME/storage/external-1 pointed to the same directory I had been attempting to access by the direct path under /storage/3934-6139/Android/data/....
revoking then granting again the Android file storage permission for the Termux app
Considering you have already done this, could be some other bug or policy change.
Attempt writing and then immediately run adb logcat -d > logcat,txt
from pc (or termux with adb wireless) and check for avc
or other permission denials near the end for termux.
I have now had time to investigate this further.
Curiously, in fact I do actually still seem to have the ability to read files located in the Termux Private directory on the External SD card, what is being blocked is actually listing the contents of directories (and sub-directories) using 'ls'. If I know the exact pathname of a file within this private directory, then I can still 'ls' that specific file, and I can still read the contents of that file.
Also, I do now seem to have read access (and can 'ls') files stored within the 'public' directories on the external SD card (eg. 'Documents', 'Download', etc.). This is very unusual, since I recall that when I first experienced the upgrade to Android 11, I lost all access to the public areas of the SD card from within Termux, and the only way I could use the SD card was via Termux's private directory on the SD card. That, of course, complicated accessing files on the SD card from outside the Termux environment, other than through SAF using Termux's DocumentProvider interface.
So, it would appear that a work-around to allow me to continue using the external SD card with Termux at the moment would be to move to using a public subdirectory on the SD card, eg. something like ${EXTERNAL_SD_ROOT_PATH}/Documents/Termux and manually set symlinks in ~/storage/ to point to this. Then I could use adb to move the 'trapped' files currently in Termux's private directory to this new public directory. This would
I will try implementing this as a (temporary) work-around shortly.
I'm going to post more detailed debugging information regarding this issue in separate message(s) in a few moments...
Doing a "adb logcat -d
" after running a "ls -l
" within Termux that failed, we find no SELinux
warnings; grepping for 'avc' or 'audit' only reveals grants of executing bash:
10-27 09:24:48.334 3622 3622 E audit : type=1400 audit(1666859088.331:127945): avc: granted { execute } for pid=15666 comm="bash" name="coreutils" dev="mmcblk0p32" ino=280848 scontext=u:r:untrusted_app_27:s0:c173,c257,c512,c768 tcontext=u:object_r:app_data_file:s0:c173,c257,c512,c768 tclass=file SEPF_SM-A105FN_11_0010 audit_filtered
10-27 09:24:48.334 3622 3622 E audit : type=1300 audit(1666859088.331:127945): arch=40000028 syscall=334 per=8 success=yes exit=0 a0=ffffff9c a1=f356b728 a2=1 a3=0 items=0 ppid=15318 pid=15666 auid=4294967295 uid=10429 gid=10429 euid=10429 suid=10429 fsuid=10429 egid=10429 sgid=10429 fsgid=10429 tty=pts1 ses=4294967295 comm="bash" exe="/data/data/com.termux/files/usr/bin/bash" subj=u:r:untrusted_app_27:s0:c173,c257,c512,c768 key=(null)
10-27 09:24:48.334 3622 3622 E audit : type=1327 audit(1666859088.331:127945): proctitle=2F646174612F646174612F636F6D2E7465726D75782F66696C65732F7573722F62696E2F62617368002D6C
10-27 09:24:48.335 3622 3622 E audit : type=1400 audit(1666859088.331:127946): avc: granted { execute } for pid=15666 comm="bash" name="coreutils" dev="mmcblk0p32" ino=280848 scontext=u:
Information on Android permissions:
Permission from Termux App Manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.DUMP" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
Permissions granted from adb dumpsys package com.termux
command:
installPermissionsFixed=true
pkgFlags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ]
declared permissions:
com.termux.permission.RUN_COMMAND: prot=dangerous, INSTALLED
requested permissions:
android.permission.ACCESS_NETWORK_STATE
android.permission.INTERNET
android.permission.WRITE_EXTERNAL_STORAGE: restricted=true
android.permission.WAKE_LOCK
android.permission.VIBRATE
android.permission.FOREGROUND_SERVICE
android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
android.permission.SYSTEM_ALERT_WINDOW
android.permission.READ_LOGS
android.permission.DUMP
android.permission.WRITE_SECURE_SETTINGS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.PACKAGE_USAGE_STATS
android.permission.READ_EXTERNAL_STORAGE: restricted=true
android.permission.ACCESS_MEDIA_LOCATION
install permissions:
android.permission.NFC: granted=true
android.permission.FOREGROUND_SERVICE: granted=true
android.permission.RECEIVE_BOOT_COMPLETED: granted=true
android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS: granted=true
android.permission.INTERNET: granted=true
android.permission.TRANSMIT_IR: granted=true
android.permission.CHANGE_WIFI_STATE: granted=true
android.permission.ACCESS_NETWORK_STATE: granted=true
android.permission.SET_WALLPAPER: granted=true
android.permission.USE_FINGERPRINT: granted=true
android.permission.REQUEST_DELETE_PACKAGES: granted=true
android.permission.VIBRATE: granted=true
android.permission.ACCESS_WIFI_STATE: granted=true
android.permission.USE_BIOMETRIC: granted=true
android.permission.WAKE_LOCK: granted=true
User 0: ceDataInode=311297 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
User 95: ceDataInode=0 installed=false hidden=false suspended=false distractionFlags=0 stopped=true notLaunched=true enabled=0 instant=false virtual=false
User 150: ceDataInode=0 installed=false hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
Shared users:
SharedUser [com.termux] (afb1fa2):
userId=10429
Packages
PackageSetting{45634ff com.termux/10429}
PackageSetting{8393b4e com.termux.api/10429}
PackageSetting{feea228 com.termux.widget/10429}
install permissions:
android.permission.NFC: granted=true
android.permission.FOREGROUND_SERVICE: granted=true
android.permission.RECEIVE_BOOT_COMPLETED: granted=true
android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS: granted=true
android.permission.INTERNET: granted=true
android.permission.TRANSMIT_IR: granted=true
android.permission.CHANGE_WIFI_STATE: granted=true
android.permission.ACCESS_NETWORK_STATE: granted=true
android.permission.SET_WALLPAPER: granted=true
android.permission.USE_FINGERPRINT: granted=true
android.permission.REQUEST_DELETE_PACKAGES: granted=true
android.permission.VIBRATE: granted=true
android.permission.ACCESS_WIFI_STATE: granted=true
android.permission.USE_BIOMETRIC: granted=true
android.permission.WAKE_LOCK: granted=true
User 0:
gids=[3003]
runtime permissions:
android.permission.READ_SMS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|RESTRICTION_INSTALLER_EXEMPT|RESTRICTION_UPGRADE_EXEMPT]
android.permission.READ_CALL_LOG: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|RESTRICTION_INSTALLER_EXEMPT|RESTRICTION_UPGRADE_EXEMPT]
android.permission.ACCESS_FINE_LOCATION: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.BODY_SENSORS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.READ_EXTERNAL_STORAGE: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|RESTRICTION_INSTALLER_EXEMPT|RESTRICTION_UPGRADE_EXEMPT]
android.permission.ACCESS_COARSE_LOCATION: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.READ_PHONE_STATE: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.SEND_SMS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|RESTRICTION_INSTALLER_EXEMPT|RESTRICTION_UPGRADE_EXEMPT]
android.permission.CALL_PHONE: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.CAMERA: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.WRITE_EXTERNAL_STORAGE: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|RESTRICTION_INSTALLER_EXEMPT|RESTRICTION_UPGRADE_EXEMPT]
android.permission.RECORD_AUDIO: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.READ_CONTACTS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.ACCESS_BACKGROUND_LOCATION: granted=false, flags=[ REVOKE_WHEN_REQUESTED|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|RESTRICTION_INSTALLER_EXEMPT|RESTRICTION_UPGRADE_EXEMPT]
android.permission.ACCESS_MEDIA_LOCATION: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
User 95:
gids=[3003]
runtime permissions:
android.permission.READ_SMS: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.READ_CALL_LOG: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.READ_EXTERNAL_STORAGE: granted=false, flags=[ REVOKE_WHEN_REQUESTED|APPLY_RESTRICTION]
android.permission.SEND_SMS: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.WRITE_EXTERNAL_STORAGE: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.ACCESS_BACKGROUND_LOCATION: granted=false, flags=[ REVOKE_WHEN_REQUESTED|APPLY_RESTRICTION]
android.permission.ACCESS_MEDIA_LOCATION: granted=false, flags=[ REVOKE_WHEN_REQUESTED]
User 150:
gids=[3003]
runtime permissions:
android.permission.READ_SMS: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.READ_CALL_LOG: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.READ_EXTERNAL_STORAGE: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.SEND_SMS: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.WRITE_EXTERNAL_STORAGE: granted=false, flags=[ APPLY_RESTRICTION]
android.permission.ACCESS_BACKGROUND_LOCATION: granted=false, flags=[ APPLY_RESTRICTION]
This message contains a mixture of Termux and adb shell sessions looking at file accesses and file modes:
The curious thing is that in Termux we can use 'ls' to query a particular directory, but not read the contents of the directory. However, if we already know the name of an object within that directory, we can explicitly query the object with 'ls' using its full path (and then any objects within sub-directories, providing we know their exact pathnames).
Termux session:
~ $ ls -lZ /storage/3934-6139/Android/data/com.termux/files
ls: cannot open directory '/storage/3934-6139/Android/data/com.termux/files': Permission denied
~ $ ls -lZd /storage/3934-6139/Android/data/com.termux/files
drwxrwx--- 16 u0_a429 everybody ? 131072 Sep 18 08:14 /storage/3934-6139/Android/data/com.termux/files
~ $ id
uid=10429(u0_a429) gid=10429(u0_a429) groups=10429(u0_a429),3003(inet),9997(everybody),20429(u0_a429_cache),50429(all_a429)
Things to note:
Looking through the directory hierarchy in a Termux session:
~ $ pwd
/data/data/com.termux/files/home
~ $ ls -lZd .
drwx------ 29 u0_a429 u0_a429 ? 4096 Oct 27 13:59 .
~ $ ls -lZ /data
ls: cannot open directory '/data': Permission denied
~ $ ls -lZ /storage
ls: cannot open directory '/storage': Permission denied
~ $ ls -lZd /storage
drwx--x--x 5 shell everybody ? 100 Oct 27 10:34 /storage
~ $ ls -lZd /storage/3934-6139
drwxrwx--- 33 root everybody ? 131072 Oct 27 10:34 /storage/3934-6139
~ $ ls -lZd /storage/3934-6139/Android
drwxrwx--- 6 root everybody ? 131072 Oct 6 2021 /storage/3934-6139/Android
~ $ ls -lZd /storage/3934-6139/Android/data
drwxrwx--- 218 root everybody ? 131072 Oct 27 13:11 /storage/3934-6139/Android/data
~ $ ls -lZd /storage/3934-6139/Android/data/com.termux
drwxrwx--- 3 u0_a429 everybody ? 131072 Nov 30 2021 /storage/3934-6139/Android/data/com.termux
~ $ ls -lZd /
drwxr-xr-x 26 root root ? 4096 Dec 31 2008 /
where I can understand the denials on listing the contents of '/data' and '/storage' but obviously I can still descend into them via the 'x' bit.
We now use adb
to find the full pathname of a file held within the Termux App's private directory on the external SD card. Take for example the file /storage/3934-6139/Android/data/com.termux/files/test/repodata-idx.txt within Termux's private directory on the external SD card:
Now look for this file from within a Termux session:
~ $ ls -lZd /storage
drwx--x--x 5 shell everybody ? 100 Oct 27 10:34 /storage
~ $ ls -lZd /storage/3934-6139/Android/data/com.termux/files/
drwxrwx--- 16 u0_a429 everybody ? 131072 Sep 18 08:14 /storage/3934-6139/Android/data/com.termux/files/
~ $ ls -lZd /storage/emulated/0/Documents
drwxrwx--- 13 root everybody ? 4096 Oct 19 10:41 /storage/emulated/0/Documents
~ $ ls -lZ /storage/3934-6139/Android/data/com.termux/files/test/repodata-idx.txt
-rwxrwx--- 1 u0_a429 everybody ? 684 Mar 26 2022 /storage/3934-6139/Android/data/com.termux/files/test/repodata-idx.txt
~ $ hexdump -C /storage/3934-6139/Android/data/com.termux/files/test/repodata-idx.txt
[[successfully reads and displays contents of file]]
which demonstrates we can access information (using 'ls') about a specific file (providing we know its full pathname) and even open that file for reading; we just cannot list the contents of directories within app private storage on the external SD card.
Conclusion: there is a problem with using 'ls' to list directory contents of Termux 's private directory (and subdirectories thereof) on the external SD card. This is not just limited to 'ls', other methods within the Termux shell seem to fail in the same way. I presume that this is common to any code that uses the C stdio calls to opendir()
and readdir()
to enumerate directory contents.
On the other hand, we now seem to be fine looking at the 'public' parts of the external SD card that previously we didn't (under Android 11) have access to in Termux: we're ok with the root of external storage and the 'common' directories within this, eg. 'Download' and 'Documents'.
~ $ ls -lZ /storage/3934-6139
~ $ ls -lZ /storage/3934-6139/Documents
~ $ ls -lZ /storage/3934-6139/Download
all succeed and produce a directory listing. Also, /storage/3934-6139/Android and /storage/3934-6139/Android/media can be listed, but not /storage/3934-6139/Android/data.
Looking at some of the directory entries that caused problems under Termux, this time from an adb
session reveals:
a10:/ $ ls /storage/3934-6139/Android/data/com.termux/files/
test
test2
...
a10:/ $ ls -ldZ /storage/3934-6139/Android/data/com.termux/files/
drwxrwx--- 16 u0_a429 everybody u:object_r:fuse:s0 131072 2022-09-18 08:14 /storage/3934-6139/Android/data/com.termux/files/
a10:/ $ ls -ldZ /
drwxr-xr-x 26 root root u:object_r:rootfs:s0 4096 2008-12-31 15:00 /
a10:/ $ ls -ldZ /storage
drwx--x--x 5 shell everybody u:object_r:mnt_user_file:s0 100 2022-10-27 10:34 /storage
a10:/ $ ls -ldZ /storage/3934-6139/
drwxrwx--- 33 root everybody u:object_r:fuse:s0 131072 2022-10-27 10:34 /storage/3934-6139/
a10:/ $ ls -ldZ /storage/3934-6139/Download
drwxrwx--- 16 root everybody u:object_r:fuse:s0 131072 2022-10-27 20:23 /storage/3934-6139/Download
a10:/ $ ls -ldZ /storage/3934-6139/Android/
drwxrwx--- 6 root everybody u:object_r:fuse:s0 131072 2021-10-06 17:09 /storage/3934-6139/Android/
a10:/ $ ls -ldZ /storage/3934-6139/Android/data
drwxrwx--- 218 root everybody u:object_r:fuse:s0 131072 2022-10-27 13:11 /storage/3934-6139/Android/data
a10:/ $ ls -ldZ /storage/3934-6139/Android/data/com.termux
drwxrwx--- 3 u0_a429 everybody u:object_r:fuse:s0 131072 2021-11-30 15:10 /storage/3934-6139/Android/data/com.termux
a10:/ $ ls -ldZ /storage/3934-6139/Android/data/com.termux/files
drwxrwx--- 16 u0_a429 everybody u:object_r:fuse:s0 131072 2022-09-18 08:14 /storage/3934-6139/Android/data/com.termux/files
a10:/ $ ls -lZ /storage/3934-6139/Android/data/com.termux/files/test/repodata-idx.txt
-rwxrwx--- 1 u0_a429 everybody u:object_r:fuse:s0 684 2022-03-26 07:40 /storage/3934-6139/Android/data/com.termux/files/test/repodata-idx.txt
and as we can see, using 'ls' from within an adb
session does reveal the SELinux Contexts on the files.
Problem description
I used to use the Termux private (app-specific) storage directory on external storage (real SD card) to store files that we larger than I wanted to store in private internal storage ($HOME/) but now I don't seem to have permission to access it any more (and I had files stored in there).
This is under Android 11 on Samsung, and the change occurred within the last month: I wonder if it's related to a recent minor update to the Android OS? It might be intentional rather than a Termux bug.
Specifically, I have access to shares external storage at /storage/3934-6139/ but when I access the app-private folder for user files at /storage/3934-6139/Android/data/com.termux/files I get "ls: cannot open directory '/storage/3934-6139/Android/data/com.termux/files': Permission denied"
I have tried
I think Termux should have access itself to files in subdirs beneath /storage/3934-6139/Android/data/com.termux/ and I wonder if it is just shell commands such as ls (implemented through coreutils) that have a problem and if within code of the app itself access is still possible?
Thanks for any insight!
Steps to reproduce the behavior.
ls -l /storage/3934-6139/Android/data/com.termux/files
I get "ls: cannot open directory '/storage/3934-6139/Android/data/com.termux/files': Permission denied"
(obviously substitute the label of the SD card on your system into the pathname above).
What is the expected behavior?
Should give directory listing.
System information