Right, let’s talk about SUID. It’s one of those things that sounds complicated but is actually a beautifully simple, terrifyingly powerful hack. The acronym stands for Set User ID, and its purpose is to temporarily and selectively promote a user’s privileges. Think of it as a temporary VIP pass for a specific program.

Normally, when you run a program, it runs with your permissions. You can’t delete other users’ files because the process is wearing your identity badge. SUID flips this script. When you run an SUID program, it doesn’t run as you; it runs as the user who owns the executable file. This is almost always root.

The classic, perfect example is /usr/bin/passwd. Go on, look at it:

ls -l /usr/bin/passwd

You’ll see something like: -rwsr-xr-x 1 root root 63960 Feb 7 2023 /usr/bin/passwd

See that s where the execute (x) permission for the owner should be? That’s the SUID bit in all its glory. This means when you, a mere mortal user, run passwd, the process doesn’t run with your limited privileges. It runs as root. This is why you’re allowed to write to the protected /etc/shadow file to change your password. The program is designed carefully to only let you change your own password, not anyone else’s. The SUID privilege is the enabler; the program’s own logic is the safety check. Without SUID, the passwd command would try to write to /etc/shadow, get a big fat “Permission Denied” error, and fail spectacularly.

How to Set (and Unset) the SUID Bit

Setting this thing is straightforward, which is why you need to be careful with it. You use the chmod command with the u+s mode.

# Set the SUID bit on a fictional program
chmod u+s /usr/local/bin/my_special_program

# Remove the SUID bit just as easily
chmod u-s /usr/local/bin/my_special_program

You can also use the numeric method, which is what you’ll see most often in the wild. The SUID bit adds 4000 to the standard permission octal.

# This gives the file rwx for owner, r-x for group and others, AND sets the SUID bit
chmod 4755 /usr/local/bin/my_special_program

A quick ls -l will show the s in the owner’s execute position if it’s set. If you see a capital S (e.g., -rwSrwxr-x) instead of a lowercase s, it means the SUID bit is set but the owner does not have execute permissions. This is useless and broken. The bit is set, but since the owner can’t even execute the file, the feature can’t function. It’s a common mistake when using the numeric method.

The Sudo Example: A Subtler Case

Let’s clear up a common point of confusion. When you run sudo, you type your password and then it runs a command as root. It might feel like SUID, but it’s a different mechanism (sudo is an authentication service). However, the sudo binary itself is SUID. Check it:

ls -l /usr/bin/sudo

-rwsr-xr-x 1 root root 166056 Jan 19 2023 /usr/bin/sudo

Why? Because the sudo program needs to run as root from the very start so it can authenticate you against the root-owned /etc/sudoers file and then switch to the target user. It’s SUID that gives it that initial boost to even start the authentication process. It’s a great example of SUID being used to bootstrap a more complex privilege system.

The Massive Caveat and Best Practices

Here’s where I stop being witty and get dead serious. SUID is a massive attack surface. You are granting a program the ability to run as root. If that program has a vulnerability—a buffer overflow, a symlink attack, anything—an attacker can potentially hijack that root privilege and own your entire system.

This is why the list of SUID binaries on a modern system is very short and very curated. You should treat any new SUID binary you create with extreme suspicion.

  • Best Practice #1: The absolute number one rule is minimize. If a task can be accomplished without SUID (e.g., using group permissions or sudo), that is almost always the safer path.
  • Best Practice #2: The SUID program must be meticulously written and audited. It should drop its elevated privileges the instant it no longer needs them (using seteuid() or similar) and should never trust un-sanitized user input.
  • Best Practice #3: Regularly audit your system. Find all the SUID files so you know what’s there. You can’t secure what you don’t know about.
# Find all SUID files on your system
find / -type f -perm -4000 -ls 2>/dev/null

Run that. Look at the short, predictable list it returns. That’s what a secure system looks like. If you ever see a shell script (e.g., suid_script.sh) in that list, panic. Then remove the SUID bit from it. The Linux kernel straight-up ignores the SUID bit on shell scripts for exactly this reason—it’s too easy to exploit. It’s a historical relic that doesn’t work, so seeing it set is a sign of profound misunderstanding.

SUID is a sharp tool. It solves a real problem elegantly, but it will cut you if you aren’t an expert. Use it only when you have no other choice, and even then, double-check your work.