Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 628540 (CVE-2017-18240) - <app-admin/collectd-5.7.2-r1: privilege escalation via PID file manipulation
Summary: <app-admin/collectd-5.7.2-r1: privilege escalation via PID file manipulation
Status: RESOLVED FIXED
Alias: CVE-2017-18240
Product: Gentoo Security
Classification: Unclassified
Component: Vulnerabilities (show other bugs)
Hardware: All Linux
: Normal major (vote)
Assignee: Gentoo Security
URL:
Whiteboard: B1 [glsa+ cve]
Keywords:
Depends on:
Blocks: CVE-2017-16820
  Show dependency tree
 
Reported: 2017-08-21 18:10 UTC by Michael Orlitzky
Modified: 2018-03-22 00:21 UTC (History)
1 user (show)

See Also:
Package list:
app-admin/collectd-5.7.2-r1
Runtime testing required: ---
stable-bot: sanity-check+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Orlitzky gentoo-dev 2017-08-21 18:10:59 UTC
The init script for collectd gives ownership of the PID file directory to the same user that the daemon runs as:

  checkpath --directory
            --mode 0770
            --owner ${COLLECTD_USER}:${COLLECTD_GROUP}
            "$(dirname "${COLLECTD_PIDFILE}")"

As a result, the $COLLECTD_USER can write whatever he wants into the PID file. Later, that may be exploitable: when the service is stopped, root will call "kill" on the contents of that file.

The init script is doing that because start-stop-daemon starts collectd as the ${COLLECTD_USER} user. Thus the PID file created by the daemon is created by the ${COLLECTD_USER} user, who needs permission to write it. The usual way that this problem is avoided is that the daemon itself drops privileges, rather than start-stop-daemon doing the work. However, collectd doesn't have any such user/group options.

Fortunately, collectd *does* have the ability to run in the foreground. As a workaround, you can pass the "-f" flag to collectd to run it in the foreground. Then command_background=true can be used to tell start-stop-daemon that it should both force the process into the background, and manage the PID file itself. That will require no special privileges on the PID directory, thus avoiding the vulnerability.

To summarize the changes that I would make:

  1. add "-f" to command_args, and drop -P "${COLLECTD_PIDFILE}" from it.
  2. set command_background=true
  3. use /run/collectd.pid (writable only by root) as the COLLECTD_PIDFILE.
  4. eliminate the (now redundant) stop_post function
  5. utilize command_user to set the user/group, rather than start_stop_daemon_args
