UNIX Computing Security/UNIX filesystem

Suggested topics: volume managers, file systems, files, directories, ls, find, chown, chgrp, chmod, umask, setuid, setgid, device files, ACLs.


Most of the data used by a computer is stored on disk drives. These are physical devices with a relative high access latency, compared to, say, physical memory, but large storage capacity. On a server system a disk drive can be located inside the same cabinet as the CPU, an adjacent expansion cabinet, attached to the network as an appliance, or attached as part of a Storage Area Network. Some sites may also employ removeable disk media that can be loaded by an operator or a robotic device.

Filesystem and files

edit

The filesystem is the method by which data on a device, such as a disk drive, is laid out. It includes information that the operating system can use to find specific data content and who is allowed to access that data. All of this data is organized into a series of files, which are an essential means of managing information on a computer system. The data in a file is organized in a format that applications can understand. The location of a file on a directory tree is called its path.

In UNIX, as on many other modern operating systems, files are stored in a tree structure with the branch nodes being called directories. A directory is a special type of file that can reference zero or more other files and directories, allowing the data to be organized and access managed. Directory trees are contained in one or more filesystems.

In UNIX the filesystem contains the following information available for each file:

  • Unique inode number
  • The length of the file in bytes
  • The identifier of the device that contains the file
  • File type
  • A set of permissions bits, or mode
  • Identifier of the file's owner, or uid
  • Identifier of the file's group, or gid
  • File creation date and time
  • File last access date and time
  • File last modification date and time
  • The total number of hard links to the inode

The typical UNIX file types are as follows:

  • Block file
  • Raw file
  • Regular file
  • Directory
  • Named pipe
  • Symbolic link
  • Socket

A hard link is a type of file that references another file on the same device and file system by means of its inode number. A symbolic link is a type of file that contains the path information to another file.

File permissions

edit

Information about a file's statistics can be viewed by means of the ls command in combination with the -l "long listing" option. Here is an example:

$ ls -l /usr/bin/vi
-r-xr-xr-t  6  bin  bin  604880  Sep  3 2003 /usr/bin/vi

The left-most field of the ls output displays the mode of a file. This is an integer field that is normally 2 bytes (16 bits) in length. Each bit within the mode is a binary flag that represents a type of security access setting.

The number to the right of the mode shows the total number of hard links to the file, including the original file. So this case the command has five other hard links. Next are the names of the file owner and group, followed by the file size in bytes, the date or time of the last modification, and the file name or path.

The ls displays the mode information as a field of ten characters. The first (left-most) character shows the type of the file. The common types are as follows:

- — Ordinary file
b — Block special file
c — Character special file
d — Directory
D — Door (Solaris)
l — Symbolic link
n — Network special file (HP-UX)
p — Named pipe
s — Socket

The remaining nine characters consist of three groups of three characters each. Each of these groups describe a set of file permissions that determine whether a file can be read, write, and executed as a program. (They can also cover certain special execution modes. More on that in a moment.)

These permissions are indicated by an r, w and x, respectively. Thus an rwx in the group set indicates that any member of the file group can read, modify, or run the file as a program (or script). The r-x above is missing the write flag, so members of the group would not necessarily be able to modify the file.

From left to right, the first set of three characters indicates the permission settings for the owner of the file. The middle set are the permission settings for the file group, and the last set to the right are the permissions for every body else (usually referred to as "world".)

Set ID on execute

edit

The mode can also contain special flags that set the permissions of a file when it is executed. That is, if a file is a program or a script, the set permissions bits will determine the owner or group under which it will run. Normally when a job is run, it uses the user and group of the account that executes the file. This controls the type of access that the job gains.

For example, suppose a command myjob has permissions r-xr-x--- and is run by the file owner, user bill in group research. The process that executes the myjob command is given the owner bill and group research. The job can access any file that can also be accessed from the account bill.

