Understanding the file permissions in Android (and Linux)
Everyone should know how the internal mechanics of the operating system their app is going to run on. Files and permission is a crucial part of any OS.
Let’s start with them, how Android knows which file is accessible by this app and which is not?
Begin with creating file in the app private directory using the following code:
val newFile = File(context.filesDir.absolutePath, "newFile.txt")
FileOutputStream(newFile).use{ outputStream->
outputStream.write("Hello World".toByteArray())
}
Now, if you navigate to the file, it should be in /data/data/<package.name>/files/
. And do ls -l
on this file in adb shell, you will get the following line:
-rw------- 1 u0_a169 u0_a169 11 2024-11-28 09:59 newFile.txt
Let’s break it down, block by block.
First Block: -rw-------
Before first space: -rw-------
is permission block.
The first character in this block represents the file type:
d
means directory |-
means regular file |s
for symbolic link and so on.
In our case, it is a regular file.
The 9 remaining character in this block are separated in three groups, each containing 3 symbols.
First group represents permissions for the owner of this file, second for the group and third for others.
Each symbol in each group represents if a permission is allowed to that particular user i.e owner, group of users or others.
In our case, in first group we have rw-
which means read and write allowed to owner of this file, but not execution, because it would have an x
at third place if execution was allowed.
In second and third group we see all dashes -
means no other permission is allowed to anyone else.
Wit this, we understand that this file has read and write permission to the owner of this file. But who is the owner? Continue reading.
Second Block 1
The second block shows number 1, which is a hard link, which basically means how many other file point to the same location in memory. One file can have more than one hard links but file will be deleted only if hard link count drops to 0. That’s not so important for what I am explaining here.
Third Block u0_a169
This is the user id of the owner. A mapped user ID, but you can call it a user id. When the app is first installed, this UID is assigned to it, even if user never opens the app.
And this user id never changes until you reinstall the app or a choose a different user than primary user, which is not common. That’s why 0 in u0
means primary/default user.
You can look at the user id of the app by running:adb shell ps | grep <package.name>
the very first block will be the userId.
Cool, so you remember the First Block, the Permission block, the first group in that block represented the permission for owner and you said which owner? Well, this owner.
So now you know that any process running with this userId will have read and write permission to this file. Let’s move to next block.
Forth Block u0_a169
Forth block shows the GID of the group that has access mentioned in the 2nd group in the the permission block. In our case, the group id is same as user id, means user is the group here.
Remaining Blocks
11
is the file size in bytes, which is not how much it will take on disk.2024-11-28 09:59
is the creation date timestampnewFile.txt
is the file name.
Moving on, let’s create a file in Downloads directory and check out who can access it.
Here is the code:
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val newFile = File(dir, "newFile.txt")
FileOutputStream(newFile).use{ outputStream->
outputStream.write("Hello World".toByteArray())
}
Let’s navigate to this file using in adb, it should be at /sdcard/Download/
and doing ls -l
will print the following:
-rw-rw---- 1 u0_a169 media_rw 11 2024-11-28 11:14 newFile.txt
Noticed th difference?
Here we have rw-
permissions in both Owner and Group blocks. And we have media_rw
as the GID.
Which means not only this user but this group with id media_rw
also has the permission to read and write this file.
Why media_rw
?
This essentially means any apps that have runtime permission of External Storage can access this file. That is why we can see the file not only in phones Files app but any other app that have this permission.
If you have read so far, I have a question for you, who you do you think have the delete permission to both of those files?
Before you leave
The clap button goes up to 50 if you press and hold it.
Cheers ✌️