Treat EPERM as a non-error case when checking to see if old postmaster
is still alive. This improves our odds of not getting fooled by an unrelated process when checking a stale lock file. Other checks already in place, plus one newly added in checkDataDir(), ensure that we cannot attempt to usurp the place of a postmaster belonging to a different userid, so there is no need to error out. Add comments indicating the importance of these other checks.
This commit is contained in:
parent
d344505d1b
commit
7a969cad2e
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.446 2005/03/10 07:14:03 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.447 2005/03/18 03:48:49 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -952,9 +952,32 @@ checkDataDir(void)
|
|||||||
DataDir)));
|
DataDir)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the directory belongs to my userid; if not, reject.
|
||||||
|
*
|
||||||
|
* This check is an essential part of the interlock that prevents two
|
||||||
|
* postmasters from starting in the same directory (see CreateLockFile()).
|
||||||
|
* Do not remove or weaken it.
|
||||||
|
*
|
||||||
|
* XXX can we safely enable this check on Windows?
|
||||||
|
*/
|
||||||
|
#if !defined(WIN32) && !defined(__CYGWIN__)
|
||||||
|
if (stat_buf.st_uid != geteuid())
|
||||||
|
ereport(FATAL,
|
||||||
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||||
|
errmsg("data directory \"%s\" has wrong ownership",
|
||||||
|
DataDir),
|
||||||
|
errhint("The server must be started by the user that owns the data directory.")));
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the directory has group or world access. If so, reject.
|
* Check if the directory has group or world access. If so, reject.
|
||||||
*
|
*
|
||||||
|
* It would be possible to allow weaker constraints (for example, allow
|
||||||
|
* group access) but we cannot make a general assumption that that is
|
||||||
|
* okay; for example there are platforms where nearly all users customarily
|
||||||
|
* belong to the same group. Perhaps this test should be configurable.
|
||||||
|
*
|
||||||
* XXX temporarily suppress check when on Windows, because there may not
|
* XXX temporarily suppress check when on Windows, because there may not
|
||||||
* be proper support for Unix-y file permissions. Need to think of a
|
* be proper support for Unix-y file permissions. Need to think of a
|
||||||
* reasonable check to apply on Windows.
|
* reasonable check to apply on Windows.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.137 2004/12/31 22:01:40 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.138 2005/03/18 03:48:49 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -505,6 +505,9 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Try to create the lock file --- O_EXCL makes this atomic.
|
* Try to create the lock file --- O_EXCL makes this atomic.
|
||||||
|
*
|
||||||
|
* Think not to make the file protection weaker than 0600. See
|
||||||
|
* comments below.
|
||||||
*/
|
*/
|
||||||
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
|
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
@ -564,6 +567,21 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
|||||||
* then all but the immediate parent shell will be root-owned processes
|
* then all but the immediate parent shell will be root-owned processes
|
||||||
* and so the kill test will fail with EPERM.
|
* and so the kill test will fail with EPERM.
|
||||||
*
|
*
|
||||||
|
* We can treat the EPERM-error case as okay because that error implies
|
||||||
|
* that the existing process has a different userid than we do, which
|
||||||
|
* means it cannot be a competing postmaster. A postmaster cannot
|
||||||
|
* successfully attach to a data directory owned by a userid other
|
||||||
|
* than its own. (This is now checked directly in checkDataDir(),
|
||||||
|
* but has been true for a long time because of the restriction that
|
||||||
|
* the data directory isn't group- or world-accessible.) Also,
|
||||||
|
* since we create the lockfiles mode 600, we'd have failed above
|
||||||
|
* if the lockfile belonged to another userid --- which means that
|
||||||
|
* whatever process kill() is reporting about isn't the one that
|
||||||
|
* made the lockfile. (NOTE: this last consideration is the only
|
||||||
|
* one that keeps us from blowing away a Unix socket file belonging
|
||||||
|
* to an instance of Postgres being run by someone else, at least
|
||||||
|
* on machines where /tmp hasn't got a stickybit.)
|
||||||
|
*
|
||||||
* Windows hasn't got getppid(), but doesn't need it since it's not
|
* Windows hasn't got getppid(), but doesn't need it since it's not
|
||||||
* using real kill() either...
|
* using real kill() either...
|
||||||
*
|
*
|
||||||
@ -577,11 +595,11 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (kill(other_pid, 0) == 0 ||
|
if (kill(other_pid, 0) == 0 ||
|
||||||
(errno != ESRCH
|
(errno != ESRCH &&
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
&& errno != EINVAL
|
errno != EINVAL &&
|
||||||
#endif
|
#endif
|
||||||
))
|
errno != EPERM))
|
||||||
{
|
{
|
||||||
/* lockfile belongs to a live process */
|
/* lockfile belongs to a live process */
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user