Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4677fe9

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 f4e787c commit 4677fe9

File tree

1 file changed

+18
-39
lines changed

1 file changed

+18
-39
lines changed

src/backend/postmaster/postmaster.c

+18-39
Original file line numberDiff line numberDiff line change
@@ -4635,10 +4635,17 @@ SubPostmasterMain(int argc, char *argv[])
46354635
/* Setup essential subsystems (to ensure elog() behaves sanely) */
46364636
InitializeGUCOptions();
46374637

4638+
/* Check we got appropriate args */
4639+
if (argc < 3)
4640+
elog(FATAL, "invalid subpostmaster invocation");
4641+
46384642
/* Read in the variables file */
46394643
memset(&port, 0, sizeof(Port));
46404644
read_backend_variables(argv[2], &port);
46414645

4646+
/* Close the postmaster's sockets (as soon as we know them) */
4647+
ClosePostmasterPorts(strcmp(argv[1], "--forklog") == 0);
4648+
46424649
/*
46434650
* Set reference point for stack-depth checking
46444651
*/
@@ -4656,15 +4663,21 @@ SubPostmasterMain(int argc, char *argv[])
46564663
errmsg("out of memory")));
46574664
#endif
46584665

4659-
/* Check we got appropriate args */
4660-
if (argc < 3)
4661-
elog(FATAL, "invalid subpostmaster invocation");
4662-
46634666
/*
46644667
* If appropriate, physically re-attach to shared memory segment. We want
46654668
* to do this before going any further to ensure that we can attach at the
46664669
* same address the postmaster used. On the other hand, if we choose not
46674670
* to re-attach, we may have other cleanup to do.
4671+
*
4672+
* If testing EXEC_BACKEND on Linux, you should run this as root before
4673+
* starting the postmaster:
4674+
*
4675+
* echo 0 >/proc/sys/kernel/randomize_va_space
4676+
*
4677+
* This prevents using randomized stack and code addresses that cause the
4678+
* child process's memory map to be different from the parent's, making it
4679+
* sometimes impossible to attach to shared memory at the desired address.
4680+
* Return the setting to its old value (usually '1' or '2') when finished.
46684681
*/
46694682
if (strcmp(argv[1], "--forkbackend") == 0 ||
46704683
strcmp(argv[1], "--forkavlauncher") == 0 ||
@@ -4710,9 +4723,6 @@ SubPostmasterMain(int argc, char *argv[])
47104723
{
47114724
Assert(argc == 3); /* shouldn't be any more args */
47124725

4713-
/* Close the postmaster's sockets */
4714-
ClosePostmasterPorts(false);
4715-
47164726
/*
47174727
* Need to reinitialize the SSL library in the backend, since the
47184728
* context structures contain function pointers and cannot be passed
@@ -4743,27 +4753,14 @@ SubPostmasterMain(int argc, char *argv[])
47434753
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
47444754
InitProcess();
47454755

4746-
/*
4747-
* Attach process to shared data structures. If testing EXEC_BACKEND
4748-
* on Linux, you must run this as root before starting the postmaster:
4749-
*
4750-
* echo 0 >/proc/sys/kernel/randomize_va_space
4751-
*
4752-
* This prevents a randomized stack base address that causes child
4753-
* shared memory to be at a different address than the parent, making
4754-
* it impossible to attached to shared memory. Return the value to
4755-
* '1' when finished.
4756-
*/
4756+
/* Attach process to shared data structures */
47574757
CreateSharedMemoryAndSemaphores(false, 0);
47584758

47594759
/* And run the backend */
47604760
BackendRun(&port); /* does not return */
47614761
}
47624762
if (strcmp(argv[1], "--forkboot") == 0)
47634763
{
4764-
/* Close the postmaster's sockets */
4765-
ClosePostmasterPorts(false);
4766-
47674764
/* Restore basic shared memory pointers */
47684765
InitShmemAccess(UsedShmemSegAddr);
47694766

@@ -4777,9 +4774,6 @@ SubPostmasterMain(int argc, char *argv[])
47774774
}
47784775
if (strcmp(argv[1], "--forkavlauncher") == 0)
47794776
{
4780-
/* Close the postmaster's sockets */
4781-
ClosePostmasterPorts(false);
4782-
47834777
/* Restore basic shared memory pointers */
47844778
InitShmemAccess(UsedShmemSegAddr);
47854779

@@ -4793,9 +4787,6 @@ SubPostmasterMain(int argc, char *argv[])
47934787
}
47944788
if (strcmp(argv[1], "--forkavworker") == 0)
47954789
{
4796-
/* Close the postmaster's sockets */
4797-
ClosePostmasterPorts(false);
4798-
47994790
/* Restore basic shared memory pointers */
48004791
InitShmemAccess(UsedShmemSegAddr);
48014792

@@ -4814,9 +4805,6 @@ SubPostmasterMain(int argc, char *argv[])
48144805
/* do this as early as possible; in particular, before InitProcess() */
48154806
IsBackgroundWorker = true;
48164807

4817-
/* Close the postmaster's sockets */
4818-
ClosePostmasterPorts(false);
4819-
48204808
/* Restore basic shared memory pointers */
48214809
InitShmemAccess(UsedShmemSegAddr);
48224810

@@ -4834,27 +4822,18 @@ SubPostmasterMain(int argc, char *argv[])
48344822
}
48354823
if (strcmp(argv[1], "--forkarch") == 0)
48364824
{
4837-
/* Close the postmaster's sockets */
4838-
ClosePostmasterPorts(false);
4839-
48404825
/* Do not want to attach to shared memory */
48414826

48424827
PgArchiverMain(argc, argv); /* does not return */
48434828
}
48444829
if (strcmp(argv[1], "--forkcol") == 0)
48454830
{
4846-
/* Close the postmaster's sockets */
4847-
ClosePostmasterPorts(false);
4848-
48494831
/* Do not want to attach to shared memory */
48504832

48514833
PgstatCollectorMain(argc, argv); /* does not return */
48524834
}
48534835
if (strcmp(argv[1], "--forklog") == 0)
48544836
{
4855-
/* Close the postmaster's sockets */
4856-
ClosePostmasterPorts(true);
4857-
48584837
/* Do not want to attach to shared memory */
48594838

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

0 commit comments

Comments
 (0)