2

I wrote this testing code, and find that this program can always read the file successfully even after I canceled the read permission when running getchar().

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/types.h> 
int main(){
    int f = open("a.txt",O_RDONLY);
    uint8_t data[200];
    printf("Got %d from read", pread(f, (void *)data, 200, 0));
    getchar();
    printf("Got %d from read", pread(f, (void *)data, 200, 0));
}

This program printed

Got 9 from read

twice, even though I use chmod a-r a.txt during pausing.

I'm pretty sure that I'm just a normal user and my process doesn't have CAP_DAC_OVERRIDE; why doesn't the second pread() return any error?

My guess is, when doing read/write, kernel only check file permission on open file description, which is created with open(), and don't change even I changed the file permission on the underlying filesystem.

Is my guess correct?

Extra question:

  • If I'm right about this, then how about mmaped regions?

  • Do kernel only check permissions recorded in page table when I read/write/execute that mmaped region?

  • Is that true inode data stored in filesystem is only used when creating open file description and mmap region?

  • Yes, permissions are only checked at open time and recorded. So you can't write to a file descriptor that you opened for read-only access regardless of if you are potentially able to write to the file, The kernel consults in memory inodes rather than the ones stored in the filesystem. They differ in the reference count for open files, and mount points get the inode of the mounted file. – icarus Jan 2 at 9:49
  • 1
    When you're using a network file system (such as NFS), the remote side might do additional access checks on every read op that deny access to the file after the chmod, regardless of how permissive the kernel on the local system may be. – Mark Plotnick Jan 2 at 11:05
1

Yes, permissions are only checked at open time and recorded. So you can't write to a file descriptor that you opened for read-only access regardless of if you are potentially able to write to the file.

The kernel consults in-memory inodes rather than the ones stored in the filesystem. They differ in the reference count for open files, and mount points get the inode of the mounted file.

If I'm right about this, then how about mmaped regions?

Same. (PROT_* flags passed to mmap() equivalent to O_RDWR / O_RDONLY / O_WRONLY flags passed to open()).

Do kernel only check permissions recorded in page table when I read/write/excute that mmaped region?

I'm not sure when else it could check permissions recorded in the page table :-). As far as I understand your question: yes.

Is that true inode data stored in filesystem is only used when creating open file description and mmap region?

Inode permissions are also checked for metadata operations, e.g. mkdir() (and similarly open() with O_CREAT).

And don't forget chdir(), which is different from any open() call. (Or at least, it is different from any open() call on current Linux).

I'm not sure about SELinux-specific permissions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.