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: | postgresql | Assignee: | Tom Lane <tgl> |
Status: | CLOSED DUPLICATE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
Severity: | unspecified | Docs Contact: | |
Priority: | unspecified | ||
Version: | 17 | CC: | 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
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. 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. [ 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. CC: Dan Walsh as the owner of the ServicesPrivateTmp feature 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. 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. 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." (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. 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) /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. (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. (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. 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? (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. (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. (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 ... (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? (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? I don't see anything to fix here in systemd, reassigning to Postgresql. 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 *** |