Permissions

Now that we’ve discussed the basic structure of a file system, let’s move on to access permissions. Access permissions are a set of rules that determine who can interact with a file or directory and what operations they can perform. These permissions are crucial for maintaining system security, ensuring privacy, and preventing unauthorized access to sensitive data.

A file’s access permissions are stored in a 12-bit value called its mode; the first three bits are special file access modifier bits called the Set-User ID, Set-Group ID, and Sticky bits. Next come three sets of three access bits (read, write, and execute), for each of the file ownership classes: user, group, and other.

File Ownership

Each file is independently owned by a user and group; these values are set to the user id and primary group id of the user that creates the file. The owner of a file can change the file’s group to any group that user is a member of, but administrator capabilities are required to change a file’s user, or to change its group to one that its owner is not a member of.

A user can belong to one or more groups. When a user is created, it must be assigned a primary group; generally, a group with the same name as the new user is simultaneously created and assigned as a user’s primary group, of which they are the only member. An administrator can then add the user to additional groups, and that user may freely change its own primary group to any group it belongs to.

Group ownership serves two primary purposes in Unix: facilitating file sharing among a group of users, such as a project team, and providing a convenient way to manage access to system resources without the need to manually manage individual user permissions for each resource.

For instance, to access a system’s sound and video devices, users typically need to belong to the audio and video groups, respectively. Additionally, many Unix systems have a special wheel[1] group, which grants its members superuser status. This allows them to masquerade as any other user on the system, including the root user, on demand.

If a process’s EUID is the owner of a file, its access permissions are determined by the “user” mode bits. If it is not the owner of a file, but its EGID matches the group which owns it, its access permissions are determined by the “group” mode bits. Finally, if neither applies, permissions are determined by the “other” mode bits. Notice that permissions do not stack, meaning the first applicable set of permissions (user, group, or other) is used.

In general, the “user” permissions are at least as permissive as “group” permissions, and “other” permissions tend to be the least permissive. However, there are situations where it might be desirable to set permissions differently; for example, the root user might unset the user execute permission on a utility they own and manage, but set the other execute permission. This might be the case if the utility were meant to be run by regular users but would be dangerous if accidentally run by the root user.

Special Permission Bits

There are three additional special permission bits that can be set on files and directories:

  • Set User ID (SUID): When the SUID bit is set on an executable file, the process runs with the privileges of the file’s owner, rather than the user who started the process.

  • Set Group ID (SGID): When the SGID bit is set on an executable file, the process runs with the privileges of the file’s group, rather than the user’s group. When set on a directory, it ensures that new files and directories inherit the group ownership of the parent directory.

  • Sticky Bit: When the sticky bit is set on a directory, only the owner of a file within that directory can delete or rename their file, even if other users have write access to the directory.

Set User ID Bit

The SUID bit is often used to allow users to run certain programs with elevated privileges without needing to have those privileges themselves. For example, all user passwords are stored in a single system password file which is owned by the root user. In order to change their passwords, users can run the passwd utility, which is owned by the root user and has its SUID bit set. The passwd utility is then able to access and modify the password file without exposing other users’ passwords to an user. SUID programs can be a security risk if they are not properly designed and implemented, as they can be used to gain elevated privileges and execute unauthorized actions.

The way this works is that the file in question is executed so that the resulting process has a UID equal to its parent process, but with an EUID that is set to the user ID that owns the executable. A process can swap its UID and EUID back and forth to perform tasks as either of the two users. It can also elevate itself and fully become the other user by setting its UID to match the EUID, or it can drop privileges by setting its EUID back to the real user ID.

Set Group ID Bit

The SGID bit is usually used to ensure that files created in a directory inherit the group ownership of that directory, rather than the group ownership of the user who created the file. This can be useful in situations where multiple users need to work on files in a shared directory, and those files need to be accessible to all users in a particular group.

For example, consider a directory shared by the members of a project team. The directory can be owned by a project group, and the SGID bit can be set on the directory. When a user creates a new file in the directory, the file will be owned by the project group instead of the user’s personal group. This ensures that all team members can access the file, even if they are not members of the user’s personal group.

