The nitty gritty of Unix rights management

Cross-Examination

Article from Issue 177/2015
Author(s):

People applying for IT jobs should brace themselves for the popular interview question about the sticky bit in Unix operating systems. It certainly pays to know.

A frequently asked IT interview question concerns the "sticky bit." I do not personally ask this question when vetting a candidate, because I think anyone who knows the answers is, at best, showing good interview preparation. It does not provide any proof of professional expertise. However, many Silicon Valley companies have the question in their catalog and, as a player in the software industry's major league, you need to know the answer to unnecessary questions.

That's why I picked the topic for the Perl column this month. What is the sticky bit's purpose? Michael Kerrisk's book [2] – as always – helps when it comes to tricky Unix questions. As a hardback, this tome with more than 1,500 pages seems to be designed for bodybuilders, but it is easy to carry around anywhere as an e-book. Those who think they understand the intricacies of programming in Unix will stand back in amazement upon reading this epic book: Even gray-bearded Unix gurus will discover intriguing facts from the depths of this resource, time and time again.

For example, did you know that users on a Unix system can delete a file from a directory even if they do not have any write permissions on the file? Correct: Only write and execute permissions are required for the directory the file is located in, and the file's permissions don't matter at all. Listing 1 creates new directory test in the current directory for demonstration purposes and uses the 0333 octal value to assign permissions of -wx-wx-wx.

Listing 1

file-rm

01 #!/usr/local/bin/perl -w
02 use strict;
03 use Sysadm::Install qw( blurt );
04 use File::Path qw( rmtree );
05
06 mkdir "test";
07 blurt "data", "test/abc";
08 chmod 0333, "test";
09 chmod 0444, "test/abc";
10
11 # d-wx-wx-wx test
12 # -r--r--r-- test/abc
13
14 unlink "test/abc"
15   or die "unlink failed: $!";
16
17 rmtree "test";

Deleting Without Rights

The chmod instruction in line 9 uses the octal value 0444 to assign permissions of -r--r--r-- to the abc file created using the blurt() function from the CPAN Sysadm::Install module. All users are thus allowed to read, but not write to, the file. However, the unlink instruction in line 14 runs without any complaint; typing rm -f test/abc at the command line also deletes the file without question or error, and this is exactly how it is meant to be: Write permissions for a file in Unix allow the content of a file to be modified. Delete rights on the file, on the other hand, are controlled by the directory in which the file is located – not by the file itself.

Another interesting intricacy of Unix programming, shown in Listing 1, is that the test directory grants all users write and execute permissions (-wx-wx-wx) but not read permissions. Based on these rules, the script can walk into the directory with write access to its content but cannot list the files that the directory contains.

However, because the script already knows that the test/abc file exists, it can therefore delete it. Even if the file belongs to another user, this does not change anything; Unix deletes the file ruthlessly if the containing directory gives the thumbs up. This functionality naturally leads to problems, for which the founding fathers of Unix hacked out a fairly wacky solution – but more on that later.

Trespassing Rights

What does the x mean if a directory shows you -wx-wx-wx permissions? It controls the right of way for passing through the directory. Whether a command wants to read the contents of file sub/file or wants to chdir() to sub/sub1 to enter a sub1 subdirectory located in the sub directory, it requires execution rights to the sub directory.

As shown in Listing 2, this does not, however, mean that a command that accesses the top/sub/sub1 directory requires execution rights to all path components, top, sub, and sub1. For example, if a script manages to set its current directory to top/sub/sub2 via chdir() before the access lock is in place, it can still access sub1 using a relative path name of ../sub1 if top has its x rights revoked later on – as in line 21 of Listing 2 (Figure 1).

Listing 2

dir-traverse

