12.4 Sticky Bit on Directories: Protecting /tmp
Right, so you’ve got /tmp. A glorious, chaotic free-for-all where every user and their cron job can create files. It’s the digital equivalent of a public park after a concert. The problem is, if it’s world-writable (which it has to be), what’s stopping User A from waltzing in and deleting User B’s precious temporary file? Or, more nefariously, replacing a script User B is about to execute?
Enter the Sticky Bit. This is the old, grumpy bouncer of the directory world. It doesn’t care who creates a file—the bouncer lets anyone into the club. Its one job is to make sure you can’t mess with someone else’s stuff once it’s in there. The name is a historical artifact; it was originally designed to “stick” a program’s executable image in swap space after it finished to make it load faster. That use is long dead, but the name and its modern, far more important purpose on directories lives on.
You’ll see it in action every day. Go on, take a look at your /tmp:
ls -ld /tmp
You’ll almost certainly see permissions that look like this:
drwxrwxrwt 15 root root 4096 May 20 10:00 /tmp
See that t at the end of the permissions string, where you’d normally expect an x for “others”? That’s the visual giveaway. The lowercase t means the directory has both the execute permission (for others) and the sticky bit set. If you ever see a capital T, that means the sticky bit is set but the execute permission for others is not set. This is mostly useless and just creates confusion, a perfect example of a questionable design choice that we just have to live with.
How It Actually Works: The Rule of Deletion
The magic of the sticky bit boils down to a single, simple rule enforced by the kernel: In a directory with the sticky bit set, you can only delete or rename a file if you are the owner of the file, the owner of the directory, or the root user.
Let’s make this concrete. Imagine /tmp has the sticky bit. User alice creates a file:
alice$ touch /tmp/alices_secret_plan.txt
alice$ ls -l /tmp/alices_secret_plan.txt
-rw-r--r-- 1 alice alice 0 May 20 10:05 /tmp/alices_secret_plan.txt
Now User bob comes along. He can see the file, he can even read it (if the permissions allow), but the kernel will flat-out refuse to let him delete it or rename it.
bob$ rm /tmp/alices_secret_plan.txt
rm: remove write-protected regular empty file '/tmp/alices_secret_plan.txt'? y
rm: cannot remove '/tmp/alices_secret_plan.txt': Operation not permitted
The system doesn’t say “Permission denied” because of the file’s permissions—it says “Operation not permitted” because of the directory’s sticky bit rule. This is a crucial distinction. The file’s own rwx permissions are almost irrelevant here; the directory’s rule is the ultimate gatekeeper.
Setting and Removing the Sticky Bit
It’s dead simple. The symbolic way uses chmod +t:
# Set it
sudo chmod +t /path/to/directory
# Remove it
sudo chmod -t /path/to/directory
The numeric way is a bit more explicit. Remember that the special permissions (SUID, SGID, Sticky) are represented by a fourth digit prepended to the standard three. The sticky bit is represented by the number 1.
# Give a directory 1777 permissions (rwxrwxrwt)
sudo chmod 1777 /path/to/directory
# Give a directory 1755 permissions (rwxr-xr-t) - Note the capital T!
sudo chmod 1755 /path/to/directory
# To remove it, just use a normal mode like 755 or 777
sudo chmod 777 /path/to/directory
Common Pitfalls and Best Practices
First, the capital T pitfall. Setting the sticky bit without execute permission (chmod 1755) creates a drwxr-xr-t permission. That capital T is a beacon of uselessness. Users can’t even cd into the directory, making the sticky bit’s deletion rule completely moot. Always ensure the directory has the execute bit set for whoever needs access. Just use 1777 or chmod o+t.
Second, the sticky bit only governs deletion and renaming. It is not a security panacea. User bob can still:
- Read the contents of
alice’s file (if its permissions allowr). - Overwrite the contents of the file (if its permissions allow
w). This is a huge gotcha. If a world-writable file exists in/tmp,bobcanecho "evil" > /tmp/alices_fileand corrupt it, even though he can’t delete it.
This is why best practice for creating temporary files is to use functions like mkstemp() or mktemp in scripts, which create files with restrictive permissions (e.g., 0600) by default, preventing other users from reading or writing to them. The sticky bit handles the deletion part; you have to handle the file permissions yourself.
So where should you use this? Obviously, on /tmp and /var/tmp. It’s also incredibly useful on any collaborative directory, like a shared upload or dropbox folder where multiple users need to add files but should only be able to remove their own. It’s the simplest, most effective way to prevent a digital Wild West in a shared space.