Menu
in , , ,

Umask and unusual file permissions and types

In this last entry in our series on Linux file permissions we look at the umask and some more advanced file permissions. We also throw in some discussion of other file types you may see in a directory listing.


The umask

We’ll start with the subject of umask, a means of controlling the permissions on files and directories when they’re first created.

The umask is set when you log in, and is usually set in one of the default shell config files (like /etc/profile). You can override the umask for a particular user by setting their umask in the user’s shell profile, usually in ~/.bashrc. The setting looks something like:

umask 022

The umask octal value is kind of the reverse of chmod permissions — you set it with an octal value, but instead of specifying the permissions you want the created file to have, you specify what you don’t want it to have. For comic book fans, think of it as Bizarro Permission.

In the example above, the 2 set for group and other means, instead of adding write permission to the created file, everything except write permission is added for those two categories. The 0 means all permissions are set for the file owner.

You will sometimes see the umask expressed as four digits, like 0022. Both styles work. That first digit is for setting some special permissions, which we will describe shortly. But the quick version: You usually won’t want to set those with umask, so if you send umask four digits just use a zero as the first digit.

Note that the default behavior for files is to omit the executable permission for all categories. So while the above example only omits the write permission, a file created with that umask would have the octal permissions 644, while a directory would include the executable permissions, and thus be 755.

If you prefer a mathematical way to look at it, take the maximum default permissions (777 for a directory, 666 for a file), then subtract the umask value to get the initial permissions.

Another example to illustrate the point:

umask 027

This one removes write from group and everything from other, making a file that can be read and written to by its owner, read by its group, and denies all access to everyone else. A created directory would be the same, but would also include execute for owner and group.

You can view the current umask setting for your shell session by typing simply:

umask

Symbolic values and umask

You will almost always see the umask set with the octal value assignment. This is mostly because of history and backward compatibility — older shells only support octal values for umask. But current Linux distributions ship with default user shells that support symbolic values for umask (like bash), so if you prefer to go symbolic, you should be fine.

One significant point of note about using symbolic values with umask is that you don’t do the “use the reverse of what you want” thing like you do with octal umask. If you do an assignment of symbolic permissions with umask, it works a lot like it would if you used chmod. The one difference would be that the behavior of not assigning execute permission to regular files when they’re created still applies.

To express the equivalent of umask 022 with symbols, you can directly assign the permissions:

umask u=rwx,g=rx,o=rx

Again, noting that the x permission will only be applied to directories, not regular files. You can also use relative symbols with umask, but that can get a little tricky. If you use relative symbols with umask, like:

umask g+w

Then the adjustment is applied to whatever the current umask is set to. That can be confusing if the default umask gets changed later, though – imagine the above example if someone comes along later and takes group read and execute permission out of the default umask. You’ll end up with files and directories that your group can write to but can’t read or cd into.

So if you know you just want to change the umask for a particular category, it’s best to just use something like:

umask g=rwx

That way you’ll still be using the default for the other category, but you can be sure group will always have the permissions you need set.

It’s handy to know that you can get the symbolic representation of the current umask by passing umask the -S option:

umask -S

For a umask that would create files with the default octal permission 644 and directories with 755, the results of umask checks would look like:

$ umask
0022
$ umask -S
u=rwx,g=rx,o=rx

The high-order bits

There are some other types of permissions you can set that we haven’t really talked about yet. They are the high order permissions. To set them with octal you need to use a four-digit octal number, and the first digit will represent the high-order permissions. The high-order permissions are setuid, setgid, and text (the sticky bit).

Since you may notice them lying around your file system and wonder about them, let’s briefly cover what each is for, and how they look in an ls -l.

Setuid

If the setuid bit is set on a file, when you execute the file the process will run as if it were launched by the file’s owner. If you’re running as user “demo” and run a file owned by root that has “setuid” on it, then when the program runs it will run as if root launched it.

As you might imagine, you want to be careful with this one. The smallest of security holes in a program running as root can lead to pretty big exploits. For this reason most scripts won’t even launch if setuid is set on them.

Setuid is represented by an s in the user category when viewed in ls. A file with setuid looks like:

-rwsr-xr-x 2 root root     122880 2010-04-14 20:12 sudo

When setuid is set on a directory, the system ignores it.

In octal representation, the setuid bit is 4. So setting the permissions in octal for the sudo program above would look like:

chmod 4755 sudo

Symbolically, setuid is s added to the user category only. So adding setuid to sudo could look like:

chmod u+s sudo

Setgid

The setgid permission works like setuid, except it causes a file to run as the file’s group instead of the group of the user that launched it. So a program with the setgid bit on it that’s in the group www-data will always run as if it were launched by a user with the primary group www-data, whether the user that actually launched it is in www-data or not.

A file can have both setuid and setgid active at the same time.

Setgid looks the same as setuid in ls, it just appears in the group category instead of the user category:

-rwxr-sr-x 1 root crontab   31656 2009-05-12 21:58 crontab

In octal representation the setgid bit is 2. So setting the permissions for crontab above would look like:

chmod 2755 crontab

Symbolically, setgid is s added to the group category only. So adding setgid to crontab could look like:

chmod g+s chmod

It’s possible for a file to have setgid set, but not be executable by its group (it’s also possible for this to happen with setuid, but is much less likely). When that happens, setgid is displayed as a capital S instead of the usual lowercase s. If you changed the permissions for crontab in the above example so that only root could run it, but kept setgid active, the end result would look like:

-rwxr-Sr-- 1 root crontab   31656 2009-05-12 21:58 crontab

Directories handle setgid differently. If setgid is set on a directory, every file created in that directory will be created with the directory’s group instead of the creating user’s group. Furthermore, new subdirectories will inherit the setgid bit from the parent directory.

The inheritance behavior of setgid on a directory can be useful if you want a particular directory and all its contents to always be accessible to users in a particular group. You can just put the setgid permission on the parent directory (and any existing subdirectories), then change the default umask so files and directories will be created with group write permissions.

Note that you can’t use setuid or setgid with the -R flag for chmod (for recursive permission changes) — you have to set that permission on each file or directory individually.

The sticky bit

The sticky bit confuses a lot of people. There’s a good reason for this: The sticky bit means different things to different versions of Unix. Fortunately we only need to worry about Linux, so we only have to talk about one implementation of the sticky bit.

The sticky bit is ignored when set on files.

When set on a directory, the sticky bit tells the system that files in that directory can only be renamed or deleted by the user that owns them (and root). The most common use for the sticky bit, and really the only one you’re ever likely to need, is on /tmp:

drwxrwxrwt   5 root root  4096 2010-07-16 02:47 tmp

The t at the end of the permissions is the sticky bit. The letter hearkens back to the sticky bit’s original meaning, which involved caching text in memory. A handy mnemonic might be to think of the sticky bit as the tmp bit or text bit, depending on which association might work best for you.

That’s the trouble with using letters to abbreviate this stuff. Because sticky bit is a memorable name you’ll run into a lot of instances of people mistakenly reading an s in a permissions list as the sticky bit, when s is actually setuid and setgid. You will now know better. Feel free to correct people when they say sticky bit when they mean setuid or setgid. Unless they are particularly large and ill-tempered, in which case it may be best to just let it slide.

Anyway, you probably won’t want to set the sticky bit anywhere else. It’s useful in /tmp because it makes the permissions there a little more restrictive than a directory usually would be with 777 permissions.

In octal representation, the sticky bit is 1. So if you accidentally deleted /tmp (trust me, it can happen) and wanted to recreate it, you could set the octal permissions of your new /tmp with:

chmod 1777 /tmp

A high-order cheat sheet

To summarize the octal values of those high-order permissions:

setuid = 4
setgid = 2
sticky = 1

Other file types

There are file types other than regular files, directories and symlinks that you might see in directory listings, particularly in /dev. These special file types represent ways for programs to talk with other programs or with hardware.

They illustrate part of what made Unix so weird and special at its creation: Treating most interactions similarly to file interactions. It’s not a perfect setup, but the biggest benefit is providing a simple and fairly standard way for programs to talk to other parts of the system.

You might not need to use any of these file types yourself but an overview can be helpful, if only to know something about what the system is doing behind the scenes. Mostly I cover them here because you might see them in a directory listing and want some idea of what the heck they are.

These file types can be recognized by the first letter in an ls -l result, where you’d usually see a - for a regular file, d for a directory, or l for a symlink.

Socket

A socket file is a special type of file that lets a program write to a network interface using the normal file system interface. Instead of doing a write and having the text wind up in a text file, the text gets sent to the network interface.

A socket file is labeled with an s in the first slot, as in:

srw-rw-rw- 1 root   root           0 2010-02-26 22:46 log

That particular example is a socket located at /dev/log. That socket can be used by programs (like logger) to send log entries to a syslog daemon without needing to connect to the daemon directly.

Named pipe

A named pipe basically lets one program put data into the pipe and have another program read it. It’s usually created with the mkfifo command.

You might have been told at some point to pipe data from one program to another with the | separator. If so, then you’ve used an unnamed pipe before. A named pipe is like that, except it lives in the filesystem and can be reused.

A named pipe is labeled with p in the file type slot of a directory listing.

For example, a named pipe at /dev/xconsole might be used by syslog to send logging data to xconsole, which in turn would be displayed to a user running x-windows. In a directory listing it would look like:

prw-r----- 1 syslog adm            0 2010-07-15 17:09 xconsole

Block special file

A block special file is a representation of a block device in the file system. A block device is a piece of hardware that the system would read from or write to in blocks of data, like a hard drive.

A block special file is represented by a b in the directory listing. The hard drive at /dev/sda1 would look like:

brw-rw---- 1 root   disk      8,   1 2010-02-26 22:45 sda1

Character device

A character special file is an interface to a character device. A character device is similar to a block device, but instead of reading from or writing to the interface in blocks, the system talks to the device one character at a time.

Where a block device tends to be something that stores data for later retrieval (like a disk), a character device is usually one where the system only needs to send or receive data of a more immediate nature – like sending a file to a printer, or receiving keystrokes from a keyboard.

A character special file is labeled with a c in a directory listing.

For example, a terminal session is a character device, usually named something like /dev/tty1:

crw------- 1 root root 4, 0 Jun 30 03:29 /dev/tty1

Summary

You probably now know more than you ever wanted to about Linux file permissions and file types. What can I say? I like to be thorough. Most of it is the sort of information you may never need, but when you do (like when you need to change default file permissions, or want to send data easily between programs), it can save you some research time if you know something of what’s possible beforehand.

  • Author: Jered @ SliceHost

Leave a Reply

Exit mobile version