01 #!/usr/local/bin/perl -w
02 use strict;
03 use Test::More;
04 use Test::Exception;
05 use File::Temp qw( tempdir );
06 use Sysadm::Install qw( blurt slurp
07   cd cdback );
08
09 my $ROOT_DIR = tempdir( CLEANUP => 1 );
10
11 # Read via a relative path while the abso-
12 # lute path doesn't have traversal rights.
13 dirmk( "top", 0700 );
14 dirmk( "top/sub", 0700 );
15 dirmk( "top/sub/sub1", 0700 );
16 dirmk( "top/sub/sub2", 0700 );
17
18 blurt "content",
19   "$ROOT_DIR/top/sub/sub1/file";
20 cd "$ROOT_DIR/top/sub/sub2";
21 chmod 0600, "$ROOT_DIR/top";
22
23 throws_ok
24   { slurp( "$ROOT_DIR/top/sub/sub1/file" ) }
25   qr/Permission denied/, "abs path fails";
26
27 is slurp( "../sub1/file" ),
28   "content", "rel path ok";
29
30 cdback;
31 done_testing();
32
33 ###########################################
34 sub dirmk {
35 ###########################################
36   my( $dir, $perm ) = @_;
37
38   my $path = "$ROOT_DIR/$dir";
39   mkdir $path or die "$!";
40   chmod $perm, $path or die "$!";
41 }
Figure 1: If the top directory does not grant right of way, access to sub1 via the absolute path will fail, but the relative path from sub2 to sub1 is still passable.

Listing 2 shows a test suite implemented with Test::More for verifying this fact. The throws_ok() function in line 23 comes from the CPAN Test::Exception module. This catches any errors and makes it possible to compare them with errors expected by the test suite using regular expressions. A Permission denied error thus predictably occurs when accessing via the absolute path, whereas a relative path name, as in line 27, leads to success:

$ ./dir-traverse
ok 1 - abs path fails
ok 2 - rel path ok
1..2

By the way, if you're thinking that the trick with the relative path will also work if it is not top that cancels the right of way but top/sub, you need to think again. If a script is located in top/sub/sub2 and accesses top/sub/sub1 using ../sub1, it passes through top/sub and thus needs right of way there.

Sticky Stuff

The curiosity mentioned previously that a user can delete a file even if the file itself does not grant any write permissions leads to problems if several users share a directory. If, for example, users A and B save the files file-a and file-b in /tmp, user A should not be allowed to delete file-b. But, how is that supposed to work if it is not the file itself, but the directory containing it, that controls delete access?

The rights of /tmp are set to rwxrwxrwx so that all users can access it. However, this also extends delete rights to all files that exist there to any users. The founding fathers of Unix thus resorted to a trick: They invented a special sticky bit, which is set like this:

chmod +t /tmp

You can see this by the results of the ls command, which displays the directory rights as follows:

$ ls -ld /tmp
drwxrwxrwt 7 root root 4096 Apr 13 00:17 /tmp

There is now an rwt in the mode instead of a final rwx, and Unix therefore turns the access rules in this directory on their heads. Suddenly, it is no longer possible for all users to delete entries; instead, only the owner of the respective entry can delete it.

This is exactly why each Unix system activates the sticky bit on its /tmp directory. This prevents users from mutually deleting their temporary files. Read and write permissions to the directory are still granted for all.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Beginners: File Control

    From the vault:This article first appeared in issue #1 (October 2000). You'll also find this article on our 10-year anniversary Archive DVD included in issue #120 (November 2010).

    With any operating system it is important to ensure that users remain in control of their files and directories and are prevented from tampering with those belonging to other users, or the system. This is what the Linux permissions system is all about, as Jono Bacon explains.

  • Metadata in the Shell

    Armed with the right shell commands, you can quickly identify and evaluate file and directory metadata.

  • Command Line: Access Control

    A sophisticated system of users and permissions precisely controls who has access to what on Linux. At the command line, you can define ownership with the chmod, chgrp, and chown tools.

  • Command Line: File Management

    Do some serious spring cleaning and reorganize your data. The right commands can help you to keep on top of your file and directory management.

  • File Management

    We give you an overview of commands for moving, editing, compressing, and generally manipulating files.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News