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'
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?
(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.
Oops, I meant /etc/postgresql-$SLOT/postgresql.conf above, not /etc/postgresql.conf.
(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.
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.
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.
(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?
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.
(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.
(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.
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.
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.
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.
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
(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.
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
This has been completed 3 months ago now. What's our next step to closed this bug?
Converting into security bug. Bug is now public. Added to an existing GLSA.
This issue was resolved and addressed in GLSA 201810-08 at https://security.gentoo.org/glsa/201810-08 by GLSA coordinator Thomas Deutschmann (whissi).