Quick overview:
In early 2022, a significant security hole surfaced in SUSE’s openSUSE Factory Linux distribution. Tied to the way the systemd service script for Sendmail worked, CVE-2022-31256 made it possible for ordinary mail users to gain full root access with little effort. Let’s break down why it happened, show a simple code example, and share what you need to know to stay safe.
What is CVE-2022-31256?
CVE-2022-31256 refers to an *Improper Link Resolution Before File Access* vulnerability, better known as a “Link Following” issue. Here, a system script called by the sendmail systemd service failed to correctly verify where symbolic links pointed, enabling attackers to manipulate file permissions and escalate privileges.
Affected versions:
SUSE openSUSE Factory’s sendmail *before* version 8.17.1-1.1
Original advisory:
- openSUSE Security announcement
- NVD CVE-2022-31256
How Did The Vulnerability Work?
When a service like Sendmail starts or restarts, the systemd unit calls a helper script to prepare certain mail data files, setting permissions and ownership. Normally, these files (like /var/spool/mail/*) belong to normal users, not root. But the script trusted these paths fully. If, before the script ran, someone replaced their own /var/spool/mail/<user> file with a *symlink* to some other file, the script would *happily* change *that* file’s permissions, as root.
That’s classic “symlink race” territory. If the attacker timed it right, they could point the symlink at any root-writable file on the system.
Step 1: Create a Symlink
Suppose you’re user mailuser on a vulnerable system. You want to overwrite, say, /etc/shadow (the file storing root password hashes).
cd /var/spool/mail
rm mailuser # delete your mail file (if you own it)
ln -s /etc/shadow mailuser
Ask the admin (or service) to restart sendmail
sudo systemctl restart sendmail
Step 3: What Happens Next
The helper script, running as root, sees /var/spool/mail/mailuser and *blindly* tries to chown and chmod it to make it writable by your user account. Since it’s actually a link to /etc/shadow, you now own /etc/shadow. With write access, you can easily set a root password of your choosing.
Change the root password hash to your own, or just echo your own password hash into /etc/shadow
echo 'root::::99999:7:::' > /etc/shadow
*(This example would “blank” root’s password. Don’t copy this on a real system!)*
Example Vulnerable Script (Simplified)
Here’s an illustration of what the bad logic might look like (Python-ized, but works similarly in bash):
import os
MAIL_SPOOL = '/var/spool/mail'
for username in os.listdir(MAIL_SPOOL):
path = os.path.join(MAIL_SPOOL, username)
# BAD: No check for symlink!
os.chown(path, get_uid_for_user(username), get_gid_for_group('mail'))
os.chmod(path, o660)
A secure script should detect and refuse symlinks, like this
import os
if not os.path.islink(path):
os.chown(path, ...)
os.chmod(path, ...)
Why Does This Happen?
The CWE for this is CWE-59: Improper Link Resolution Before File Access ('Link Following'). In a nutshell, this happens any time a privileged program changes permissions, or writes to a file, without first making sure it's a *normal* file and not a link to something unexpected.
Check scripts:
If you manage services setting file ownership automatically, *always* check for symlinks before taking action.
More References
- Full Debian advisory (similar issue)
- Red Hat: About symbolic link vulnerabilities
- MITRE CVE entry
- Good explanation on symlink attacks
Closing Thoughts
CVE-2022-31256 is a classic reminder: Even trusted system scripts can be tricked by something as simple as a symlink. If you’re running a mail server, patch right away. If you’re writing scripts that handle files as root, never trust a file just because it’s where you expect—check before you act. Stay safe!
Timeline
Published on: 10/26/2022 09:15:00 UTC
Last modified on: 10/28/2022 17:49:00 UTC