The Unix Filesystem

Under unix we can think of the filesystem as everything being a file. Thus directories are really nothing more than files containing the names of other files and so on. In addition, the filesystem is used to represent physical devices such as tty lines or even disk and tape units.

Each file on the system has what is called an inode that contains information on the file. To see the fields of the inode look at manual page of the stat system call. This shows the following fields:

    struct stat {
       dev_t   st_dev;    /* device inode resides on */
       ino_t   st_ino;    /* this inode's number */
       u_short st_mode;   /* protection */
       short   st_nlink;  /* number or hard links to the file */
       short   st_uid;    /* user-id of owner */
       short   st_gid;    /* group-id of owner */
       dev_t   st_rdev;   /* the device type, for inode that is device */
       off_t   st_size;   /* total size of file */
       time_t  st_atime;  /* file last access time */
       int     st_spare1;
       time_t  st_mtime;   /* file last modify time */
       int     st_spare2;
       time_t  st_ctime;   /* file last status change time */
       int     st_spare3;
       long st_blksize; /* optimal blocksize for file system i/o ops */
       long st_blocks;  /* actual number of blocks allocated */
       long st_spare4;
       u_long st_gennum; /* file generation number */
         };

The key fields in the structure are st_mode (the permission bits), st_uid the UID, st_gid the GID, and st_*time (assorted time fields).

The ls -l command is used to look at all of those fields.

umbc4:gopher> ls -l dead.letter
-rw-rw-rw-  1 gopher        307 Sep 14 12:33 dead.letter

umbc4:gopher> ls -F www
acsinfo/    index.html  irc.gif     logo.gif    umbcfaq/

File times.

Unix records three file times in the inode, these are referred to as ctime, mtime, and atime. The ctime field refers to the time the inode was last changed, mtime refers to the last modification time of the file, and atime refers to the time the file was last accessed.

The ctime file of the inode is updated whenever the file is written too, protections are changed, or the ownership changed. Usually, ctime is a better indication of file modification than the mtime field. The mtime and atime fields can easily be changed via a system call in C (or a perl script). The ctime field is a little harder to change, although not impossible.

File times are important because the are used in many ways by system administators. For example, when performing backups, an incremental dump will check the mtime of the inode to see if a file has been modified and should be written to tape. Also, system administrators often check the mtime of certain key system files when looking for signs of tampering (while sometimes useful, a hacker will sufficient skill will reset the mtime back). Finally, when managing disk space , some sites have a policy where files not accessed in a cetain time are marked for archival, it is not uncommon to have certain users deliberately set the atime or mtime to defeat this policy.

File Permissions

File permissions ae used to control access to files on the system. Clearly in a multi-user system some method must be devised that allows users to select files for sharing with other users while at the same time selecting other files to keep private. Under Unix, the inode maintains a set of 12 mode bits. Three of the mode bits correspond to special permissions, while the other nine are general user permissions.

The nine general file permissions are divided into three groups of three. The three groups correspond to owner, group, and other. Within each group there are three distinct permissions, read, write, and execute. The nine general file permissions are listed via the ls -l . The following table sumarizes the file permissions:

Read (r)
Read access means you can open the file with the open system call and can read the contents of the file with the read system call.
Write (w)
Write access means you can overwrite the file or modify itŐs contents. It gives you access to the system calls write and truncate.
Execute(x)
Execute access means you can specify the path of this file and run it as a program. When a file name is specified to the shell the shell examines the file for execute access and calls the exec system call. The first two bytes of the file are checked for the system magic number, signifying the file is an executable. If the magic number is not contained in the first two bytes the file is assumed to be a shell script.
The file permissions described above apply to plain files, devices, sockets, and FIFOs. These permissions do not apply to directories and symbolic links. Symbolic links have no permission control on the link, all access is resolved by examining the permissions on the target of the link.

Some anomalies can develop, for examaple, it is possible to set permissions so that a program can be run but the file cannot be read. Also, it is possible to set permissions so that anyone on the system, except members of your group can read the file.

Directory permissions

