Bug 801506

Summary: Postgresql, please enable PrivateTmp=yes and move AF_UNIX sockets to /run, rather then /tmp
Product: [Fedora] Fedora Reporter: Bruno Wolff III <bruno>
Component: postgresqlAssignee: Tom Lane <tgl>
Status: CLOSED DUPLICATE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 17CC: bruno, devrim, dwalsh, hhorak, johannbg, lpoetter, metherid, mschmidt, notting, petr.tuma, plautrba, systemd-maint, tgl
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-08-09 02:21:03 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Bruno Wolff III 2012-03-08 17:30:30 UTC
Description of problem:
The standard postgres domain socket location is not visible to services (such as httpd) that use the private /tmp feature. While a local network connection can be used instead, you lose easy ident authentication.

It would be nice to be able to keep private /tmp turned on for httpd while also running postgres in its normal configuration and still be able to use unix domain sockets.

Version-Release number of selected component (if applicable):
postgresql-server-9.1.3-1.fc17.x86_64

How reproducible:


Steps to Reproduce:
1.
2.
3.
  
Actual results:


Expected results:


Additional info:

Comment 1 Tom Lane 2012-03-08 17:44:21 UTC
I'm inclined to reassign this to systemd and let them think of a solution.  We're not relocating the postgres socket --- that's an API break with unforeseeable but not small consequences.

Comment 2 Bruno Wolff III 2012-03-08 17:50:10 UTC
That would be OK.

If things don't change for the release, this would be a good thing to have in the Fedora 17 release notes.

