Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C file open() function is only setting user level permission in Android

I am using C open() function to create the file in android and set the access permission as required. I am observing that in Android, the open() is only able to set the user level access permission. To give the file necessary group & other level permission I have to explicitly use chmod() after creating the file.

Here is what I am doing,

/*Test code - starts*/
    tmp = open("/data/data/com.application.app1.tests/foo5.txt", O_CREAT | O_RDWR | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); // these permissions doen't seems o work hence will work with chmod
    close(tmp);
    tmp = open("/data/data/com.application.app1.tests/foo7.txt", O_CREAT | O_RDWR | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    close(tmp);
    tmp = open("/data/data/com.application.app1.tests/foo8.txt", O_CREAT | O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
    close(tmp);

    tmp = open("/data/data/com.application.app1.tests/foo55.txt", O_CREAT | O_RDWR | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); // these permissions doen't seems o work hence will work with chmod
    close(tmp);
    chmod("/data/data/com.application.app1.tests/foo55.txt", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    tmp = open("/data/data/com.microsoft.palAWasp.tests/foo77.txt", O_CREAT | O_RDWR | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    close(tmp);
    chmod("/data/data/com.application.palAWasp.tests/foo77.txt", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    tmp = open("/data/data/com.application.app1.tests/foo88.txt", O_CREAT | O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
    close(tmp);
    chmod("/data/data/com.application.app1.tests/foo88.txt", S_IRUSR | S_IRGRP | S_IROTH);

    /*Test code - Ends*/

The output of the following is something like this,

enter image description here

/***************EDIT***************/ Another important observation is that when I tried creating the similar files with the above-mentioned permission bits then the default permission bits are,

-rw------- u0_a100  u0_a100         0 2018-03-26 12:43 foo5.txt
-rw------- u0_a100  u0_a100         0 2018-03-26 12:43 log0.log

and when I try to change the permission bits using chmod it is failing. Please note that chmod is working for files in data directory but not for files on /sdcard/

Please help me in understanding this behavior.

like image 362
Bhupesh Pant Avatar asked Jan 18 '26 13:01

Bhupesh Pant


1 Answers

Probably what you are looking for is set the umask so that the default permissions are assigned as you expect.

Linux umask command

This other link explain how it works. Note the area related with error codes and its explanation.

Setting Permissions

In overview: The system restrict the permissions of a file when it is created based into the umask associated to the process. You can change later the permissions using chmod or fchmod. If the filesystem does not allow some permissions (for example try to set write permissions to a file that is hosted into a read-only filesystem), you will receive an error. This could apply too, if some options when the filesystem is mounted were specified. This could explain the fact that your chmod invoked on the /data is working and not into /sdcard (different filesystems with different umask options associated to them). To know more about your scenario, check errno when the chmod function fail.

In other words:

final_mask = mask_open & ~umask_process & mask_opt_filesystem

where mask_open are the permissions specified into the "open()" function; umask_process is the permissions specified into the umask associated to the process; mask_opt_filesystem are the mask associated to the filesystem that is combined with the above when creating a new file; final_mask is the final mask that represent the permissions to be assigned to the just created file.

Finally, you can change the umask for the current process, and subprocesses, but it is not recommendable, based into the read of the above links, so that, you are doing the right thing with chmod.

If you run "mount" into a terminal inside your Android device, you can see some entries appear the option "mode". This is the mask used for that filesystem. If you run "umask" into the same terminal, you can see the umask applied into the terminal.