5.1.1.2 open()
The following describes the call sequence of an open() call to create a file:
1. Call the open() system call with a relative pathname and flags to create a file for read and write.
2. open() calls open_namei(), which ultimately derives the dentry for the directory in which
the file is being created. If the pathname contains multiple directories, search permission for all
directories in the path is required to get access to the file.
This search permission check is performed for each directory dentry by calling permission().
If the operation vector of the inode, which contains pointers to valid inode operation routines, is
set, then each call to permission() is diverted to the disk-based file system-specific permission
call. Otherwise, generic_permission() is called, to ensure that the process has the appropriate
permission. If at this stage the process has the DAC permission, because either the generic or disk-
based file system granted the permission, then AppArmor permission is checked through the
security_inode_permission() LSM call.
3. Once the directory dentry is found, permission() is called to make sure the process is
authorized to write in this directory. Again, if the operation vector of the inode is set, then the call
to permission() is diverted to the disk-based file system-specific permission call; otherwise
generic_permission() is called to ensure that the process has the appropriate permission. If at
this stage the process has the DAC permission, because either the generic or disk-based file system
granted the permission, then AppArmor permission is checked through the
security_inode_permission() LSM call.
4. If the user is authorized to create a file in this directory, then get_empty_filp() is called to get
a file pointer. get_empty_filp() calls memset() to ensure that the newly allocated file
pointer is zeroed out, thus taking care of the object reuse requirement. To create the file,
get_empty_filp() calls the disk-based file system-specific open routine through the file
operations vector in the file pointer.
At this point, data structures for the file object, dentry object, and inode object for the newly created file
are set up correctly, whereby the process can access the inode by following a pointer chain leading from the
file object to the dentry object to the inode object. The following diagram shows the simplified
linkage:
37
Figure 5-6: VFS data structures and their relationships with each other