Comment 3 Tom Lane 2012-03-08 18:10:33 UTC
[ reassigning to systemd because I think that's the component responsible for the implementation of PrivateTmp ... but I might be wrong about that ]

IMO this complaint illustrates that there is a need for PrivateTmp to be selective somehow.  Yes, ordinary files in /tmp ought to be relocated elsewhere, but there are services that put communication sockets in /tmp and are not likely to change that decision.  postgresql is one, X11 is another.  The feature needs to be tweaked to not break that.  I'm not sure if it'd be more reasonable to key off the file type ("any socket in /tmp is globally visible") or just whitelist certain name patterns.  The postgresql server itself could not be changed to use PrivateTmp unless it could whitelist both the socket itself and the ordinary-file lockfile that has to live beside the socket.

Comment 4 Michal Schmidt 2012-03-09 07:44:16 UTC
CC: Dan Walsh as the owner of the ServicesPrivateTmp feature

Comment 5 Daniel Walsh 2012-03-09 14:56:24 UTC
Tom, X also uses the abstract name space for this,  So X listens on both @/tmp/.X11/X0 and /tmp/.X11/X0. The library that connects to the socket always tries the abstract namespace first, which is what allows tools like sandbox to work.

Comment 6 Tom Lane 2012-03-09 15:11:31 UTC
Um ... what is an abstract name space, and exactly how invasive might it be to persuade postgres and all its different client libraries to know about it?

Frankly, I thought the selling point of PrivateTmp was that it was a *transparent* security improvement.  The chances of getting multiple upstreams to take back code changes in support of it are not good.

Comment 7 Daniel Walsh 2012-03-09 15:47:39 UTC
Well one of the goals is to stop apps from using /tmp and instead use /run (/var/run).  Which is what privileged apps should be doing.

Google finds.

http://blog.eduardofleury.com/archives/2007/09/13/

As a good description of this.

I guess if there was one place within postgresql libraries to create/bind/connect to the /tmp/postgres_fifo file, then the change would only need to be here.  And the change is simply to prepend '\0' to the path.

"The trick to trigger the abstract namespace is simple: start the name with a null-byte. All characters found after the null-byte will then be interpreted as the identifier name and the socket will registered by the Kernel under the given name."

Comment 8 Kay Sievers 2012-03-09 15:59:04 UTC
(In reply to comment #7)
> Well one of the goals is to stop apps from using /tmp and instead use /run
> (/var/run).  Which is what privileged apps should be doing.

Yeah, we moved quite some tools already to that model. Really, nothing should
use sockets in /tmp today, it's very broken model to put security sensitive
pieces into a world writable directory.

If legacy stuff needs to be supported, with well-known hard-coded paths
in /tmp, we should consider using just symlinks in /tmp to /run, these
links could then possibly be created with tmpfiles in the private /tmp
instance too.

Comment 9 Lennart Poettering 2012-03-12 13:26:32 UTC
It's more often than not a security problem if software places sockets in /tmp, due to the fact that it is a shared namespace.

May I ask what precisely the path of the socket of PostgreSQL is in /tmp?

I am tempted to say that the better solution than turning off PrivateTmp for PostgreSQL and all the packages that might use it is to move PostgreSQL's sockets to /run instead, possibly keeping compatibility symlinks in place which are created at very early boot (for example via tmpfiles or so).

But to figure this out, where are those sockets placed precisely?

(In general I believe that abstract namespace sockets are not really an adequate replacement for this problem simply since they also lie within a shared namespace and hence subject to DoS attacks. The place for AF_UNIX sockets is /run and nothing but /run)

Comment 10 Bruno Wolff III 2012-03-12 13:37:55 UTC
/tmp/.s.PGSQL.5432 and /tmp/.s.PGSQL.5432.lock are the normal places. However 5432 is a (psuedo) port number and can change based on how the server is configured.

Comment 11 Tom Lane 2012-03-12 14:02:57 UTC
(In reply to comment #9)
> I am tempted to say that the better solution than turning off PrivateTmp for
> PostgreSQL and all the packages that might use it is to move PostgreSQL's
> sockets to /run instead, possibly keeping compatibility symlinks in place which
> are created at very early boot (for example via tmpfiles or so).

We've heard that before.  It's nothing but security by knee-jerk.  A socket in /tmp is exactly as secure (or not) as a TCP port at a non-privileged port number, which is the other standard method for connecting to a Postgres server.  If you're concerned about people impersonating the server then you have to use higher-level methods for verifying the identity of the process you've connected to, such as SSL certificates.  And Postgres does provide such methods.

Hence, I'm uninterested in moving the socket.  I'm also not very concerned about turning on PrivateTmp for the Postgres server, because it doesn't put any actual temp files into /tmp, preferring to keep them within its database directory.  (Now, Postgres does allow extension code to be loaded into the server, and it's within the realm of possibility that an extension might create a temp file using non-Postgres-standard methods.  So there's a small chance that PrivateTmp would be useful, and so I'd be willing to turn it on if it were otherwise free ... but not if I have to contend with moving the socket.)

So IMO this is only interesting to the extent that turning on PrivateTmp in potential *client* processes interferes with the clients' ability to connect to the Postgres server.  And here is where I think your argument is fatally flawed.  Clients do not get to dictate where a server listens.  So the long and the short of it is that this supposedly transparent security feature breaks application communication protocols that it has no business breaking.

Comment 12 Michal Schmidt 2012-03-12 14:19:57 UTC
(In reply to comment #11)
> this supposedly transparent security feature breaks
> application communication protocols that it has no business breaking.

I don't know who said it was transparent.
"man systemd.exec" warns that it "makes sharing between processes via /tmp impossible."
Lennart's blog about the feature ( http://0pointer.de/blog/projects/security.html ) has a whole "Caveat" paragraph about sockets in /tmp.

Comment 13 Daniel Walsh 2012-03-12 15:20:58 UTC
Tom we also want to allow users to use private /tmp (pam_namespace) which has been a feature since RHEL5/Fedora 6.  This feature is not exactly new.  If I setup private /tmp for users they would also not be able to access these postgresql ports.

Is this something we should bring up for discussion with upstream postgresql or are you dead set against it?

Comment 14 Lennart Poettering 2012-03-12 19:14:36 UTC
(In reply to comment #11)
> (In reply to comment #9)
> > I am tempted to say that the better solution than turning off PrivateTmp for
> > PostgreSQL and all the packages that might use it is to move PostgreSQL's
> > sockets to /run instead, possibly keeping compatibility symlinks in place which
> > are created at very early boot (for example via tmpfiles or so).
> 
> We've heard that before.  It's nothing but security by knee-jerk.  A socket in
> /tmp is exactly as secure (or not) as a TCP port at a non-privileged port
> number, which is the other standard method for connecting to a Postgres server.
>  If you're concerned about people impersonating the server then you have to use
> higher-level methods for verifying the identity of the process you've connected
> to, such as SSL certificates.  And Postgres does provide such methods.

Well, I am quite sure that you don't have to listen on a TCP port, right? I mean, I know that on my own web server i have always disabled IP for mysql, simply to avoid the attack surface. And with the attack surface the namespace problem is gone too. I am quite sure that quite a number of users only need to access Postgres locally, and it's definitely worth making things safer for them.

But even if you leave TCP enabled: just because A is borked it doesn't mean you have to leave B borked, too.

> Hence, I'm uninterested in moving the socket.  I'm also not very concerned
> about turning on PrivateTmp for the Postgres server, because it doesn't put any
> actual temp files into /tmp, preferring to keep them within its database
> directory.  (Now, Postgres does allow extension code to be loaded into the
> server, and it's within the realm of possibility that an extension might create
> a temp file using non-Postgres-standard methods.  So there's a small chance
> that PrivateTmp would be useful, and so I'd be willing to turn it on if it were
> otherwise free ... but not if I have to contend with moving the socket.)

You know, it's not that simple. By placing your socket in /tmp (where it doesn't belong, and hasn't belonged in quite some time) you make PrivateTmp= unavailable for every service that might access PostgreSQL. That means that due to Postgresql's decision about /tmp you force it on a lot of other services as well. And not only services, but also user session. That's not a nice move.

> So IMO this is only interesting to the extent that turning on PrivateTmp in
> potential *client* processes interferes with the clients' ability to connect to
> the Postgres server.  And here is where I think your argument is fatally
> flawed.  Clients do not get to dictate where a server listens.  So the long and
> the short of it is that this supposedly transparent security feature breaks
> application communication protocols that it has no business breaking.

I have never claimed it to be transparent. It's an option, and it's documented that it might break things that place communication primitives in /tmp. Please note that making use of PrivateTmp= system-wide is a new feature for fedora that has to be implemented across a wide number of packages, to be useful. That requires changes in a variety of places. Mostly in .service files, but sometimes in code as well, for example, to patch daemons to move their sockets to /run, or find another solution.

Let's find a suitable solution here. It would be a pity if just because of PostgreSQL we couldn't implement this feature in all packages which might end up accessing postgresql either directly or by some plugin we ship.

Comment 15 Tom Lane 2012-03-13 14:15:42 UTC
(In reply to comment #13)
> Is this something we should bring up for discussion with upstream postgresql or
> are you dead set against it?

This isn't an issue for upstream, it's a matter of how we configure the Fedora package.  But if you mean would upstream change their default, no they wouldn't.  /tmp is the default for a number of reasons (eg, portability and ability to run a server without any special installation privileges, and of course backwards compatibility at the client protocol level is not going to be lightly dropped).  Compatibility with dubious security features isn't enough to override those reasons.  Upstream's heard all this before.

Comment 16 Tom Lane 2012-03-13 14:18:33 UTC
(In reply to comment #14)
> Well, I am quite sure that you don't have to listen on a TCP port, right?

You're kidding, right?  Or is that about the level of practicality I should expect from you?

> Let's find a suitable solution here.

I suggested a solution in comment #3 ...

Comment 17 Michal Schmidt 2012-03-13 14:32:10 UTC
(In reply to comment #16)
> (In reply to comment #14)
> > Well, I am quite sure that you don't have to listen on a TCP port, right?
> 
> You're kidding, right?  Or is that about the level of practicality I should
> expect from you?

Let's calm down. He wasn't suggesting that the TCP transport be removed. I read it merely as a question asking whether it can be enabled/disabled by the administrator.

> I suggested a solution in comment #3 ...

How would the selectiveness be implemented? By bind-mounting the whitelisted files into each private /tmp instance?

Comment 18 Michal Schmidt 2012-03-13 15:24:32 UTC
(In reply to comment #15)
> /tmp is the default for a number of reasons (eg, portability 

I can understand that /run is seen as a new thing, but what about /var/run? Isn't it portable?
It's identical (symlinked, or bind-mounted) to /run on new Linux systems.

> and ability to run a server without any special installation privileges

This can be solved by putting the socket in a subdirectory /var/run/postgresql owned by the postgres user.

> of course backwards compatibility at the client protocol level is not going
> to be lightly dropped

What incompatibility would the move of the socket cause? Don't client programs use a library that is built from the same sources as the server? Do the clients themselves have to know the path of the socket?
If a flag day transition is not possible for some reason, there could be a transitional period where the socket would be available in both paths.

> Compatibility with dubious security features isn't enough to
> override those reasons.  Upstream's heard all this before.

Do you mean that upstream developers have already discussed the possibility of moving the location of the socket? And that they declined it?

Comment 19 Lennart Poettering 2012-08-08 23:20:38 UTC
I don't see anything to fix here in systemd, reassigning to Postgresql.

Comment 20 Tom Lane 2012-08-09 02:21:03 UTC
Well, the reason this was reassigned to systemd in the first place was to see if any thought would get put into changing the behavior of PrivateTmp.  Since apparently no such thoughts will be entertained, this is just a duplicate of existing bugs.

*** This bug has been marked as a duplicate of bug 825448 ***