Comment 1 Thomas Deutschmann (RETIRED) gentoo-dev 2017-08-21 20:38:27 UTC
(In reply to Michael Orlitzky from comment #0)
> The init script for collectd gives ownership of the PID file directory to
> the same user that the daemon runs as:
> 
>   checkpath --directory
>             --mode 0770
>             --owner ${COLLECTD_USER}:${COLLECTD_GROUP}
>             "$(dirname "${COLLECTD_PIDFILE}")"
> 
> As a result, the $COLLECTD_USER can write whatever he wants into the PID
> file. Later, that may be exploitable: when the service is stopped, root will
> call "kill" on the contents of that file.

I maybe miss a thing but collectd uses OpenRC's default stop function:

> ssd_stop()
> {
>         local _progress=
>         local startcommand="$(service_get_value "command")"
>         local startchroot="$(service_get_value "chroot")"
>         local startpidfile="$(service_get_value "pidfile")"
>         local startprocname="$(service_get_value "procname")"
>         command="${startcommand:-$command}"
>         chroot="${startchroot:-$chroot}"
>         pidfile="${startpidfile:-$pidfile}"
>         procname="${startprocname:-$procname}"
>         [ -n "$command" -o -n "$procname" -o -n "$pidfile" ] || return 0
>         yesno "${command_progress}" && _progress=--progress
>         ebegin "Stopping ${name:-$RC_SVCNAME}"
>         start-stop-daemon --stop \
>                 ${retry:+--retry} $retry \
>                 ${command:+--exec} $command \
>                 ${procname:+--name} $procname \
>                 ${pidfile:+--pidfile} $chroot$pidfile \
>                 ${stopsig:+--signal} $stopsig \
>                 ${_progress}
> 
>         eend $? "Failed to stop ${name:-$RC_SVCNAME}"
> }

(https://github.com/OpenRC/openrc/blob/master/sh/start-stop-daemon.sh)

And the runscript defines "command":

> command="/usr/sbin/collectd"

(https://gitweb.gentoo.org/repo/gentoo.git/tree/app-admin/collectd/files/collectd.initd-r1#n14)

...so I don't understand how a user able to control the content of "/run/collectd/collectd.pid" (and you are right, per default, the collectd user is able to control this file) could abuse this file to escalate privileges: Start-stop-daemon should detect that the PID doesn't match the command.
Comment 2 Michael Orlitzky gentoo-dev 2017-08-21 22:45:24 UTC
(In reply to Thomas Deutschmann from comment #1)
> Start-stop-daemon should detect that the PID doesn't match the
> command.

A reasonable assumption that turns out to be wrong if you try it =)
Comment 3 Michael Orlitzky gentoo-dev 2017-08-21 23:01:49 UTC
It would be nice if we could fix issues like these wholesale, but it's not so clear-cut; e.g.

  https://github.com/OpenRC/openrc/pull/156

In the meantime, it's still a good idea to update the init scripts because people copy around stop() and reload() functions without any regard for what they're doing. Even if OpenRC was able to check the command name against the PID, there are plenty of copy/pasted stop() functions that don't pass the command name to s-s-d. Having bulletproof examples in the tree provides another layer of defense against the issue.
Comment 4 Larry the Git Cow gentoo-dev 2018-01-25 22:34:43 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=9a70b58bd58ff19395c55abbf0a2e620a5a56f3a

commit 9a70b58bd58ff19395c55abbf0a2e620a5a56f3a
Author:     Thomas Deutschmann <whissi@gentoo.org>
AuthorDate: 2018-01-25 22:34:18 +0000
Commit:     Thomas Deutschmann <whissi@gentoo.org>
CommitDate: 2018-01-25 22:34:34 +0000

    app-admin/collectd: bump, fixes CVE-2017-16820 & #628540
    
    Ebuild changes:
    ===============
    - To address bug 628540, we no longer run collectd in
      daemon mode, instead we will run collectd everywhere
      in foreground and let the init system handle the PID
      file.
    
    - /run/collectd/ (default location for collectd's UNIX socket)
      is now maintained using tmpfiles service.
    
    Bug: https://bugs.gentoo.org/628540
    Bug: https://bugs.gentoo.org/637538
    Package-Manager: Portage-2.3.20, Repoman-2.3.6

 app-admin/collectd/collectd-5.7.2-r1.ebuild        | 541 +++++++++++++++++++++
 .../files/collectd-5.7.2-CVE-2017-16820.patch      |  39 ++
 app-admin/collectd/files/collectd.confd-r2         |  49 ++
 app-admin/collectd/files/collectd.initd-r2         |  70 +++
 app-admin/collectd/files/collectd.tmpfile          |   1 +
 5 files changed, 700 insertions(+)}
Comment 5 Thomas Deutschmann (RETIRED) gentoo-dev 2018-01-25 22:37:25 UTC
@ Michael: Could you please review my changes if they address all the problems?
Comment 6 Michael Orlitzky gentoo-dev 2018-01-27 00:31:12 UTC
Looks good, thanks!
Comment 7 Thomas Deutschmann (RETIRED) gentoo-dev 2018-01-27 00:33:00 UTC
Thanks for the review and the report :)

@ Arches,

please test and mark stable: =app-admin/collectd-5.7.2-r1
Comment 8 Thomas Deutschmann (RETIRED) gentoo-dev 2018-01-28 16:37:25 UTC
x86 stable
Comment 9 Agostino Sarubbo gentoo-dev 2018-01-31 07:59:29 UTC
amd64 stable
Comment 10 Markus Meier gentoo-dev 2018-02-05 21:18:42 UTC
arm stable, all arches done.
Comment 11 Larry the Git Cow gentoo-dev 2018-03-03 16:43:58 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=c148c069385caf68d0bc5609ce13db4ba9e71415

commit c148c069385caf68d0bc5609ce13db4ba9e71415
Author:     Thomas Deutschmann <whissi@gentoo.org>
AuthorDate: 2018-03-03 16:41:59 +0000
Commit:     Thomas Deutschmann <whissi@gentoo.org>
CommitDate: 2018-03-03 16:43:51 +0000

    app-admin/collectd: Security cleanup
    
    Bug: https://bugs.gentoo.org/628540
    Package-Manager: Portage-2.3.24, Repoman-2.3.6

 app-admin/collectd/Manifest                        |   2 -
 app-admin/collectd/collectd-5.6.2-r4.ebuild        | 532 --------------------
 app-admin/collectd/collectd-5.7.1.ebuild           | 537 ---------------------
 app-admin/collectd/collectd-5.7.2.ebuild           | 536 --------------------
 .../files/collectd-5.6.2-CVE-2017-7401.patch       |  56 ---
 .../collectd/files/collectd-5.6.2-issue2303.patch  |  44 --
 app-admin/collectd/files/collectd.confd-r1         |  45 --
 app-admin/collectd/files/collectd.initd-r1         |  78 ---
 8 files changed, 1830 deletions(-)}
Comment 12 Thomas Deutschmann (RETIRED) gentoo-dev 2018-03-03 16:44:43 UTC
New GLSA request filed.
Comment 13 Christopher Díaz Riveros (RETIRED) gentoo-dev Security 2018-03-19 02:10:38 UTC
CVE-2017-18240 Assigned.
Comment 14 GLSAMaker/CVETool Bot gentoo-dev 2018-03-22 00:21:49 UTC
This issue was resolved and addressed in
 GLSA 201803-10 at https://security.gentoo.org/glsa/201803-10
by GLSA coordinator Christopher Diaz Riveros (chrisadr).