git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: fb9042f)
Add support for detecting register-stack overrun on IA64.
Sun, 7 Nov 2010 02:59:09 +0000 (22:59 -0400)
Sun, 7 Nov 2010 02:59:09 +0000 (22:59 -0400)
Per recent investigation, the register stack can grow faster than the
regular stack depending on compiler and choice of options. To avoid
crashes we must check both stacks in check_stack_depth().

Back-patch to all supported versions.


diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index f94c5152204b12bd90e4f3769a67f1d9d5fbdcf3..62adaca2174807830e1a44388623a352c3647363 100644 (file)
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -118,6 +118,12 @@ static long max_stack_depth_bytes = 100 * 1024L;
*/
char *stack_base_ptr = NULL;
+/*
+ * On IA64 we also have to remember the register stack base.
+ */
+#if defined(__ia64__) || defined(__ia64)
+char *register_stack_base_ptr = NULL;
+#endif
/*
* Flag to mark SIGHUP. Whenever the main loop comes around it
@@ -2982,6 +2988,35 @@ ProcessInterrupts(void)
}
+/*
+ * IA64-specific code to fetch the AR.BSP register for stack depth checks.
+ *
+ * We currently support gcc and icc here.
+ */
+#if defined(__ia64__) || defined(__ia64)
+
+#include <asm/ia64regs.h>
+
+static __inline__ char *
+ia64_get_bsp(void)
+{
+ char *ret;
+
+#ifndef __INTEL_COMPILER
+ /* the ;; is a "stop", seems to be required before fetching BSP */
+ __asm__ __volatile__(
+ ";;\n"
+ " mov %0=ar.bsp \n"
+: "=r"(ret));
+#else
+ ret = (char *) __getReg(_IA64_REG_AR_BSP);
+#endif
+ return ret;
+}
+
+#endif /* IA64 */
+
+
/*
* check_stack_depth: check for excessively deep recursion
*
@@ -3024,6 +3059,28 @@ check_stack_depth(void)
errhint("Increase the configuration parameter \"max_stack_depth\", "
"after ensuring the platform's stack depth limit is adequate.")));
}
+
+ /*
+ * On IA64 there is a separate "register" stack that requires its own
+ * independent check. For this, we have to measure the change in the
+ * "BSP" pointer from PostgresMain to here. Logic is just as above,
+ * except that we know IA64's register stack grows up.
+ *
+ * Note we assume that the same max_stack_depth applies to both stacks.
+ */
+#if defined(__ia64__) || defined(__ia64)
+ stack_depth = (long) (ia64_get_bsp() - register_stack_base_ptr);
+
+ if (stack_depth > max_stack_depth_bytes &&
+ register_stack_base_ptr != NULL)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
+ errmsg("stack depth limit exceeded"),
+ errhint("Increase the configuration parameter \"max_stack_depth\", "
+ "after ensuring the platform's stack depth limit is adequate.")));
+ }
+#endif /* IA64 */
}
/* GUC assign hook for max_stack_depth */
@@ -3433,6 +3490,9 @@ PostgresMain(int argc, char *argv[], const char *username)
/* Set up reference point for stack depth checking */
stack_base_ptr = &stack_base;
+#if defined(__ia64__) || defined(__ia64)
+ register_stack_base_ptr = ia64_get_bsp();
+#endif
/* Compute paths, if we didn't inherit them from postmaster */
if (my_exec_path[0] == '0円')
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /