Skip to content

Commit e12b83a

Browse files
committed
Do ClosePostmasterPorts() earlier in SubPostmasterMain().
In standard Unix builds, postmaster child processes do ClosePostmasterPorts immediately after InitPostmasterChild, that is almost immediately after being spawned. This is important because we don't want children holding open the postmaster's end of the postmaster death watch pipe. However, in EXEC_BACKEND builds, SubPostmasterMain was postponing this responsibility significantly, in order to make it slightly more convenient to pass the right flag value to ClosePostmasterPorts. This is bad, particularly seeing that process_shared_preload_libraries() might invoke nearly-arbitrary code. Rearrange so that we do it as soon as we've fetched the socket FDs via read_backend_variables(). Also move the comment explaining about randomize_va_space to before the call of PGSharedMemoryReAttach, which is where it's relevant. The old placement was appropriate when the reattach happened inside CreateSharedMemoryAndSemaphores, but that was a long time ago. Back-patch to 9.3; the patch doesn't apply cleanly before that, and it doesn't seem worth a lot of effort given that we've had no actual field complaints traceable to this. Discussion: <4157.1475178360@sss.pgh.pa.us>
1 parent d8b4c34 commit e12b83a

File tree

1 file changed

+18
-39
lines changed

1 file changed

+18
-39
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4618,10 +4618,17 @@ SubPostmasterMain(int argc, char *argv[])
46184618
/* Setup essential subsystems (to ensure elog() behaves sanely) */
46194619
InitializeGUCOptions();
46204620

4621+
/* Check we got appropriate args */
4622+
if (argc < 3)
4623+
elog(FATAL, "invalid subpostmaster invocation");
4624+
46214625
/* Read in the variables file */
46224626
memset(&port, 0, sizeof(Port));
46234627
read_backend_variables(argv[2], &port);
46244628

4629+
/* Close the postmaster's sockets (as soon as we know them) */
4630+
ClosePostmasterPorts(strcmp(argv[1], "--forklog") == 0);
4631+
46254632
/*
46264633
* Set reference point for stack-depth checking
46274634
*/
@@ -4639,15 +4646,21 @@ SubPostmasterMain(int argc, char *argv[])
46394646
errmsg("out of memory")));
46404647
#endif
46414648

4642-
/* Check we got appropriate args */
4643-
if (argc < 3)
4644-
elog(FATAL, "invalid subpostmaster invocation");
4645-
46464649
/*
46474650
* If appropriate, physically re-attach to shared memory segment. We want
46484651
* to do this before going any further to ensure that we can attach at the
46494652
* same address the postmaster used. On the other hand, if we choose not
46504653
* to re-attach, we may have other cleanup to do.
4654+
*
4655+
* If testing EXEC_BACKEND on Linux, you should run this as root before
4656+
* starting the postmaster:
4657+
*
4658+
* echo 0 >/proc/sys/kernel/randomize_va_space
4659+
*
4660+
* This prevents using randomized stack and code addresses that cause the
4661+
* child process's memory map to be different from the parent's, making it
4662+
* sometimes impossible to attach to shared memory at the desired address.
4663+
* Return the setting to its old value (usually '1' or '2') when finished.
46514664
*/
46524665
if (strcmp(argv[1], "--forkbackend") == 0 ||
46534666
strcmp(argv[1], "--forkavlauncher") == 0 ||
@@ -4693,9 +4706,6 @@ SubPostmasterMain(int argc, char *argv[])
46934706
{
46944707
Assert(argc == 3); /* shouldn't be any more args */
46954708

4696-
/* Close the postmaster's sockets */
4697-
ClosePostmasterPorts(false);
4698-
46994709
/*
47004710
* Need to reinitialize the SSL library in the backend, since the
47014711
* context structures contain function pointers and cannot be passed
@@ -4726,27 +4736,14 @@ SubPostmasterMain(int argc, char *argv[])
47264736
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
47274737
InitProcess();
47284738

4729-
/*
4730-
* Attach process to shared data structures. If testing EXEC_BACKEND
4731-
* on Linux, you must run this as root before starting the postmaster:
4732-
*
4733-
* echo 0 >/proc/sys/kernel/randomize_va_space
4734-
*
4735-
* This prevents a randomized stack base address that causes child
4736-
* shared memory to be at a different address than the parent, making
4737-
* it impossible to attached to shared memory. Return the value to
4738-
* '1' when finished.
4739-
*/
4739+
/* Attach process to shared data structures */
47404740
CreateSharedMemoryAndSemaphores(false, 0);
47414741

47424742
/* And run the backend */
47434743
BackendRun(&port); /* does not return */
47444744
}
47454745
if (strcmp(argv[1], "--forkboot") == 0)
47464746
{
4747-
/* Close the postmaster's sockets */
4748-
ClosePostmasterPorts(false);
4749-
47504747
/* Restore basic shared memory pointers */
47514748
InitShmemAccess(UsedShmemSegAddr);
47524749

@@ -4760,9 +4757,6 @@ SubPostmasterMain(int argc, char *argv[])
47604757
}
47614758
if (strcmp(argv[1], "--forkavlauncher") == 0)
47624759
{
4763-
/* Close the postmaster's sockets */
4764-
ClosePostmasterPorts(false);
4765-
47664760
/* Restore basic shared memory pointers */
47674761
InitShmemAccess(UsedShmemSegAddr);
47684762

@@ -4776,9 +4770,6 @@ SubPostmasterMain(int argc, char *argv[])
47764770
}
47774771
if (strcmp(argv[1], "--forkavworker") == 0)
47784772
{
4779-
/* Close the postmaster's sockets */
4780-
ClosePostmasterPorts(false);
4781-
47824773
/* Restore basic shared memory pointers */
47834774
InitShmemAccess(UsedShmemSegAddr);
47844775

@@ -4797,9 +4788,6 @@ SubPostmasterMain(int argc, char *argv[])
47974788
/* do this as early as possible; in particular, before InitProcess() */
47984789
IsBackgroundWorker = true;
47994790

4800-
/* Close the postmaster's sockets */
4801-
ClosePostmasterPorts(false);
4802-
48034791
/* Restore basic shared memory pointers */
48044792
InitShmemAccess(UsedShmemSegAddr);
48054793

@@ -4817,27 +4805,18 @@ SubPostmasterMain(int argc, char *argv[])
48174805
}
48184806
if (strcmp(argv[1], "--forkarch") == 0)
48194807
{
4820-
/* Close the postmaster's sockets */
4821-
ClosePostmasterPorts(false);
4822-
48234808
/* Do not want to attach to shared memory */
48244809

48254810
PgArchiverMain(argc, argv); /* does not return */
48264811
}
48274812
if (strcmp(argv[1], "--forkcol") == 0)
48284813
{
4829-
/* Close the postmaster's sockets */
4830-
ClosePostmasterPorts(false);
4831-
48324814
/* Do not want to attach to shared memory */
48334815

48344816
PgstatCollectorMain(argc, argv); /* does not return */
48354817
}
48364818
if (strcmp(argv[1], "--forklog") == 0)
48374819
{
4838-
/* Close the postmaster's sockets */
4839-
ClosePostmasterPorts(true);
4840-
48414820
/* Do not want to attach to shared memory */
48424821

48434822
SysLoggerMain(argc, argv); /* does not return */

0 commit comments

Comments
 (0)