2005-03-10 08:14:03 +01:00
|
|
|
/*
|
|
|
|
* fork_process.c
|
2005-10-15 04:49:52 +02:00
|
|
|
* A simple wrapper on top of fork(). This does not handle the
|
|
|
|
* EXEC_BACKEND case; it might be extended to do so, but it would be
|
|
|
|
* considerably more complex.
|
2005-03-10 08:14:03 +01:00
|
|
|
*
|
2019-01-02 18:44:25 +01:00
|
|
|
* Copyright (c) 1996-2019, PostgreSQL Global Development Group
|
2005-03-10 08:14:03 +01:00
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/backend/postmaster/fork_process.c
|
2005-03-10 08:14:03 +01:00
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "postmaster/fork_process.h"
|
|
|
|
|
2010-01-11 19:39:32 +01:00
|
|
|
#include <fcntl.h>
|
2005-03-14 00:27:38 +01:00
|
|
|
#include <time.h>
|
2010-01-11 19:39:32 +01:00
|
|
|
#include <sys/stat.h>
|
2005-03-14 00:27:38 +01:00
|
|
|
#include <sys/time.h>
|
2005-03-10 08:14:03 +01:00
|
|
|
#include <unistd.h>
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
#ifdef USE_OPENSSL
|
Reset OpenSSL randomness state in each postmaster child process.
Previously, if the postmaster initialized OpenSSL's PRNG (which it will do
when ssl=on in postgresql.conf), the same pseudo-random state would be
inherited by each forked child process. The problem is masked to a
considerable extent if the incoming connection uses SSL encryption, but
when it does not, identical pseudo-random state is made available to
functions like contrib/pgcrypto. The process's PID does get mixed into any
requested random output, but on most systems that still only results in 32K
or so distinct random sequences available across all Postgres sessions.
This might allow an attacker who has database access to guess the results
of "secure" operations happening in another session.
To fix, forcibly reset the PRNG after fork(). Each child process that has
need for random numbers from OpenSSL's generator will thereby be forced to
go through OpenSSL's normal initialization sequence, which should provide
much greater variability of the sequences. There are other ways we might
do this that would be slightly cheaper, but this approach seems the most
future-proof against SSL-related code changes.
This has been assigned CVE-2013-1900, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
Back-patch to all supported branches.
Marko Kreen
2013-03-27 23:50:21 +01:00
|
|
|
#include <openssl/rand.h>
|
|
|
|
#endif
|
2005-03-10 08:14:03 +01:00
|
|
|
|
2005-03-16 01:02:39 +01:00
|
|
|
#ifndef WIN32
|
2005-03-10 08:14:03 +01:00
|
|
|
/*
|
|
|
|
* Wrapper for fork(). Return values are the same as those for fork():
|
|
|
|
* -1 if the fork failed, 0 in the child process, and the PID of the
|
|
|
|
* child in the parent process.
|
|
|
|
*/
|
|
|
|
pid_t
|
|
|
|
fork_process(void)
|
|
|
|
{
|
2005-10-15 04:49:52 +02:00
|
|
|
pid_t result;
|
2014-06-19 02:12:47 +02:00
|
|
|
const char *oomfilename;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2005-03-10 08:14:03 +01:00
|
|
|
#ifdef LINUX_PROFILE
|
|
|
|
struct itimerval prof_itimer;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Flush stdio channels just before fork, to avoid double-output problems.
|
|
|
|
* Ideally we'd use fflush(NULL) here, but there are still a few non-ANSI
|
|
|
|
* stdio libraries out there (like SunOS 4.1.x) that coredump if we do.
|
|
|
|
* Presently stdout and stderr are the only stdio output channels used by
|
|
|
|
* the postmaster, so fflush'ing them should be sufficient.
|
2005-03-10 08:14:03 +01:00
|
|
|
*/
|
|
|
|
fflush(stdout);
|
|
|
|
fflush(stderr);
|
|
|
|
|
|
|
|
#ifdef LINUX_PROFILE
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2005-03-10 08:14:03 +01:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Linux's fork() resets the profiling timer in the child process. If we
|
|
|
|
* want to profile child processes then we need to save and restore the
|
|
|
|
* timer setting. This is a waste of time if not profiling, however, so
|
|
|
|
* only do it if commanded by specific -DLINUX_PROFILE switch.
|
2005-03-10 08:14:03 +01:00
|
|
|
*/
|
|
|
|
getitimer(ITIMER_PROF, &prof_itimer);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
result = fork();
|
2006-01-05 04:01:38 +01:00
|
|
|
if (result == 0)
|
2005-03-10 08:14:03 +01:00
|
|
|
{
|
|
|
|
/* fork succeeded, in child */
|
|
|
|
#ifdef LINUX_PROFILE
|
|
|
|
setitimer(ITIMER_PROF, &prof_itimer, NULL);
|
|
|
|
#endif
|
|
|
|
|
2010-01-11 19:39:32 +01:00
|
|
|
/*
|
|
|
|
* By default, Linux tends to kill the postmaster in out-of-memory
|
|
|
|
* situations, because it blames the postmaster for the sum of child
|
|
|
|
* process sizes *including shared memory*. (This is unbelievably
|
|
|
|
* stupid, but the kernel hackers seem uninterested in improving it.)
|
|
|
|
* Therefore it's often a good idea to protect the postmaster by
|
2014-06-19 02:12:47 +02:00
|
|
|
* setting its OOM score adjustment negative (which has to be done in
|
|
|
|
* a root-owned startup script). Since the adjustment is inherited by
|
|
|
|
* child processes, this would ordinarily mean that all the
|
|
|
|
* postmaster's children are equally protected against OOM kill, which
|
|
|
|
* is not such a good idea. So we provide this code to allow the
|
|
|
|
* children to change their OOM score adjustments again. Both the
|
|
|
|
* file name to write to and the value to write are controlled by
|
|
|
|
* environment variables, which can be set by the same startup script
|
|
|
|
* that did the original adjustment.
|
2012-06-13 21:34:57 +02:00
|
|
|
*/
|
2014-06-19 02:12:47 +02:00
|
|
|
oomfilename = getenv("PG_OOM_ADJUST_FILE");
|
2012-06-13 21:34:57 +02:00
|
|
|
|
2014-06-19 02:12:47 +02:00
|
|
|
if (oomfilename != NULL)
|
2010-01-11 19:39:32 +01:00
|
|
|
{
|
|
|
|
/*
|
2010-02-26 03:01:40 +01:00
|
|
|
* Use open() not stdio, to ensure we control the open flags. Some
|
|
|
|
* Linux security environments reject anything but O_WRONLY.
|
2010-01-11 19:39:32 +01:00
|
|
|
*/
|
2014-06-19 02:12:47 +02:00
|
|
|
int fd = open(oomfilename, O_WRONLY, 0);
|
2010-01-11 19:39:32 +01:00
|
|
|
|
|
|
|
/* We ignore all errors */
|
|
|
|
if (fd >= 0)
|
|
|
|
{
|
2014-06-19 02:12:47 +02:00
|
|
|
const char *oomvalue = getenv("PG_OOM_ADJUST_VALUE");
|
2012-05-27 21:35:01 +02:00
|
|
|
int rc;
|
2010-01-11 19:39:32 +01:00
|
|
|
|
2014-06-19 02:12:47 +02:00
|
|
|
if (oomvalue == NULL) /* supply a useful default */
|
|
|
|
oomvalue = "0";
|
|
|
|
|
|
|
|
rc = write(fd, oomvalue, strlen(oomvalue));
|
2012-05-27 21:35:01 +02:00
|
|
|
(void) rc;
|
2010-01-11 19:39:32 +01:00
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
}
|
Reset OpenSSL randomness state in each postmaster child process.
Previously, if the postmaster initialized OpenSSL's PRNG (which it will do
when ssl=on in postgresql.conf), the same pseudo-random state would be
inherited by each forked child process. The problem is masked to a
considerable extent if the incoming connection uses SSL encryption, but
when it does not, identical pseudo-random state is made available to
functions like contrib/pgcrypto. The process's PID does get mixed into any
requested random output, but on most systems that still only results in 32K
or so distinct random sequences available across all Postgres sessions.
This might allow an attacker who has database access to guess the results
of "secure" operations happening in another session.
To fix, forcibly reset the PRNG after fork(). Each child process that has
need for random numbers from OpenSSL's generator will thereby be forced to
go through OpenSSL's normal initialization sequence, which should provide
much greater variability of the sequences. There are other ways we might
do this that would be slightly cheaper, but this approach seems the most
future-proof against SSL-related code changes.
This has been assigned CVE-2013-1900, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
Back-patch to all supported branches.
Marko Kreen
2013-03-27 23:50:21 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure processes do not share OpenSSL randomness state.
|
|
|
|
*/
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
#ifdef USE_OPENSSL
|
Reset OpenSSL randomness state in each postmaster child process.
Previously, if the postmaster initialized OpenSSL's PRNG (which it will do
when ssl=on in postgresql.conf), the same pseudo-random state would be
inherited by each forked child process. The problem is masked to a
considerable extent if the incoming connection uses SSL encryption, but
when it does not, identical pseudo-random state is made available to
functions like contrib/pgcrypto. The process's PID does get mixed into any
requested random output, but on most systems that still only results in 32K
or so distinct random sequences available across all Postgres sessions.
This might allow an attacker who has database access to guess the results
of "secure" operations happening in another session.
To fix, forcibly reset the PRNG after fork(). Each child process that has
need for random numbers from OpenSSL's generator will thereby be forced to
go through OpenSSL's normal initialization sequence, which should provide
much greater variability of the sequences. There are other ways we might
do this that would be slightly cheaper, but this approach seems the most
future-proof against SSL-related code changes.
This has been assigned CVE-2013-1900, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
Back-patch to all supported branches.
Marko Kreen
2013-03-27 23:50:21 +01:00
|
|
|
RAND_cleanup();
|
|
|
|
#endif
|
2005-03-10 08:14:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2005-10-15 04:49:52 +02:00
|
|
|
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
#endif /* ! WIN32 */
|