Skip to content

Commit 2bf7754

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 4bff35c commit 2bf7754

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
@@ -4566,10 +4566,17 @@ SubPostmasterMain(int argc, char *argv[])
45664566
/* Setup essential subsystems (to ensure elog() behaves sanely) */
45674567
InitializeGUCOptions();
45684568

4569+
/* Check we got appropriate args */
4570+
if (argc < 3)
4571+
elog(FATAL, "invalid subpostmaster invocation");
4572+
45694573
/* Read in the variables file */
45704574
memset(&port, 0, sizeof(Port));
45714575
read_backend_variables(argv[2], &port);
45724576

4577+
/* Close the postmaster's sockets (as soon as we know them) */
4578+
ClosePostmasterPorts(strcmp(argv[1], "--forklog") == 0);
4579+
45734580
/*
45744581
* Set reference point for stack-depth checking
45754582
*/
@@ -4587,15 +4594,21 @@ SubPostmasterMain(int argc, char *argv[])
45874594
errmsg("out of memory")));
45884595
#endif
45894596

4590-
/* Check we got appropriate args */
4591-
if (argc < 3)
4592-
elog(FATAL, "invalid subpostmaster invocation");
4593-
45944597
/*
45954598
* If appropriate, physically re-attach to shared memory segment. We want
45964599
* to do this before going any further to ensure that we can attach at the
45974600
* same address the postmaster used. On the other hand, if we choose not
45984601
* to re-attach, we may have other cleanup to do.
4602+
*
4603+
* If testing EXEC_BACKEND on Linux, you should run this as root before
4604+
* starting the postmaster:
4605+
*
4606+
* echo 0 >/proc/sys/kernel/randomize_va_space
4607+
*
4608+
* This prevents using randomized stack and code addresses that cause the
4609+
* child process's memory map to be different from the parent's, making it
4610+
* sometimes impossible to attach to shared memory at the desired address.
4611+
* Return the setting to its old value (usually '1' or '2') when finished.
45994612
*/
46004613
if (strcmp(argv[1], "--forkbackend") == 0 ||
46014614
strcmp(argv[1], "--forkavlauncher") == 0 ||
@@ -4641,9 +4654,6 @@ SubPostmasterMain(int argc, char *argv[])
46414654
{
46424655
Assert(argc == 3); /* shouldn't be any more args */
46434656

4644-
/* Close the postmaster's sockets */
4645-
ClosePostmasterPorts(false);
4646-
46474657
/*
46484658
* Need to reinitialize the SSL library in the backend, since the
46494659
* context structures contain function pointers and cannot be passed
@@ -4674,27 +4684,14 @@ SubPostmasterMain(int argc, char *argv[])
46744684
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
46754685
InitProcess();
46764686

4677-
/*
4678-
* Attach process to shared data structures. If testing EXEC_BACKEND
4679-
* on Linux, you must run this as root before starting the postmaster:
4680-
*
4681-
* echo 0 >/proc/sys/kernel/randomize_va_space
4682-
*
4683-
* This prevents a randomized stack base address that causes child
4684-
* shared memory to be at a different address than the parent, making
4685-
* it impossible to attached to shared memory. Return the value to
4686-
* '1' when finished.
4687-
*/
4687+
/* Attach process to shared data structures */
46884688
CreateSharedMemoryAndSemaphores(false, 0);
46894689

46904690
/* And run the backend */
46914691
BackendRun(&port); /* does not return */
46924692
}
46934693
if (strcmp(argv[1], "--forkboot") == 0)
46944694
{
4695-
/* Close the postmaster's sockets */
4696-
ClosePostmasterPorts(false);
4697-
46984695
/* Restore basic shared memory pointers */
46994696
InitShmemAccess(UsedShmemSegAddr);
47004697

@@ -4708,9 +4705,6 @@ SubPostmasterMain(int argc, char *argv[])
47084705
}
47094706
if (strcmp(argv[1], "--forkavlauncher") == 0)
47104707
{
4711-
/* Close the postmaster's sockets */
4712-
ClosePostmasterPorts(false);
4713-
47144708
/* Restore basic shared memory pointers */
47154709
InitShmemAccess(UsedShmemSegAddr);
47164710

@@ -4724,9 +4718,6 @@ SubPostmasterMain(int argc, char *argv[])
47244718
}
47254719
if (strcmp(argv[1], "--forkavworker") == 0)
47264720
{
4727-
/* Close the postmaster's sockets */
4728-
ClosePostmasterPorts(false);
4729-
47304721
/* Restore basic shared memory pointers */
47314722
InitShmemAccess(UsedShmemSegAddr);
47324723

@@ -4745,9 +4736,6 @@ SubPostmasterMain(int argc, char *argv[])
47454736
/* do this as early as possible; in particular, before InitProcess() */
47464737
IsBackgroundWorker = true;
47474738

4748-
/* Close the postmaster's sockets */
4749-
ClosePostmasterPorts(false);
4750-
47514739
/* Restore basic shared memory pointers */
47524740
InitShmemAccess(UsedShmemSegAddr);
47534741

@@ -4763,27 +4751,18 @@ SubPostmasterMain(int argc, char *argv[])
47634751
}
47644752
if (strcmp(argv[1], "--forkarch") == 0)
47654753
{
4766-
/* Close the postmaster's sockets */
4767-
ClosePostmasterPorts(false);
4768-
47694754
/* Do not want to attach to shared memory */
47704755

47714756
PgArchiverMain(argc, argv); /* does not return */
47724757
}
47734758
if (strcmp(argv[1], "--forkcol") == 0)
47744759
{
4775-
/* Close the postmaster's sockets */
4776-
ClosePostmasterPorts(false);
4777-
47784760
/* Do not want to attach to shared memory */
47794761

47804762
PgstatCollectorMain(argc, argv); /* does not return */
47814763
}
47824764
if (strcmp(argv[1], "--forklog") == 0)
47834765
{
4784-
/* Close the postmaster's sockets */
4785-
ClosePostmasterPorts(true);
4786-
47874766
/* Do not want to attach to shared memory */
47884767

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

0 commit comments

Comments
 (0)