The SGID bit is also used on executable files in the same way that the SUID bit is, and results in the GID matching the parent process, but the EGID matching the group ID that owns the file in question.

Sticky Bit

The sticky bit is often used on directories that are shared among multiple users, such as the /tmp directory, to prevent users from accidentally deleting or modifying files owned by other users. By setting the sticky bit on the /tmp directory, each user can write to the directory in order to create temporary files, but they cannot delete or modify files created by other users.

The sticky bit is only meaningful when set on a directory, and is also known as the restricted deletion bit.

Representation of File Mode

The mode of a file can be expressed in both a numeric octal representation and in human readable textual format.

In the octal representation, the mode is usually expressed as a 3-digit octal number, where each digit corresponds to the permissions for the owner, the group, and others, respectively. Each digit is a three-bit value with each bit representing read, write, and execute permissions, respectively. A fourth (leftmost) digit represents the special permission bits, which is often omitted if none are set.

In the human-readable representation, the mode is expressed as a 10-character string, called a modestring, where the first character indicates the file type (e.g., ‘-’ for regular files, ‘d’ for directories, and ‘l’ (el) for symbolic links). The remaining nine characters represent the permissions for the owner, the group, and others, in groups of three characters each. An ‘r’, ‘w’, or ‘x’ appearing in each position indicates the corresponding read, write, or execute permission is set, while a ‘-’ indicates that it is unset.

Unlike with the octal representation, additional characters are not used to represent special permissions. Instead, the ‘x’ position’s character is changed to a different letter. For the SUID and SGID bits, it’s changed to ‘s’ for owner and group classes, respectively. For the sticky bit, it is changed to a ‘t’ for the other class. For any of these classes, if the execute permission isn’t set, but the corresponding special bit is, then a capital ‘S’ or ‘T’ is used, instead.

You can explore how the different mode bits are reflected in both representations, in this interactive exploration,

Permissions and Special Files

Access permissions can work differently for special files like symlinks and directories.

Access permissions affect the behavior of directories in the following ways:

Read (r)

Allows processes to list the contents of the directory.

Write (w)

Allows processes to create, delete, or modify files and directories within the directory.

Execute (x)

Allows processs to access files and directories within the directory and change to it as their working directory.

A process that has read (r) permissions, but not execute (x) permissions, on a directory can see the names of files in the directory but cannot access (change into) the directory or list the contents with details. In contrast, a process that has execute (x) permissions, but not read (r) permissions, on a directory can access (change into) the directory and interact with its files, provided they know the exact filenames, but they are unable to list the names of the files within the directory. This is sometimes used as a very rudimentary secret file-sharing mechanism, where the name of a file is a secret that is hard to guess, so only authorized users can access it by knowing its name; however, it is not very secure.

Permissions aren’t settable on a symlink. A symlink can be created, modified, or destroyed based on the permissions of the parent directory, just like with a hard link. A symlink always shows permissions as “lrwxrwxrwx”, but these permissions do not have any real impact because the actual permissions of the file that it references are what determine access privileges once the symlink has been followed to the target.

Alternative Access Control

Unix also permits alternative access control mechanisms on top of what is described above. For example, Access Control Lists (ACLs) are a flexible and fine-grained approach to managing file permissions in Unix-based systems. They provide a way to set permissions on a per-user or per-group basis, rather than relying solely on the traditional owner, group, and other permissions model. ACLs allow administrators to grant or deny access to specific users or groups, enabling more control over file and directory access.

An ACL consists of a set of entries, each defining the access permissions for a specific user or group. The entries can grant or deny read, write, or execute permissions. ACLs can be applied to both files and directories, and they are typically used in situations where the traditional Unix file permissions model is insufficient or too restrictive. In addition to the standard Unix permissions, ACLs provide a more customizable and precise way to manage access control in complex environments.

Alternative access mechanisms add an 11th character to a mode string. For example, if ACL is enabled on a filesystem, an 11th character is added to the mode string to indicate the presence of an ACL for that file. This 11th character is “+” if an ACL is present for that file, or “.” if there is no ACL for that file.