Skip to content

Commit ef3883d

Browse files
committed
Do stack-depth checking in all postmaster children.
We used to only initialize the stack base pointer when starting up a regular backend, not in other processes. In particular, autovacuum workers can run arbitrary user code, and without stack-depth checking, infinite recursion in e.g an index expression will bring down the whole cluster. The comment about PL/Java using set_stack_base() is not yet true. As the code stands, PL/java still modifies the stack_base_ptr variable directly. However, it's been discussed in the PL/Java mailing list that it should be changed to use the function, because PL/Java is currently oblivious to the register stack used on Itanium. There's another issues with PL/Java, namely that the stack base pointer it sets is not really the base of the stack, it could be something close to the bottom of the stack. That's a separate issue that might need some further changes to this code, but that's a different story. Backpatch to all supported releases.
1 parent 7feeced commit ef3883d

File tree

3 files changed

+76
-8
lines changed

3 files changed

+76
-8
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,11 @@ PostmasterMain(int argc, char *argv[])
970970
*/
971971
set_max_safe_fds();
972972

973+
/*
974+
* Set reference point for stack-depth checking.
975+
*/
976+
set_stack_base();
977+
973978
/*
974979
* Initialize the list of active backends.
975980
*/
@@ -3977,6 +3982,11 @@ SubPostmasterMain(int argc, char *argv[])
39773982
memset(&port, 0, sizeof(Port));
39783983
read_backend_variables(argv[2], &port);
39793984

3985+
/*
3986+
* Set reference point for stack-depth checking
3987+
*/
3988+
set_stack_base();
3989+
39803990
/*
39813991
* Set up memory area for GSS information. Mirrors the code in ConnCreate
39823992
* for the non-exec case.

src/backend/tcop/postgres.c

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,10 @@ int PostAuthDelay = 0;
115115
static long max_stack_depth_bytes = 100 * 1024L;
116116

117117
/*
118-
* Stack base pointer -- initialized by PostgresMain. This is not static
119-
* so that PL/Java can modify it.
118+
* Stack base pointer -- initialized by PostmasterMain and inherited by
119+
* subprocesses. This is not static because old versions of PL/Java modify
120+
* it directly. Newer versions use set_stack_base(), but we want to stay
121+
* binary-compatible for the time being.
120122
*/
121123
char *stack_base_ptr = NULL;
122124

@@ -2957,6 +2959,53 @@ ia64_get_bsp(void)
29572959
#endif /* IA64 */
29582960

29592961

2962+
/*
2963+
* set_stack_base: set up reference point for stack depth checking
2964+
*
2965+
* Returns the old reference point, if any.
2966+
*/
2967+
pg_stack_base_t
2968+
set_stack_base(void)
2969+
{
2970+
char stack_base;
2971+
pg_stack_base_t old;
2972+
2973+
#if defined(__ia64__) || defined(__ia64)
2974+
old.stack_base_ptr = stack_base_ptr;
2975+
old.register_stack_base_ptr = register_stack_base_ptr;
2976+
#else
2977+
old = stack_base_ptr;
2978+
#endif
2979+
2980+
/* Set up reference point for stack depth checking */
2981+
stack_base_ptr = &stack_base;
2982+
#if defined(__ia64__) || defined(__ia64)
2983+
register_stack_base_ptr = ia64_get_bsp();
2984+
#endif
2985+
2986+
return old;
2987+
}
2988+
2989+
/*
2990+
* restore_stack_base: restore reference point for stack depth checking
2991+
*
2992+
* This can be used after set_stack_base() to restore the old value. This
2993+
* is currently only used in PL/Java. When PL/Java calls a backend function
2994+
* from different thread, the thread's stack is at a different location than
2995+
* the main thread's stack, so it sets the base pointer before the call, and
2996+
* restores it afterwards.
2997+
*/
2998+
void
2999+
restore_stack_base(pg_stack_base_t base)
3000+
{
3001+
#if defined(__ia64__) || defined(__ia64)
3002+
stack_base_ptr = base.stack_base_ptr;
3003+
register_stack_base_ptr = base.register_stack_base_ptr;
3004+
#else
3005+
stack_base_ptr = base;
3006+
#endif
3007+
}
3008+
29603009
/*
29613010
* check_stack_depth: check for excessively deep recursion
29623011
*
@@ -2972,7 +3021,7 @@ check_stack_depth(void)
29723021
long stack_depth;
29733022

29743023
/*
2975-
* Compute distance from PostgresMain's local variables to my own
3024+
* Compute distance from reference point to to my local variables
29763025
*/
29773026
stack_depth = (long) (stack_base_ptr - &stack_top_loc);
29783027

@@ -3434,7 +3483,6 @@ PostgresMain(int argc, char *argv[], const char *username)
34343483
{
34353484
const char *dbname;
34363485
int firstchar;
3437-
char stack_base;
34383486
StringInfoData input_message;
34393487
sigjmp_buf local_sigjmp_buf;
34403488
volatile bool send_ready_for_query = true;
@@ -3461,10 +3509,7 @@ PostgresMain(int argc, char *argv[], const char *username)
34613509
SetProcessingMode(InitProcessing);
34623510

34633511
/* Set up reference point for stack depth checking */
3464-
stack_base_ptr = &stack_base;
3465-
#if defined(__ia64__) || defined(__ia64)
3466-
register_stack_base_ptr = ia64_get_bsp();
3467-
#endif
3512+
set_stack_base();
34683513

34693514
/* Compute paths, if we didn't inherit them from postmaster */
34703515
if (my_exec_path[0] == '\0')

src/include/miscadmin.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,19 @@ extern bool VacuumCostActive;
246246

247247

248248
/* in tcop/postgres.c */
249+
250+
#if defined(__ia64__) || defined(__ia64)
251+
typedef struct
252+
{
253+
char *stack_base_ptr;
254+
char *register_stack_base_ptr;
255+
} pg_stack_base_t;
256+
#else
257+
typedef char *pg_stack_base_t;
258+
#endif
259+
260+
extern pg_stack_base_t set_stack_base(void);
261+
extern void restore_stack_base(pg_stack_base_t base);
249262
extern void check_stack_depth(void);
250263

251264
/* in tcop/utility.c */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy