The nitty gritty of Unix rights management
Cross-Examination
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 }
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
(incl. VAT)
Buy Linux Magazine
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.
News
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.
-
Rhino Linux Announces Latest "Quick Update"
If you prefer your Linux distribution to be of the rolling type, Rhino Linux delivers a beautiful and reliable experience.