While directories are considered to be part of the file system the protection the mode bits take on different meanings in the context of directory files.
Read (r)
Read access permits the opendir and readdir system calls to be performed on the directory file. Read access on a directory will allow you to see the file names in the directory file.
Write (w)
Write access allows you to add or remove file names from the directory file. With write access I can add files to a particular directory or use the rm command to delete a file.
Execute(x)
Execute access allows access to the stat system call to displays the values in the inode (such as the ls command does). You must have execute access to the directory to make it your current directory or to open files inside that directory.

SUID, SGID, and Sticky bit file permissions

Unix allows programs to be endowed with privileges that belong to another user (such as root). Unix uses three of the twelve mode bits to support special permissions. These permissions are named SetUID (SUID), SetGID (SGID), and sticky bit permissions. Files that have the SUID bit set will run with effective user UID of the owner of the file. Files that have the SGID bit set will run with the effective group ID of the group owner of the file. Files with the sticky bit have special properties. Regular files with the sticky bit set are supposed to remain in the swap file after they have finished execution. This was to provide better performance to the system and not force commonly accessed programs to be loaded from swap each time. On directory files, the sticky bit is interpreted in such a way that only the owner of the file in that directory can delete a file. This is generally used with the /tmp directory so that users cannot delete other users files even though all users The SUID and SGID permissions are indicated with the ls -l command. A s in the execute field for owner or group indicates SUID or SGID respectively. The sticky bit is indicated in the ls -l command by a t in the execute bit for others.

Setting file protections

Umask

The umask command sets the default file protection for your process. The default file protection on the system is 0666, a umask value is subtracted from the default to give a new user specified default. Thus a umask of 0077 denies all users except your own. A umask of 022 elimiantes execute mode.

Chmod

The chmod [-Rf] mode filelist command (change mode) sets the file permission for a set of files. The command supports two options -R and -f. The -R option is used to recursively move down through the file system and select files matching the filelist. The -f option is used to keep errors from being reported back (when used in shell scripts). The values you can specify are either a absolute mode mask or a set of letters. When using the absolute mode mask the value is specified as an three digit octal number and each octal number corresponds to a user category (owner, group, or other). Since an octal number requires three bits each bit of the number corresponds to a file permission (read, write, or execute). Thus using the octal number 7 which has a binary value of 111 which implies read,write, and execute access.

Common file setting

0755
Owner has RWX, Group has RX, Others have RX.
0700
Owner has RWX, Group has none, Other have none
4755
Owner has RWX, Group has RX, Others have RX, SUID bit is set.
ite by group

Problems with SUID

SUID programs have a place on the system, in fact it would be difficult, if not impossible, to run Unix without SUID programs. For example, the file /bin/passwd is a SUID program owned by root. This makes sense, you want to restrict access to changing passwords in some way and SUID is a good way to do that. That said, SUID programs are the most frequent way that security is compromised. Problems with SUID programs fall into the following two categories.
Carelessness
The root user leaves an unattended root window and someone uses that window to create a backdoor into the system.
Poor Software Design.
Often programs are written SUID that can be written without being SUID root. Also, many programmers don't fully understand the consequences of the code they write and leave unintended back doors into the system.
To identify SUID programs on your system use the command find . The find command with the correct options will list all files that are SUID or SGID on the system.

find / -perm -004000 -o -perm -002000 -type f -print

Changing ownership of a file.

The chown command is used to change the ownership of files on the system. The format of the command is

chown [-Rf] owner.group

Under BSD based systems you must be root to use the chown command. Under SYSV, the chown command can be run by any user. This has interesting implications when running diskquotas. You will occasionally see users give files to other users so the file will count against the disk quota of the new owner. There is also a chgrp command for changing group ownership only. The chown command can set both the owner and group of a file and is the command generally used.

Creating Links

Unix provides both hard and symbolic links to files. Hard links must reside on the same filesystem. A hard link is essentially a direct reference to the file by a another name. Both files share the same inode and the inode increases the reference count of the file by one for each link. The ln command creates hard links. The format of the command is ln existing-file new-file.

A symbolic link is a file that indirectly points to another file. While the affect is the same as a hard link a symlink does not increase the reference count of a file. A symbolic link also can point to files on other file systems and files that don't even exist! The ln -s command creates a symbolic link. The format of the command is ln -s existing-file new-file. Symbolic links can greatly aid a system administrator when file systems must be redone. Through the use of symbolic links you can create your own view of the file system to keep up consistency for users. Jack Suess//jack@umbc.edu