Now suppose the myjob file is given owner root, and the set permissions bit for the user are activated by the System Administrator. The resulting file has permission bits r-sr-x---, where the s indicates that the set user ID on execution flag has been set. Because the file still belongs to group research, the user bill is able to run it. When the job is run now, however, it has access to any file that can be accessed by root (which is usually any file on the system.)

A similar effect occurs when the set group ID on execution flag has been set. The resulting file permission bits may now appear as r-xr-s---. When this file is executed, the job runs as though the user belonged to the same group as the file's group identifier. That is, if the group identifier were set to sys, when the file was executed it would have access to any file that can be accessed by the group sys.

It is important to point out at this point that the set ID feature can potentially compromise the security of a system. A file that is owned by root that has the set user ID flag has the same access privileges as the System Administrator. If this file can also be modified by any user, say, then it can be exploited to elevate that user's privileges, or perform other unauthorized activities. Even if the file can not be modified by a user, it may still contain vulnerabilities that can be exploited to gain unauthorized privileges.

For this reason, the existence of files with set user ID or set group ID permissions should be carefully monitored by the System Administrator. Selected system commands require these mode settings in order to function properly. However any other files with these settings, particularly when they can be modified by a user, can represent an unacceptible level of risk to a system. Batch jobs can be run at regular intervals to search for the existence of these files and to bring them to the attention of the System Administrator.

Note: On Linux, when a shell script is executed, all setuid and setgid permissions are ignored intentionally by system.

Directory permissions

edit

The permissions on a directory have a somewhat different meaning than they do for files. The read permissions on a directory allow the ls command, with no arguments to list the contents of that directory. However the read mode only allows the file name to be read, not the file permissions, owner, or size. You also can not change directory with the cd command to a directory where you only have read permissions, nor read the content of files in that directory.

If a directory allows you x, or execute permissions, you can cd to that directory and read the contents of any files in that directory for which you have read privileges. You can also do a "long list" of the directory using the ls -l command. If a directory allows you execute but not read permissions, you get an error if you tried to use ls to list the directory. However, if you knew that a particular file existed in that directory and if that file allowed you read privileges, you could do a "long list" of that file.

As a simple example:

$ id
uid=234(myacct) gid=100(mygrp)
$ mkdir test
$ touch test/test.txt
$ chmod 100 test
$ chmod 640 test/test.txt
$ cd test
$ ls
. unreadable
total 0
$ ls -l test.txt
-rw-r-----   1 myacct mygrp     0 Dec 9 12:00 test.txt

See the appropriate manual pages for further information on these commands.

  • set user ID or set group ID permissions
  • sticky bit.

under construction...

Setting file permissions

edit

