Skip to content

Interview question · Systems, OS & Memory Safety

A Linux service running as a non-root user is compromised. What decides whether the attacker can become root, and what do you check?

The username tells you almost nothing. The interviewer wants the list of privilege transitions reachable from that process, and which of them you would have closed in advance.

mediumNewPreparation tags: Google, Amazon, CrowdStrikeUpdated Nov 2026

TL;DR: Not the username. What matters is every privilege transition the process can reach: its own capabilities, sudo rules for its user, setuid and setgid programs, writable files that something privileged later runs or reads, secrets it can read, privileged sockets and APIs it can talk to (the Docker socket is root), the kernel surface it can call, and whether no_new_privs and a sandbox profile are set. Answer as a reviewer: enumerate those transitions for the service's identity, close each one you can, and make the rest observable.

How to approach it

Treat it as a reachability question: from this process, with these credentials, what can cause code to run with more privilege? Group the paths into what the process already holds, what it can trigger, what it can tamper with, and what it can read. Then state what you would check, in order of likelihood, and what a hardened unit file looks like.

A strong answer

FIG · FROM SERVICE ACCOUNT TO ROOT · ENUMERATE THE TRANSITIONS
Not the username: every door this process can reach

Compromised service

user www

Reachable transitions

what can it touch?

Root

or equivalent

Doors to check and close

Granted privilege

  • Capabilities, sudo rules, setuid programs

Writable things root uses

  • Cron scripts, unit files, configs, plugin directories

Privileged endpoints

  • Docker socket, cloud metadata, admin APIs

Kernel surface

  • No seccomp profile, no no_new_privs, old kernel

What the process already holds.

  • Capabilities. Linux splits root into capabilities, and a "non-root" service can still hold some. CAP_SYS_ADMIN is broad enough to be close to root; CAP_DAC_OVERRIDE ignores file permissions; CAP_SYS_PTRACE can inject into other processes; CAP_SYS_MODULE loads kernel code. Check /proc/<pid>/status (CapEff, CapBnd) and the unit file.
  • Group memberships. Membership in docker, disk, adm, wheel or lxd groups is often equivalent to root or to reading everything.
  • Open handles and inherited descriptors. A descriptor to a privileged file or socket inherited from a parent survives the privilege drop.

What it can trigger.

  • sudo rules for the service user. Any rule allowing an editor, an interpreter, find, tar or a script the user can modify is a root shell by another name.
  • setuid and setgid binaries. Each is privileged code reading the attacker's arguments and environment. Unusual or outdated ones are the risk; a minimal system has very few.
  • Privileged daemons it can talk to. The Docker or containerd socket lets the caller start a container that mounts the host filesystem. A local admin API, D-Bus services with weak policy, or a database running as root are similar.

What it can tamper with. Files that something privileged later executes or reads: scripts in root's cron, systemd unit files and their ExecStart targets, directories in a privileged program's PATH or library search path, configuration files of privileged services, Python packages imported by a root process. Write access to any of these converts to root at the next run.

What it can read. Credentials for more privileged identities: SSH keys, cloud credentials in environment files, database passwords, tokens for an orchestration API, the instance metadata service if the host's role is powerful. Often the fastest path to root is a credential, not an exploit.

The kernel. If nothing else works, the attacker targets the kernel through the system calls they can make. An unpatched kernel plus an unrestricted system call surface is the last-resort path, which is why patching and seccomp both matter.

What you check, in order. Capabilities and groups; sudo rules; writable paths used by privileged processes (find for files writable by the service user outside its own data directories); setuid inventory; reachable privileged sockets; readable secrets; kernel version and seccomp status.

What the hardened version looks like. A dedicated user with no shell and no group memberships; in the systemd unit, NoNewPrivileges=yes (so setuid binaries no longer elevate), CapabilityBoundingSet= limited to what is needed (often empty), ProtectSystem=strict and ProtectHome=yes (read-only system, no home directories), PrivateTmp=yes, ReadWritePaths= for its own data only, SystemCallFilter=@system-service, and an AppArmor or SELinux profile. Secrets come from a manager at runtime with only this service's scope. Then a successful compromise of the service gives the attacker the service's data and nothing else, which is the design goal.

What interviewers probe next

  • "Why is membership in the docker group equivalent to root?" The daemon runs as root and will start a container with the host's root filesystem mounted and privileged mode on request.
  • "What does no_new_privs change?" After it is set, execve can no longer grant privileges: setuid bits and file capabilities are ignored for that process and its children. It is also required before an unprivileged process can install a seccomp filter.
  • "How would you detect an attempt?" Process events where the service's descendants run as root, execution of sudo or setuid binaries by the service user, writes to cron or unit directories, and connections to the Docker socket.

What if?

What if · interview follow-ups

Hold your answer as the constraints change

An attacker has code execution as a web service account on a Linux host, and the team assumes they are safe because the account is not root.

  1. Start here

    What actually matters, if not the username?

How it's scored

Weak: "It runs as a normal user, so it is fine unless there is a kernel exploit."

Hire: Lists capabilities, sudo, setuid binaries, writable privileged files and readable credentials, and proposes a dedicated user with least privilege.

Strong Hire: Frames it as reachable privilege transitions, includes privileged sockets and group memberships, gives a concrete hardened unit (NoNewPrivileges, empty capability set, filesystem protection, system call filter, MAC profile), and pairs it with detections.

Common mistakes

  • Equating non-root with low privilege while ignoring capabilities and groups.
  • Forgetting writable files that privileged processes execute.
  • Missing the Docker socket and similar privileged APIs.
  • Treating kernel patching as the only control.
You just read a free answer. Every topic opens its first 5 answers to anyone. Sign in and the count per topic goes to 10, and we keep track of how far you get in every topic.Google sign-in · free · no payment details
HOW DID IT GO?
0
READING SIGNED OUT

Signing in doubles your free answers, from 5 to 10 per topic, and the site starts remembering you: mastery per topic, bookmarks, and a next-focus recommendation. Free, no card.

Sign in free
UP NEXT ON YOUR JOURNEY
DISCUSSION · 0

No comments yet. Share a correction or a different way to answer it.