DEV Community

Cover image for Linux Privileges:Peeling Back the Curtain Of How Linux Really Handles Users, Privileges, and Processes
Bhushitha Hashan
Bhushitha Hashan

Posted on

Linux Privileges:Peeling Back the Curtain Of How Linux Really Handles Users, Privileges, and Processes

Introduction

On how Linux really handle privileges on processes has always felt like a black box to me. You type a command, and sometimes the system says “permission denied,” sometimes “okay, you’re root now,” and you shrug. You think it’s magic. But today, after spending hours staring into /proc, reading task_struct, tracing execve(), and watching UIDs dance around, I finally see what’s really happening. Linux isn’t magic at all it’s mechanical, almost brutally logical.simple yet powerfull and perfect. Every privilege, every setuid program, every sudo call, every login shell is enforced in code. No luck, no wizardry just a lot of careful kernel work.

I’m going to break it all down. Strap in.


UIDs: The Kernel Doesn’t Give a Damn About Names

Okay, now, let me catch your thought: “wait, but what about /etc/passwd and usernames?” Yeah, I get you. That’s the trap most people fall into. The kernel does not care about your username. Zero. The kernel only cares about numbers: UIDs and GIDs. That’s it.

Every process has a task_struct. Inside that is a cred struct that tracks all the UIDs and GIDs relevant to the process:

struct cred {
    kuid_t ruid;  // Real UID: the user who launched the process
    kuid_t euid;  // Effective UID: what you can actually do right now
    kuid_t suid;  // Saved UID: what you can regain if you drop privileges temporarily
    kgid_t rgid;  // Real GID
    kgid_t egid;  // Effective GID
    kgid_t sgid;  // Saved GID
};
Enter fullscreen mode Exit fullscreen mode
  • ruid (Real UID): Think of it like your “birth certificate” in Linux.its who spawned you. This almost never changes unless a privileged syscall explicitly allows it.
  • euid (Effective UID): This is what the kernel actually checks for privileges. Want to open /etc/shadow? Kernel checks this. Want to bind port 80? Kernel checks this.
  • suid (Saved UID): This is your “back door” to regain privileges you temporarily dropped. I’ll show why this matters with setuid programs.

Rule: The kernel is the boss. Userspace tools like sudo or su just orchestrate things.the kernel is the one making all the actual decisions.


Setuid: Privilege Already Baked Before You Touch Anything

Next up, the setuid. That infamous +s bit. This is literally the kernel saying:

“When this program runs, I’m going to temporarily treat it as if it belongs to the file owner, not the person executing it.”

Let me break it down. You have /usr/bin/passwd (owned by root, setuid). When alice runs it:

ruid = 1000 (alice)
euid = 0    (root)
suid = 0    (root)
Enter fullscreen mode Exit fullscreen mode

Now, look closely:

  • ruid stays alice —> she is still herself.
  • euid is root —> kernel checks this for every privileged syscall.
  • suid is root —> the “return ticket” if alice temporarily drops privileges.

Yes, the saved UID exists because without it, once you drop privileges, you could never regain them. That’s the entire point.


Dropping and Regaining Privileges Safely

Setuid programs don’t just run full power the entire time cause that would be insane. They often drop privileges temporarily while doing risky stuff. Then, when needed, they regain them:

seteuid(ruid); // drop privileges
// do unprivileged work
seteuid(suid); // regain privileges
Enter fullscreen mode Exit fullscreen mode

Timeline (simplified):

Execve setuid-root:
ruid=alice  euid=root  suid=root

Drop privileges:
seteuid(ruid)
ruid=alice  euid=alice  suid=root

Regain privileges:
seteuid(suid)
ruid=alice  euid=root  suid=root
Enter fullscreen mode Exit fullscreen mode

Notice that suid never changes when you temporarily switch euid. It’s a fixed “return ticket.”


When Setuid Is Not Set

Now, let’s be clear: if a file doesn’t have +s, the kernel does something simple:

ruid = caller UID
euid = caller UID
suid = caller UID
Enter fullscreen mode Exit fullscreen mode

Nothing magical. You can’t elevate yourself arbitrarily. Only root (or a setuid-root binary) can raise privileges.


Rules of Privilege Escalation