The permissions for a file can be set using the chown, chgrp, and chmod commands. The chown is given a valid account name or numerical identifier, and is used to set the owner of a file or set of files. Likewise chgrp can be used to set the group for a file. (On some operating systems, the chown can be used to set both the owner and group of a file. Finally chmod can set the file mode.

Here is an example of a combined chown command that sets the file owner to root and the group to sys:

$ chown root:sys /usr/local/bin/bigjob
Permission Value
Execute (x) 1
Write (w) 2
Read (r) 4

The original format for the chmod command allows the entire mode to be set for a file or set of files. This is done by passing the command a three or four digit number that defines the mode settings. Each of the last three digits in the number represents one of the sets of permission flags, as discussed above. A one (1) enables the execute mode, a two (2) sets the write mode, and a four (4) sets the read mode. Any combination of these modes can be set by adding up the appropriate values.

For example:

$ chmod 550 /usr/local/bin/bigjob

has a 5 for the user permissions, a 5 for the group permissions, and a 0 for the world permissions. A 5 is equal to a 1 plus 4, so this is enabling the read (4) and execute (1) flags for both the user and group. The world gets no privileges for this file.

More recently the chmod command has been enhanced to allow a comma-separated list of symbolic operations. This allows a more refined approach to modifying the mode of a file. A symbolic operation determines who it affects, the type of operation, and the affected permissions. For example:

$ chmod u+x,g-w,o=r /usr/local/bin/bigjob

Here the u, g, and o represent the user, group, and other (world) permissions, respectively. The +, -, and = modify the permissions by adding, deleting, or setting the bits specified by the r (red), w (write), or x (execute) mode bits. This example gives the user execute permissions, removed write permissions for the file's group, and limits other (world) to read operations only.

The chown, chgrp and chmod commands normally have a recursive option that acts upon a directory and all files under that directory tree. This option is typically activated with the -R, but see the manual pages for your particular operating system. When combined with the symbolic operations of the chmod command, this can provide a powerful tool for managing permissions on a directory. For example:

$ chmod -R o-w /usr/bin

will recursively remove any world permission bits on the /usr/bin directory, or any files or directories under that directory tree.

Searching for file permissions

edit

The find can be a powerful tool for searching the file systems for files or directories with particular permission settings, as well as certain file owners and groups. In the example below (which was written for HP-UX) the find command is being used to search the /usr/bin directory tree for any files that allow world write permissions.

$ /usr/bin/find /usr/bin -type f -perm -002 -exec ls -l {} \;

The parameters passed to the find command form an expression that determines what the command is seeking in the directory tree /usr/bin. The arguements -type f restricts the search to files, instead of, say, directories, symbolic links, device files, and so forth. The -perm -002 sets the type of permissions to find; the minus before the number means to only match on the values that are set in the number. In this case the two in the third digit matches the world write bit. Finally the fancy -exec ls -al {} \; causes the command ls -l to be executed on any file that met the prior conditions. (The odd \; clause at the end is a terminator of the command.) Some variant of find has the -ls option which can replace -exec ls -al {} \;.

The example below shows a search of the /home directory tree for any files with an owner that is not in the password database.

$ /usr/bin/find /home -nouser -exec ls -l {} \;

If any accounts have been removed from the password database, a command such as this can be used to search for orphaned files.

Note that whenever the System Administrator is performing a lengthy search of the file system, it can be considerate of the users to run the find at a lower priority using the nice command. Otherwise the job may impact disc access performance. Also some care needs to be exercised to avoid searches of network-mounted directory trees as this can significantly slow the search time; this can be achieved with the help of -xdev option which limits find to search only the current filesystem.

umask

edit

Each UNIX session has a file mode creation mask that defines the initial value of the permission bits when a new file is created. This mask consists of a series of bit flags that determine whether a particular permissions setting will be turned on or off. This value is similar to the number that is passed to the chmod command, except that the values are used in the negative sense. That is, when a value is set in the mask the corresponding permission bit will be turned off when a file is created.

The command umask can be used to display the mask for the current session.

$ umask
027
$ touch testfile.txt
$ ls -al testfile.txt
-rw-r-----  1  bilbo  users    0    Jan 18 07:41 testfile.txt

In this example, the first zero affects the owner's permissions on the file. A zero means that all of the permission bits will be set, so the file owner can have read, write, and execute permissions on that file. (Note that in the example above, the system creates a file with the execute permissions turned off, regardless of the setting of the umask.) The middle number two affects the permissions for the file group. A '2' will turn off the write permission bit, so members of the group will only be able to read or execute the file. Finally the seven in the last digit will turn off all permissions for world.

To change the mask for the session, the umask command can be executed with the new mask passed as a parameter.

$ umask 077
$ umask
077
$ touch testfile2.txt
$ ls -al testfile2.txt
-rw-------  1  bilbo  users    0    Jan 18 07:47 testfile.txt

A umask setting of 077 is recommended for optimal security. The user will then need to manually modify the permissions on a file or directory in order to make it available to others. Conversely, a umask setting of 000 results in the weakest security setting, as anybody on the system can have access to the file unless the user remembers to restrict the permissions. In order to apply a base umask setting, the System Administrator can include a umask command in the shell startup files such as /etc/profile.