Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 630822 (CVE-2017-15945) - dev-db/{mysql-cluster,mariadb,mysql,percona-server,mariadb-galera}: root privilege escalation via "chown"
Summary: dev-db/{mysql-cluster,mariadb,mysql,percona-server,mariadb-galera}: root priv...
Status: RESOLVED FIXED
Alias: CVE-2017-15945
Product: Gentoo Security
Classification: Unclassified
Component: Auditing (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Security Audit Team
URL:
Whiteboard:
Keywords:
Depends on: 635702 635704 635706 635708 635710
Blocks:
  Show dependency tree
 
Reported: 2017-09-12 16:57 UTC by Michael Orlitzky
Modified: 2021-08-11 19:59 UTC (History)
5 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
bug-630822.patch (bug-630822.patch,1.46 KB, text/x-diff)
2017-09-14 17:35 UTC, Brian Evans (RETIRED)
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Orlitzky gentoo-dev 2017-09-12 16:57:22 UTC
The latest two ebuilds for mariadb (10.2.7-r2 and 10.2.8) call "chown" on the live root filesystem in pkg_postinst, in more than one place. For example,

  pkg_postinst() {
      # Make sure the vars are correctly initialized
      mysql_init_vars

      # Check FEATURES="collision-protect" before removing this
      [[ -d "${ROOT}${MY_LOGDIR}" ]] || \
          install -d -m0750 -o mysql -g mysql "${ROOT}${MY_LOGDIR}"

      # Secure the logfiles
      touch "${ROOT}${MY_LOGDIR}"/mysql.{log,err}
      chown mysql:mysql "${ROOT}${MY_LOGDIR}"/mysql*
      ...

This is exploitable by the "mysql" user to gain root. The non-recursive calls to "chown" are vulnerable to having their targets replaced by symlinks, and the recursive calls are vulnerable to the same trick with hard links. For example,

  1. emerge mariadb-10.2.8
  2. sudo su -s /bin/sh -c 'ln -sf /etc/passwd /var/log/mysql/mysql.log' mysql
  3. emerge mariadb-10.2.8
  4. The "mysql" user now owns /etc/passwd.

I haven't verified the exploit with "chown -R" because I don't want to spend another half hour on the build, but anywhere you call "chown -R" on the same directory more than once is going to be exploitable.
Comment 1 Brian Evans (RETIRED) gentoo-dev 2017-09-12 17:48:12 UTC
This is more than mariadb.  This code has existed for years and years in mysql.eclass (Overlay only now), mysql-v2.eclass, mysql-multilib*.eclass and now finally in the dev-db/mariadb ebuilds.

All versions of dev-db/{mysql,mariadb,percona-server,mysql-cluster,mariadb-galera} are included.  As well as past versions of dev-db/mysql-community.

I'm testing a patch for existence of non files so they can be removed at the log locations.

Any further suggestions are welcome.
Comment 2 Michael Orlitzky gentoo-dev 2017-09-12 17:55:00 UTC
(In reply to Brian Evans from comment #1)
> 
> Any further suggestions are welcome.

If the code has been around for that long, consider the possibility that your predecessors were wacko =)

The only person who can change ownership of a file is root, so if any of the log files have the wrong ownership, it's because root went in there and did it. So long as /var/log/mysql is writable by the "mysql" user, the logs will get created as mysql:mysql and everything will be fine.

Symlinks are easy to detect, but hard links are a lot, uh, harder -- and they have the same problem.
Comment 3 Brian Evans (RETIRED) gentoo-dev 2017-09-12 18:21:16 UTC
(In reply to Michael Orlitzky from comment #2)
> (In reply to Brian Evans from comment #1)
> > 
> > Any further suggestions are welcome.
> 
> If the code has been around for that long, consider the possibility that
> your predecessors were wacko =)
> 
> The only person who can change ownership of a file is root, so if any of the
> log files have the wrong ownership, it's because root went in there and did
> it. So long as /var/log/mysql is writable by the "mysql" user, the logs will
> get created as mysql:mysql and everything will be fine.
> 
> Symlinks are easy to detect, but hard links are a lot, uh, harder -- and
> they have the same problem.

OK.  I have removed the "# Secure the logfiles" block an just kept the install above it.  This does not affect the server since it creates mysqld.err and other files without our help.

Let me know when this is OK to push.
Comment 4 Michael Orlitzky gentoo-dev 2017-09-12 19:43:25 UTC
(In reply to Brian Evans from comment #3)
> 
> OK.  I have removed the "# Secure the logfiles" block an just kept the
> install above it.  This does not affect the server since it creates
> mysqld.err and other files without our help.
> 

I suspect this one is vulnerable too (the others should be OK because they operate on $D and not $ROOT):

  chown -R mysql:mysql "${ROOT}/${MY_DATADIR}" 2>/dev/null

I think the same reasoning applies -- everything in there should have the correct ownership already -- but I'm no expert.

If you feel like waiting for me to re-emerge mariadb one more time, I'll see if I can exploit that line above.
Comment 5 Brian Evans (RETIRED) gentoo-dev 2017-09-12 20:01:49 UTC
(In reply to Michael Orlitzky from comment #4)
> (In reply to Brian Evans from comment #3)
> > 
> > OK.  I have removed the "# Secure the logfiles" block an just kept the
> > install above it.  This does not affect the server since it creates
> > mysqld.err and other files without our help.
> > 
> 
> I suspect this one is vulnerable too (the others should be OK because they
> operate on $D and not $ROOT):
> 
>   chown -R mysql:mysql "${ROOT}/${MY_DATADIR}" 2>/dev/null
> 
> I think the same reasoning applies -- everything in there should have the
> correct ownership already -- but I'm no expert.
> 
> If you feel like waiting for me to re-emerge mariadb one more time, I'll see
> if I can exploit that line above.

While possible, this is unlikely as an attacker would have to expect that an admin is going to install a database and run 'emerge --config' and therefore create the directory in ${MY_DATADIR} which defaults to /var/lib/mysql but can be overridden in the environment by the admin at build time.
Comment 6 Brian Evans (RETIRED) gentoo-dev 2017-09-12 20:24:47 UTC
Hmm.. or otherwise remove the database directory entirely, which an admin will certainly notice, place an exploit and expect 'emerge --config' again.  A good admin should spot such trouble and prepare a new directory, but I understand this is not always the case.
Comment 7 Michael Orlitzky gentoo-dev 2017-09-12 21:15:34 UTC
Well, pkg_config won't run if /var/lib/mysql already exists, so that eliminates the easy exploit where I just stick a hard link in there whenever I feel like it and later run emerge --config.

There's still a race condition I think, but that's much less serious:

  1. local cmd=( "${EROOT}usr/share/mariadb/scripts/mysql_install_db" )
  2. [[ -f "${cmd}" ]] || cmd=( "${EROOT}usr/bin/mysql_install_db" )
  ...
  5. "${cmd[@]}" >"${TMPDIR}"/mysql_install_db.log 2>&1
  ...
  12. chown -R mysql:mysql "${ROOT}/${MY_DATADIR}" 2>/dev/null

I've probably miscounted those, but between lines 5 and 12, the "mysql" user can stick a hard link in MY_DATADIR. He could maybe clue himself into that by watching $TMPDIR for the creation of a file named mysql_install_db.log, but this is all pretty far-fetched.

Is the "chown -R" doing anything at all? If under normal circumstances, everything in that directory has the correct owner anyway, then I would say it's worthwhile to remove it just in case.
Comment 8 Michael Orlitzky gentoo-dev 2017-09-12 21:23:20 UTC
Aw shit... so, the race condition is actually stupid easy to take advantage of. Run this in a shell as the "mysql" user:

  while true ; do
    ln /etc/passwd /var/lib/mysql/x
  done

As soon as you run emerge --config, even with a brand new MY_DATADIR, the "mysql" user will take ownership of /etc/passwd.
Comment 9 Brian Evans (RETIRED) gentoo-dev 2017-09-13 13:52:43 UTC
(In reply to Michael Orlitzky from comment #7)
> Well, pkg_config won't run if /var/lib/mysql already exists, so that
> eliminates the easy exploit where I just stick a hard link in there whenever
> I feel like it and later run emerge --config.
> 
> There's still a race condition I think, but that's much less serious:
> 
>   1. local cmd=( "${EROOT}usr/share/mariadb/scripts/mysql_install_db" )
>   2. [[ -f "${cmd}" ]] || cmd=( "${EROOT}usr/bin/mysql_install_db" )
>   ...
>   5. "${cmd[@]}" >"${TMPDIR}"/mysql_install_db.log 2>&1
>   ...
>   12. chown -R mysql:mysql "${ROOT}/${MY_DATADIR}" 2>/dev/null
> 
> I've probably miscounted those, but between lines 5 and 12, the "mysql" user
> can stick a hard link in MY_DATADIR. He could maybe clue himself into that
> by watching $TMPDIR for the creation of a file named mysql_install_db.log,
> but this is all pretty far-fetched.
> 
> Is the "chown -R" doing anything at all? If under normal circumstances,
> everything in that directory has the correct owner anyway, then I would say
> it's worthwhile to remove it just in case.

The mysql_install_db script is run as root and the data files created get a group of root so is this line acceptable to replace line 12 above?

chgrp mysql "${ROOT}/${MY_DATADIR}"/{mysql,test} 2>/dev/null
Comment 10 Michael Orlitzky gentoo-dev 2017-09-13 14:07:22 UTC
(In reply to Brian Evans from comment #9)
> 
> The mysql_install_db script is run as root and the data files created get a
> group of root so is this line acceptable to replace line 12 above?
> 
> chgrp mysql "${ROOT}/${MY_DATADIR}"/{mysql,test} 2>/dev/null

What's the owner/group on $MY_DATADIR at that point? The chgrp will also affect the target of sym/hard links, so it's important that the mysql user not be able to stick a link in place of those two arguments via the same race condition. If MY_DATADIR is root:root, it should be safe.

Another thing that might work is to "su mysql ..." instead of passing --user to mysql_install_db.
Comment 11 Brian Evans (RETIRED) gentoo-dev 2017-09-13 14:15:27 UTC
(In reply to Michael Orlitzky from comment #10)
> (In reply to Brian Evans from comment #9)
> > 
> > The mysql_install_db script is run as root and the data files created get a
> > group of root so is this line acceptable to replace line 12 above?
> > 
> > chgrp mysql "${ROOT}/${MY_DATADIR}"/{mysql,test} 2>/dev/null
> 
> What's the owner/group on $MY_DATADIR at that point? The chgrp will also
> affect the target of sym/hard links, so it's important that the mysql user
> not be able to stick a link in place of those two arguments via the same
> race condition. If MY_DATADIR is root:root, it should be safe.
> 
> Another thing that might work is to "su mysql ..." instead of passing --user
> to mysql_install_db.

The end result of pkg_config() without the chown -R is that the mysql and test directories have a mysql:root with 0700 permissions.  I simply wanted to keep those directories as they should be.
Comment 12 Brian Evans (RETIRED) gentoo-dev 2017-09-13 14:50:47 UTC
(In reply to Michael Orlitzky from comment #10)
> Another thing that might work is to "su mysql ..." instead of passing --user
> to mysql_install_db.

"su mysql ..." is not an option as the user does not have a shell and the command fails.
Comment 13 Michael Orlitzky gentoo-dev 2017-09-13 15:56:54 UTC
(In reply to Brian Evans from comment #12)
> 
> "su mysql ..." is not an option as the user does not have a shell and the
> command fails.

You should be able to override that with --shell.
Comment 14 Brian Evans (RETIRED) gentoo-dev 2017-09-14 17:35:47 UTC
Created attachment 494538 [details]
bug-630822.patch

Proposed patch for 10.2.8 and similar in eclasses.  I was not able to use su effectively and break out the array.  This still does the same job and only does chgrp on special directories.
Comment 16 Michael Orlitzky gentoo-dev 2017-10-24 21:15:35 UTC
(In reply to Michael Orlitzky from comment #15)
> 
> Can we make this public so that I can reference it in the CVE request?

Ping =)
Comment 17 Thomas Deutschmann (RETIRED) gentoo-dev 2017-10-25 23:03:54 UTC
Thank you Michael for the report and thank you Brian for the fix.

Like said in comment #15, everything is done. No bumps or user action required. Vulnerability only existed while emerging one of the affected ebuilds/ebuilds using affected eclasses.
Comment 18 Michael Orlitzky gentoo-dev 2017-10-25 23:54:40 UTC
(In reply to Thomas Deutschmann from comment #17)
> Thank you Michael for the report and thank you Brian for the fix.
> 
> Like said in comment #15, everything is done. No bumps or user action
> required. Vulnerability only existed while emerging one of the affected
> ebuilds/ebuilds using affected eclasses.

That's not *entirely* true.. the pkg_config phase had a similar problem, so if you installed a vulnerable version last month and waited until today to set it up, then you might want to upgrade first.

That scenario is a bit outlandish, though, because someone needs to gain access to the "mysql" user in order to do anything. If the database was never configured, that's next to impossible. The only plausible scenario is a pre-existing, exploited mysql installation that has had its databases wiped (and now needs them re-created). I won't be offended if you decide not to spend your time warning people about that.
Comment 19 Thomas Deutschmann (RETIRED) gentoo-dev 2017-10-26 00:06:56 UTC
Re-opened to evaluate which packages need a rev bump.

Thanks, Michael.
Comment 20 Michael Orlitzky gentoo-dev 2017-10-26 00:47:12 UTC
(In reply to Thomas Deutschmann from comment #19)
> Re-opened to evaluate which packages need a rev bump.
> 
> Thanks, Michael.

What will portage do if you try to `emerge --config` a version that no longer exists? If it uses a newer version's pkg_config, or if it forces you to upgrade first -- then there's actually no need for a new revision: users need only sync their trees to remove the vulnerable code.
Comment 21 Thomas Deutschmann (RETIRED) gentoo-dev 2017-10-27 12:42:51 UTC
(In reply to Michael Orlitzky from comment #20)
> What will portage do if you try to `emerge --config` a version that no
> longer exists? If it uses a newer version's pkg_config, or if it forces you
> to upgrade first -- then there's actually no need for a new revision: users
> need only sync their trees to remove the vulnerable code.

When you emerge an ebuild, everything, including used eclasses, will be cached in the package db. This allows the user to run "emerge --config" at anytime to get the expected results even if we have removed the code from the eclass in the meantime.

However, if there was a problem in the ebuild/eclass, the user has to re-emerge the ebuild to get the fix.

That's the problem in this case.

dev-db/mariadb:

 - Affected by pkg_postinst:

   Fixed in >=mariadb-10.2.9.
   Affected mariadb-10.2.x ebuilds are removed.

   => pkg_postinst vulnerability is fixed!

 - Affected by eclass:

   Fixed eclasses available since 2017-09-28 22:30:51 -0400.
   However, users with

     - mariadb-10.0.30
     - mariadb-10.0.32
     - mariadb-10.1.24
     - mariadb-10.1.26

   installed are probably affected if they have emerged the package before the
   date mentioned above.


dev-db/mysql:

 - Affected by pkg_postinst: -

 - Affected by eclass:

   Fixed eclasses available since 2017-09-28 22:30:51 -0400.
   However, users with

     - mysql-5.6.36
     - mysql-5.6.37

   installed are probably affected if they have emerged the package before the
   date mentioned above.


dev-db/percona-server:

 - Affected by pkg_postinst: -

 - Affected by eclass:

   Fixed eclasses available since 2017-09-28 22:30:51 -0400.
   However, users with

     - percona-server-5.6.37.82.2

   installed are probably affected if they have emerged the package before the
   date mentioned above.


dev-db/mysql-cluster:

 - Affected by pkg_postinst: -

 - Affected by eclass:

   Fixed eclasses available since 2017-09-28 22:30:51 -0400.
   However, users with

     - mysql-cluster-7.2.22
     - mysql-cluster-7.3.11

   installed are probably affected if they have emerged the package before the
   date mentioned above.


dev-db/mariadb-galera:

 - Affected by pkg_postinst: -

 - Affected by eclass: - (only available ebuild in repository was bumped after eclasses were fixed)
Comment 22 Michael Orlitzky gentoo-dev 2017-10-27 21:14:26 UTC
(In reply to Thomas Deutschmann from comment #21)
> 
> When you emerge an ebuild, everything, including used eclasses, will be
> cached in the package db. This allows the user to run "emerge --config" at
> anytime to get the expected results even if we have removed the code from
> the eclass in the meantime.
> 
> However, if there was a problem in the ebuild/eclass, the user has to
> re-emerge the ebuild to get the fix.

Thanks, that's important to know. I see now that portage is saving the ebuilds, but are the eclasses kept somewhere too? The PMS doesn't say what goes on in the VDB, so regardless, I think we should tell everyone to update or reinstall, just to keep things simple.

I requested a CVE for this (CVE-2017-15945), and my suggested fix is the following:

  1. Update your ::gentoo tree.

  2. Upgrade the affected packages to the latest version that your package
     manager suggests.

  3. If an affected package was not upgraded in the previous step (for
     example, if no new version was available), then reinstall that package
     manually.

That should cover everyone, I think?
Comment 23 Thomas Deutschmann (RETIRED) gentoo-dev 2017-10-27 22:31:16 UTC
(In reply to Michael Orlitzky from comment #22)
> I see now that portage is saving the ebuilds, but are the eclasses
> kept somewhere too?

The used eclasses are cached in "environment.bz2".


>   3. If an affected package was not upgraded in the previous step (for
>      example, if no new version was available), then reinstall that package
>      manually.
I will file vulnerability bugs for each affected package to track the bumping. Everything else is not an option. Think about binary package users.
Comment 24 Michael Orlitzky gentoo-dev 2017-10-27 23:21:34 UTC
(In reply to Thomas Deutschmann from comment #23)
> 
> The used eclasses are cached in "environment.bz2".

Aha!


> I will file vulnerability bugs for each affected package to track the
> bumping. Everything else is not an option. Think about binary package users.

In hindsight, that is the simplest thing to do, and it makes the advice for end users easier to understand. I can update the CVE page afterwards. Thanks again.
Comment 25 Michael Orlitzky gentoo-dev 2017-11-06 16:41:34 UTC
I updated the CVE with the full list of affected packages, and the new mitigation instructions ("just upgrade").
Comment 26 D'juan McDonald (domhnall) 2019-07-17 02:32:58 UTC
All good here? https://security.gentoo.org/glsa/201711-04