Now, now, I know what you’re thinking: “so, only root can become anyone else, right?” Exactly. Let’s spell it out:

  • euid=0 (root): can change ruid/euid/suid to anything. Full control.
  • Normal users: can only lower privileges (drop euid). No raising to someone else’s UID.
  • Setuid files: allow a controlled, kernel-enforced elevation to the file owner’s UID.
  • ruid: almost immutable; it’s your original identity.

Example scenario:

User1: UID 1001
User2: UID 1002
Enter fullscreen mode Exit fullscreen mode
  • User1 cannot become 1002.
  • User2 cannot become 1001.
  • Only root could switch to either.

Login Shells and TTYs: The “Fall From Grace”

Alright, now I know exactly what you’re thinking if u read it till now,: “if the ruid is the one who start the process,who the hell owns the TTY I log in to?” Let me untangle this.

Before you log in, every virtual terminal (VTY) is essentially owned by root. That’s right,before login, you are like an all-powerful god sitting in /dev/tty1…6.

Then systemd or init starts getty (or agetty), which listens for login attempts. getty itself is root-owned. it has to be, because it’s going to spawn login shells, check passwords, and eventually drop privileges safely.

When you finally log in:

  • login verifies your credentials
  • then spawns your login shell (bash, zsh, whatever)
  • and suddenly you fall from grace:
ruid = your UID
euid = your UID
suid = your UID
Enter fullscreen mode Exit fullscreen mode

Haha, right? All-powerful god → mortal user in one instant. This is why root privileges are tightly controlled: you can’t just pick up random UIDs at will. The kernel enforces this rigorously.
here check this image ive attached below if u still find this tty thing confusing..


sudo, su, and Variants

Here’s the part most people misunderstand: sudo and su aren’t magical at all they’re setuid-root programs that orchestrate privilege elevation under kernel rules.

  • sudo: Runs as root (setuid), checks /etc/sudoers, then temporarily switches euid to root for your command.
  • sudo -i: Starts an interactive root shell (euid=0).
  • su: Switch user; requires root privileges to switch to another user.
  • su -: Switch user and simulate login environment (PATH, environment variables, etc.).

Without the kernel enforcing UIDs, all of this would be meaningless. When you run sudo, the kernel sees:

ruid = original user
euid = root (because sudo binary is setuid-root)
suid = root
Enter fullscreen mode Exit fullscreen mode

And everything is checked at the syscall level. Permissions aren’t faked.they are real.


Process Startup: Everything Happens in Order

Timeline, kernel-first:

Parent calls execve(path, argv, envp)
    ↓
Kernel checks permissions, filesystem flags, LSM
    ↓
Kernel sets credentials (ruid, euid, suid) → includes setuid handling
    ↓
Kernel loads ELF segments into memory
    ↓
Kernel builds stack with argc, argv, envp, auxv
    ↓
Kernel switches to user mode at _start
    ↓
C runtime extracts argc, argv, envp
    ↓
main(argc, argv, envp) runs
Enter fullscreen mode Exit fullscreen mode

Key point: credentials are applied before the environment exists, before the program executes a single instruction, and before it can touch syscalls. That’s why setuid works safely.


Mental Model

Think of Linux privileges like this:

execve()          → kernel enforces creds (ruid/euid/suid)
   ↓
ELF loaded, stack built (argc/argv/envp)
   ↓
_enter_user_mode()
   ↓
C runtime sets up main()
   ↓
program executes, syscalls checked against euid
Enter fullscreen mode Exit fullscreen mode
  • Setuid program: ruid = caller, euid = file owner, suid = file owner
  • Normal program: ruid = euid = suid = caller
  • Drop privileges temporarily → regain via suid → safe privilege handling
  • Only root or setuid-root binaries can elevate euid arbitrarily

Why This Matters

Once you understand this:

  • sudo, su, login shells, daemons, and setuid-root programs stop being mysterious.
  • Everything funnels down to kernel-enforced credentials.
  • Understanding ruid/euid/suid, setuid, and process startup explains why Linux is secure and why miswritten setuid programs are a security nightmare.

Linux isn’t magic. It’s just mechanical, precise, and enforced at every step. Once you see it, everything clicks.

Top comments (0)