Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 603716 - <dev-db/postgresql-{9.2.20-r1,9.3.16-r1,9.4.11-r1,9.5.6-r1,9.6.2-r1}: root privilege escalation via init script
Summary: <dev-db/postgresql-{9.2.20-r1,9.3.16-r1,9.4.11-r1,9.5.6-r1,9.6.2-r1}: root pr...
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Security
Classification: Unclassified
Component: Vulnerabilities (show other bugs)
Hardware: All Linux
: Normal major (vote)
Assignee: Gentoo Security
URL:
Whiteboard: B1 [glsa+]
Keywords:
Depends on:
Blocks:
 
Reported: 2016-12-25 19:24 UTC by Michael Orlitzky
Modified: 2018-10-30 21:08 UTC (History)
2 users (show)

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


Attachments
/etc/conf.d/postgresql-9.5 (postgresql-9.5,2.44 KB, text/plain)
2017-01-02 19:50 UTC, Aaron W. Swenson
no flags Details
/etc/init.d/postgresql-9.5 (postgresql-9.5,5.00 KB, text/plain)
2017-01-02 19:57 UTC, Aaron W. Swenson
no flags Details
Patch ebuilds, initscript, and conf files (secbug-603720.patch,34.77 KB, patch)
2017-02-06 16:56 UTC, Aaron W. Swenson
no flags Details | Diff
secbug-603716.tbz2 (secbug-603716.tbz2,11.92 KB, application/x-bzip)
2017-02-07 15:42 UTC, Aaron W. Swenson
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Orlitzky gentoo-dev 2016-12-25 19:24:32 UTC
The postgresql.conf file is owned by the postgres user (at least everywhere I've checked):

  # ls /etc/postgresql-9.5/
  total 40K
  -rw------- 1 postgres postgres 4.5K 2016-02-27 20:30 pg_hba.conf
  -rw------- 1 postgres postgres 1.6K 2016-02-27 20:26 pg_ident.conf
  -rw------- 1 postgres postgres  22K 2016-02-27 20:30 postgresql.conf

The init script reads the value of "unix_socket_directories" from postgresql.conf:

  get_config() {
    [ -f ${PGDATA%/}/postgresql.conf ] || return 1

    eval echo $(sed -e 's:#.*::' ${PGDATA%/}/postgresql.conf \
      | awk '$1 == "'$1'" { print ($2 == "=" ? $3 : $2) }')
  }

  ...

  socket_paths=$(get_config unix_socket_directories)

And then it gives control of those paths to postgres:postgres:

  for s in ${socket_paths}; do
    checkpath -d -m 1775 -o postgres:postgres ${s}
    ...

Thus the postgres user can gain root by setting, for example,

  unix_socket_directories = '/root'
Comment 1 Aaron W. Swenson gentoo-dev 2016-12-31 19:14:25 UTC
To be clear, the postgres system user does not gain root, only access to the data within /root that aren't restricted, or any directory listed within the unix_socket_directories setting.

The database superusers can read from or write to any file or directory on the system that the postgres system user has permissions to do so via the COPY statement (https://www.postgresql.org/docs/current/static/sql-copy.html). Further, postgresql.conf can be edited within the database via pg_settings (See https://www.postgresql.org/docs/current/static/view-pg-settings.html and https://www.postgresql.org/docs/current/static/config-setting.html).  As both are done via the client interface, remote access is possible.

However, exposure is minimal as there should only be vetted individuals with superuser rights within the database.

To mitigate the risk, we can use a variable within /etc/conf.d/postgresql-${SLOT} to determine which directories, if any, to create and/or alter. Further, we can change the owner from postgres:postgres to root:postgres so that the postgres system user cannot delete/move any files/sockets that belong to other services, such as pgbouncer or pgpool.

While this does not prevent any other directories that the postgres system user has access to from being used, it will eliminate the ability of database superusers from altering permissions on directories they should not have access to.

Is this a suitable resolution?
Comment 2 Michael Orlitzky gentoo-dev 2016-12-31 19:51:49 UTC
(In reply to Aaron W. Swenson from comment #1)
> To be clear, the postgres system user does not gain root, only access to the
> data within /root that aren't restricted, or any directory listed within the
> unix_socket_directories setting.
> 

...but the unix_socket_directories setting is contained in a file owned by the postgres system user (after emerge --config), so he can point it wherever he wants. Once I have ownership of /root, you're right -- I can't read the existing a-x files in there -- but I can replace root's bashrc with one of my own. Or instead I could set 

  unix_socket_directories = '/etc'

and then replace /etc/shadow with my own copy. Or I could take over /bin and replace the bash binary with my own shell. Or add myself to /etc/sudoers...

I didn't realize until now where the postgres:postgres ownership of /etc/postgresql.conf was coming from. Since it's granted by the ebuild, that makes me wonder -- is it really necessary for the postgres user to write to it? If not, the whole problem could be solved by making /etc/postgresql.conf owned by root:postgres and mode 640.

Tightening any other permissions would then be a bonus.
Comment 3 Michael Orlitzky gentoo-dev 2016-12-31 19:53:42 UTC
Oops, I meant /etc/postgresql-$SLOT/postgresql.conf above, not /etc/postgresql.conf.
Comment 4 Aaron W. Swenson gentoo-dev 2016-12-31 21:16:30 UTC
(In reply to Michael Orlitzky from comment #2)
> (In reply to Aaron W. Swenson from comment #1)
> > To be clear, the postgres system user does not gain root, only access to the
> > data within /root that aren't restricted, or any directory listed within the
> > unix_socket_directories setting.
> > 
> 
> ...but the unix_socket_directories setting is contained in a file owned by
> the postgres system user (after emerge --config), so he can point it
> wherever he wants. Once I have ownership of /root, you're right -- I can't
> read the existing a-x files in there -- but I can replace root's bashrc with
> one of my own. Or instead I could set 
> 
>   unix_socket_directories = '/etc'
> 
> and then replace /etc/shadow with my own copy. Or I could take over /bin and
> replace the bash binary with my own shell. Or add myself to /etc/sudoers...

I wasn't disputing this, just clarifying that this isn't a direct privilege escalation. Depending on the infrastructure, it may be impossible to escalate privilege as the only access available may be the database, (i.e., no remote SSH access).

> I didn't realize until now where the postgres:postgres ownership of
> /etc/postgresql.conf was coming from. Since it's granted by the ebuild, that
> makes me wonder -- is it really necessary for the postgres user to write to
> it? If not, the whole problem could be solved by making /etc/postgresql.conf
> owned by root:postgres and mode 640.
> 
> Tightening any other permissions would then be a bonus.

Yes, it's necessary. We cannot change the permissions on the configuration files without breaking functionality and/or making nontrivial changes to PostgreSQL itself, which is why it wasn't proposed as a solution.

Again, only vetted individuals would be able to make any changes to postgresql.conf, pg_hba.conf, and pg_ident.conf. It is good and appropriate that they be able to modify those configuration files. In practice, these same individuals tend to be the system administrators as well.

When it comes to regular database users, they are restricted to a few specific directories that they can read only. By default, there is no means for a regular user to write anything to the PostgreSQL server's filesystem.

Since /etc/{init,conf}.d/postgresql-${SLOT} are restricted to root, the proposed solution moves the creation and/or alteration of directories to those files alone eliminating the ability of any database superuser to expand their domain without the explicit knowledge of the system administrator, if they are indeed separate individuals.
Comment 5 Aaron W. Swenson gentoo-dev 2017-01-02 19:50:09 UTC
Created attachment 458414 [details]
/etc/conf.d/postgresql-9.5

New variable introduced moving the creation and alteration of directories completely under root's control.
Comment 6 Aaron W. Swenson gentoo-dev 2017-01-02 19:57:39 UTC
Created attachment 458416 [details]
/etc/init.d/postgresql-9.5

Uses the new variable alone to determine which directories to create and or modify.

I will have to backpedal a bit and say that pg_hba.conf and pg_ident.conf should not be writable from within the PostgreSQL instance as those can broaden exposure. Indeed, there's no interface to modify those files as there is with postgresql.conf. A properly written pg_hba.conf and/or pg_ident.conf will not, or rarely, need to be touched again.
Comment 7 Michael Orlitzky gentoo-dev 2017-01-03 00:50:46 UTC
(In reply to Aaron W. Swenson from comment #5)
> 
> New variable introduced moving the creation and alteration of directories
> completely under root's control.

This should work, but the duplication of that setting bothers me =P

I've tried to find out for myself, but failed -- when does the postgres daemon need to write directly to postgresql.conf?

I see that through ALTER SYSTEM, the postgres user may need to write to postgresql.auto.conf. However, if we create that (empty) file in emerge --config, is there something else preventing us from making /etc/postgresql-${SLOT} owned by root, and its postgresql.conf file unwritable?
Comment 8 Aaron W. Swenson gentoo-dev 2017-01-03 21:59:46 UTC
Not such a big fan of the duplication myself, but at least it's for something that typically never changes once set.

On to the configuration files, I'm sorry to waffle a little bit as I back-backpedal again, but there are administrative tools, such as pgAdmin, that do work with the config files (postgresql, pg_hba, etc). In order to do so, they must be owned by postgres, including pg_hba and pg_ident. As I've mentioned previously, this privilege is restricted to those who have superuser rights.

I quote RhodiumToad (Andrew), a well-known and respected figure in #postgresql on Freenode, who has this to say:

> <RhodiumToad> TitanOfOld: there's no particular benefit in having pg not own
>               the config files, since if someone's in the server as a db
>               superuser they're already in a position to do pretty much
>               anything

This reinforces my previous point that the superusers should be people that can be trusted to not be evil. Really, the danger isn't so much what superusers do to the system, as much as the danger in what they do with the data managed by PgSQL.

And, since postgresql.auto.conf can override every setting in postgresql.conf -- except for data_directory, which is declared in the initscript's configuration file already, and some compile-time settings -- there's no point in keeping postgresql.conf and friends locked away.

Still, by moving the directory creation/alteration declaration to PG_SOCKET_DIRECTORIES in the initscript's configuration file rather than pulling it from postgresql.conf we can keep the DBAs from taking over the system entirely.
Comment 9 Michael Orlitzky gentoo-dev 2017-01-03 22:23:56 UTC
(In reply to Aaron W. Swenson from comment #8)
> 
> > <RhodiumToad> TitanOfOld: there's no particular benefit in having pg not own
> >               the config files, since if someone's in the server as a db
> >               superuser they're already in a position to do pretty much
> >               anything
> 
> This reinforces my previous point that the superusers should be people that
> can be trusted to not be evil. Really, the danger isn't so much what
> superusers do to the system, as much as the danger in what they do with the
> data managed by PgSQL.

I see the point on a database server, but for another perspective, consider my own personal workstation. I sometimes test web applications that need a database, and I'm more than happy to give them full access to a disposable postgres instance. I'm going to delete the whole thing when I'm done anyway. As a result, I'm pretty careless with who gets to be the DB superuser (Wordpress? Why not?). All of my data is disposable, and the postgres user is supposed to be restricted anyway.

Even though my SQL data is worthless, root on my machine is not: it can commit to ::gentoo. So that's at least one situation where the DB and its superuser account are worthless, but having them gain root could be disastrous.


> Still, by moving the directory creation/alteration declaration to
> PG_SOCKET_DIRECTORIES in the initscript's configuration file rather than
> pulling it from postgresql.conf we can keep the DBAs from taking over the
> system entirely.

Ok, allow me to annoy you with one more idea then =)

Rather than force the user to duplicate the socket path in the conf.d file and in postgresql.conf, why not just delete the setting from postgresql.conf, and then force the value PG_SOCKET_DIRECTORIES on the command-line? That way the conf.d file is the one true source for the socket path. Setting it manually in postgresql.conf should be overridden by the command-line.
Comment 10 Aaron W. Swenson gentoo-dev 2017-01-05 01:53:17 UTC
(In reply to Michael Orlitzky from comment #9)
> (In reply to Aaron W. Swenson from comment #8)
> > 
> > > <RhodiumToad> TitanOfOld: there's no particular benefit in having pg not own
> > >               the config files, since if someone's in the server as a db
> > >               superuser they're already in a position to do pretty much
> > >               anything
> > 
> > This reinforces my previous point that the superusers should be people that
> > can be trusted to not be evil. Really, the danger isn't so much what
> > superusers do to the system, as much as the danger in what they do with the
> > data managed by PgSQL.
> 
> I see the point on a database server, but for another perspective, consider
> my own personal workstation. I sometimes test web applications that need a
> database, and I'm more than happy to give them full access to a disposable
> postgres instance. I'm going to delete the whole thing when I'm done anyway.
> As a result, I'm pretty careless with who gets to be the DB superuser
> (Wordpress? Why not?). All of my data is disposable, and the postgres user
> is supposed to be restricted anyway.
> 
> Even though my SQL data is worthless, root on my machine is not: it can
> commit to ::gentoo. So that's at least one situation where the DB and its
> superuser account are worthless, but having them gain root could be
> disastrous.

I understand your argument and concern. Superuser privilege should only be given to real people. You may need to be a superuser to install it in the first place, but if some application need to be superuser...the developers would be lambasted, I'm sure.

> Ok, allow me to annoy you with one more idea then =)

You haven't been annoying. Challenging maybe, but I've learned a bit more about the system.

> Rather than force the user to duplicate the socket path in the conf.d file
> and in postgresql.conf, why not just delete the setting from
> postgresql.conf, and then force the value PG_SOCKET_DIRECTORIES on the
> command-line? That way the conf.d file is the one true source for the socket
> path. Setting it manually in postgresql.conf should be overridden by the
> command-line.

I'm okay with this. I'll work on getting it sorted.
Comment 11 Aaron W. Swenson gentoo-dev 2017-02-06 16:56:45 UTC
Created attachment 462670 [details, diff]
Patch ebuilds, initscript, and conf files

You can run this patch withinin dev-db/postgresql to give the things a go.

The ebuilds now delete unix_socket_director{y,ies} from postgresql.conf.

9.1 is excluded as it is EOL and I will mask it with this security release. (An impending version bump is also on the way in a week or so.)

I'm sorry if things are a bit messy. I have a new postgresql.eselect module to get out as well.
Comment 12 Aaron W. Swenson gentoo-dev 2017-02-07 15:42:48 UTC
Created attachment 462806 [details]
secbug-603716.tbz2

Okay, I got a cleaned up set ready for review.

Upstream will be releasing an update this Thursday and I'd like to have this in place for that release.
Comment 13 Kristian Fiskerstrand (RETIRED) gentoo-dev 2017-02-11 13:30:11 UTC
Thank you. I've done a quick review of the updated files and it looks good to me, although mjo is closer to this particular issue.
Comment 14 Aaron W. Swenson gentoo-dev 2017-04-18 12:14:48 UTC
The fixes have been committed, but I've been vague on the reason.

commit f1b07f8816c2f0346d07468bdb4c5b9ce4ffada7
Author: Aaron W. Swenson <titanofold@gentoo.org>
Date:   Mon Apr 17 09:09:56 2017 -0400

    dev-db/postgresql: Eselect and security related fixes
    
    Dependency bumped on app-eselect/eselect-postgresql to 2.0. Some of
    its work has been shifted into the ebuild as the files/links don’t
    change until this package is reemerge, unmerged, or updated.
    
    Security issues addressed in the initscripts per bugs 603716 and 603720.
    
    Bugs: 603716, 603720
Comment 15 Michael Orlitzky gentoo-dev 2017-04-22 23:51:10 UTC
(In reply to Aaron W. Swenson from comment #14)
> The fixes have been committed, but I've been vague on the reason.
> 

For the record, I've looked through these and don't see any problems.
Comment 16 Aaron W. Swenson gentoo-dev 2018-02-11 15:56:18 UTC
commit 850efe2a5700c2ba30f9e9860dd83143cf15da34 (HEAD -> master, origin/master, origin/HEAD)
Author: Aaron W. Swenson <titanofold@gentoo.org>
Date:   Sun Feb 11 10:54:10 2018 -0500

    dev-db/postgresql: Cleanup Old and Insecure Files

    Bug: https://bugs.gentoo.org/627462
    Bug: https://bugs.gentoo.org/636978
    Bug: https://bugs.gentoo.org/630824
    Bug: https://bugs.gentoo.org/603720
    Bug: https://bugs.gentoo.org/603716
    Package-Manager: Portage-2.3.19, Repoman-2.3.6

commit 3b3ec30d0b02920ec76eeef4db2a968c3a907d23
Author: Jeroen Roovers <jer@gentoo.org>
Date:   Sun Feb 11 13:09:46 2018 +0100

    dev-db/postgresql: Stable for HPPA too.

    Package-Manager: Portage-2.3.24, Repoman-2.3.6
    RepoMan-Options: --ignore-arches
Comment 17 Aaron W. Swenson gentoo-dev 2018-05-20 09:50:48 UTC
This has been  completed 3 months ago now. What's our next step to closed this bug?
Comment 18 Thomas Deutschmann (RETIRED) gentoo-dev 2018-10-30 19:08:46 UTC
Converting into security bug.
Bug is now public.

Added to an existing GLSA.
Comment 19 GLSAMaker/CVETool Bot gentoo-dev 2018-10-30 21:08:32 UTC
This issue was resolved and addressed in
 GLSA 201810-08 at https://security.gentoo.org/glsa/201810-08
by GLSA coordinator Thomas Deutschmann (whissi).