[MDEV-13402] mysqld should create its PID file before dropping privileges Created: 2017-07-28  Updated: 2020-12-01

Status: Open
Project: MariaDB Server
Component/s: Server
Affects Version/s: 5.5, 10.0, 10.1, 10.2
Fix Version/s: 10.2

Type: Bug Priority: Minor
Reporter: Michael Orlitzky Assignee: Sergei Golubchik
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Summary

The database server daemon should create its PID file before dropping
privileges. This represents a minor security issue; additional factors
are needed to make it exploitable.

Description

The purpose of the PID file is to hold the PID of the running daemon,
so that later it can be stopped, restarted, or otherwise signalled
(many daemons reload their configurations in response to a SIGHUP).
To fulfill that purpose, the contents of the PID file need to be
trustworthy. If the PID file is writable by a non-root user, then he
can replace its contents with the PID of a root process. Afterwards,
any attempt to signal the PID contained in the PID file will instead
signal a root process chosen by the non-root user (a vulnerability).

This is commonly exploitable by init scripts that are run as root and
which blindly trust the contents of their PID files. If one daemon
flushes its cache in response to SIGUSR2 and another daemon drops all
connections in response to SIGUSR2, it is not hard to imagine a
denial-of-service by the user of the first daemon against the second.

Exploitation

There is only a risk of exploitation when some other user relies on
the data in the PID file. But you have to wonder, what's the point of
the PID file if not to provide the PID to other people? Any situation
where the PID file is used is therefore suspicious.



 Comments   
Comment by Sergei Golubchik [ 2017-08-02 ]

PID file is created as a mysql user, which normally nobody has access to. It's the user that mysqld process is running at, so this user has full access to all tables in all databases. Which practically means that only root can modify PID file.

Comment by Michael Orlitzky [ 2017-08-02 ]

The main risk is that the mysqld daemon runs on the network, and that a vulnerability in the daemon allows the mysql user to gain some root privileges – namely, the ability to send signals to root-owned process. On many installations, the mysql databases contain unimportant stuff like Wordpress data, but even partial root privileges could be a lot more dangerous.

As an example, consider the following scenario:

1. I run "/etc/init.d/mysqld start" to start the daemon.

2. mysqld drops to the "mysql" user.

3. mysqld writes its PID file, now owned by the "mysql" user.

4. Someone compromises the daemon, which sits on the network.

5. The attacker is generally limited in what he can do because the
daemon doesn't run as root. However, he can write "1" into the
mysqld.pid file, and he does.

6. I run "/etc/init.d/mysqld stop" to stop the daemon while I investigate
the weird behavior resulting from the hack.

7. The machine reboots, because I killed PID 1 (this is normally restricted to root).

This is admittedly a minor risk because it requires someone to compromise the daemon already, but if they do, they shouldn't be able to gain any root privileges (like signalling root processes).

Comment by Sergei Golubchik [ 2017-08-03 ]

Yes, agree. If mysqld would have an RCE kind of a vulnerability, then, yes, it could be exploited like that to fool root to send a signal to any other process.

Comment by Michael Orlitzky [ 2018-04-22 ]

Oracle assigned this CVE-2018-2773, and it was supposed to be fixed in their April 2018 critical patch update. However, I don't see that anything has changed w.r.t. the PID file handling. I've notified them via email.

Comment by Sergei Golubchik [ 2018-04-22 ]

MySQL 5.5.60 has this commit:

commit ecc5a07874d
Author: Shishir Jaiswal <shishir.j.jaiswal@oracle.com>
Date: Sat Dec 2 15:12:32 2017 +0530

Bug#26585560 - MYSQL DAEMON SHOULD CREATE ITS PID FILE AS
ROOT

DESCRIPTION
===========
If the .pid file is created at a world-writable location,
it can be compromised by replacing the server's pid with
another running server's (or some other non-mysql process)
PID causing abnormal behaviour.

ANALYSIS
========
In such a case, user should be warned that .pid file is
being created at a world-writable location.

FIX
===
A new function is_file_or_dir_world_writable() is defined
and it is called in create_pid_file() before .pid file
creation. If the location is world-writable, a relevant
warning is thrown.

NOTE
====
1. PID file is always created with permission bit 0664, so
for outside world its read-only.
2. Ignoring the case when permission is denied to get the
dir stats since the .pid file creation would fail anyway in
such a case.

I'm sorry, but I don't see how it is MySQL vulnerability if one of the path
components in pid file location is world writable.

Comment by Sergei Golubchik [ 2018-04-22 ]

By the way, thanks for the CVE id. In April 2018 CPU CVE-2018-2773 is attributed to you (mjo) and is listed as having

Product MySQL Server
Component Client programs
Protocol None
Remote Exploit without Auth.? No
Base Score 4.1
Attack Vector Local
Attack Complex High
Privs Req'd High
User Interact None
Scope Unchanched
Confidentiality None
Integrity None
Availability High

How's that "Client program", I wonder. And how can it affect availability of MySQL Server...

Comment by Michael Orlitzky [ 2018-04-22 ]

Ah, thanks. My original report had nothing to do with world-writable directories... makes you wonder =)

Comment by Tomas Hoger [ 2018-10-31 ]

The original problem was fixed in October 2018 CPU as CVE-2018-3174. mjo is credited as reporter, and Client programs is again listed as the affected component.

MySQL fix:
https://github.com/mysql/mysql-server/commit/e1fdeb2468f3ee16e34e0c3af856edde128836e5

Re-implemented MariaDB fix:
https://github.com/MariaDB/server/commit/73e1ffdc6899aea69182c15930f712a178813660

mjo can you confirm CVE-2018-3174 really is for this issue? You either should have received the info from Oracle, or they should confirm the CVE id assignment if you ask. Thank you!

Comment by Michael Orlitzky [ 2018-10-31 ]

It's not really fixed, but I've given up. The fix that they shipped is to use

su mysql -s /bin/bash -c kill...

in the init scripts that are shipped with MySQL. It's not a good fix:

1. It doesn't address the design flaw... why is the PID file being created after dropping privileges in the first place? The sole purpose of the PID file is to aid SysV-style init scripts (if you're also using it as e.g. a lockfile: don't do that). There's no cross-platform way to drop privileges in an init script, so they all kill the process as root. Thus, the PID file should be root-owned.
2. It only works on Redhat/Oracle, and only if you use the script from the MySQL tarball. Everyone else has to invent their own OS-specific solution, or be vulnerable. Not that they'd ever know to do that.

I've already explained the issue to Oracle like 5 times and they don't get it. They go silent for 6 months and then come back with something like a hardcoded "su mysql" command that only works on Redhat.

Generated at Thu Feb 08 08:05:19 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.