From d8fea6973cec7aad20e9fbb2afe9a19d579bb04b Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.b.smith@fujitsu.com>
Date: Tue, 25 Oct 2022 16:57:32 +1100
Subject: [PATCH v4] GUC C variable sanity check

Added a function to perform a sanity-check comparison of the C variable initial
value with the compiled-in default (boot_val). The purpose of this is to prevent
anybody reading those C declarations from being fooled by mismatched values.

Also fixed some existing mismatching values.

Checking is skipped for GUCs flagged as compiler-dependent (GUC_DEFAULT_COMPILE).
---
 src/backend/access/transam/xact.c   |  2 +-
 src/backend/access/transam/xlog.c   |  2 +-
 src/backend/libpq/be-secure.c       |  4 +-
 src/backend/utils/adt/xml.c         |  4 +-
 src/backend/utils/cache/plancache.c |  2 +-
 src/backend/utils/error/elog.c      |  2 +-
 src/backend/utils/init/globals.c    |  4 +-
 src/backend/utils/misc/guc.c        | 78 +++++++++++++++++++++++++++++++++++++
 src/backend/utils/misc/guc_tables.c |  2 +-
 9 files changed, 89 insertions(+), 11 deletions(-)

diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index fd5103a..f45c95f 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -75,7 +75,7 @@
  *	User-tweakable parameters
  */
 int			DefaultXactIsoLevel = XACT_READ_COMMITTED;
-int			XactIsoLevel;
+int			XactIsoLevel = XACT_READ_COMMITTED;
 
 bool		DefaultXactReadOnly = false;
 bool		XactReadOnly;
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 8f10eff..be54c23 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -131,7 +131,7 @@ bool		wal_init_zero = true;
 bool		wal_recycle = true;
 bool		log_checkpoints = true;
 int			sync_method = DEFAULT_SYNC_METHOD;
-int			wal_level = WAL_LEVEL_MINIMAL;
+int			wal_level = WAL_LEVEL_REPLICA;
 int			CommitDelay = 0;	/* precommit delay in microseconds */
 int			CommitSiblings = 5; /* # concurrent xacts needed to sleep */
 int			wal_retrieve_retry_interval = 5000;
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index e3e5471..c896357 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -58,8 +58,8 @@ char	   *SSLECDHCurve;
 /* GUC variable: if false, prefer client ciphers */
 bool		SSLPreferServerCiphers;
 
-int			ssl_min_protocol_version;
-int			ssl_max_protocol_version;
+int			ssl_min_protocol_version = PG_TLS1_2_VERSION;
+int			ssl_max_protocol_version = PG_TLS_ANY;
 
 /* ------------------------------------------------------------ */
 /*			 Procedures common to all secure sessions			*/
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index d32cb11..8cd5262 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -94,8 +94,8 @@
 
 
 /* GUC variables */
-int			xmlbinary;
-int			xmloption;
+int			xmlbinary = XMLBINARY_BASE64;
+int			xmloption = XMLOPTION_CONTENT;
 
 #ifdef USE_LIBXML
 
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index 0d6a295..cc94320 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -116,7 +116,7 @@ static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue);
 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
 
 /* GUC parameter */
-int			plan_cache_mode;
+int			plan_cache_mode = PLAN_CACHE_MODE_AUTO;
 
 /*
  * InitPlanCache: initialize module during InitPostgres.
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 6e0a66c..2585e24 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -107,7 +107,7 @@ extern bool redirection_done;
 emit_log_hook_type emit_log_hook = NULL;
 
 /* GUC parameters */
-int			Log_error_verbosity = PGERROR_VERBOSE;
+int			Log_error_verbosity = PGERROR_DEFAULT;
 char	   *Log_line_prefix = NULL; /* format for extra log line info */
 int			Log_destination = LOG_DESTINATION_STDERR;
 char	   *Log_destination_string = NULL;
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 1a5d29a..00bceec 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -133,8 +133,8 @@ int			max_parallel_maintenance_workers = 2;
  * MaxBackends is computed by PostmasterMain after modules have had a chance to
  * register background workers.
  */
-int			NBuffers = 1000;
-int			MaxConnections = 90;
+int			NBuffers = 16384;
+int			MaxConnections = 100;
 int			max_worker_processes = 8;
 int			max_parallel_workers = 8;
 int			MaxBackends = 0;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 6f21752..9e19a3e 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -1382,6 +1382,80 @@ check_GUC_name_for_parameter_acl(const char *name)
 	return false;
 }
 
+#ifdef USE_ASSERT_CHECKING
+/*
+ * A GUC C variable can be declared with an initial value, but the GUC mechanism
+ * will overwrite that using the compiled-in default (boot_val) as per
+ * guc_tables.c.
+ *
+ * This function performs a sanity-check comparison of the C variable initial
+ * value with the boot_val, to prevent anybody reading those C declarations
+ * from being fooled by mismatched values.
+ *
+ * GUC C variable validation rules:
+ * bool - can be false, otherwise must be same as the boot_val
+ * int  - can be 0, otherwise must be same as the boot_val
+ * real - can be 0.0, otherwise must be same as the boot_val
+ * string - can be NULL, otherwise must be strcmp equal to the boot_val
+ * enum - must be same as the boot_val
+ */
+static void
+sanity_check_GUC_C_var(struct config_generic *gconf)
+{
+	/* Skip checking for dynamic (compiler-dependent) GUCs. */
+	if (gconf->flags & GUC_DEFAULT_COMPILE)
+		return;
+
+	switch (gconf->vartype)
+	{
+		case PGC_BOOL:
+			{
+				struct config_bool *conf = (struct config_bool *) gconf;
+
+				if (*conf->variable && !conf->boot_val)
+					elog(FATAL, "GUC (PGC_BOOL) %s, boot_val=%d, C-var=%d",
+						 conf->gen.name, conf->boot_val, *conf->variable);
+				break;
+			}
+		case PGC_INT:
+			{
+				struct config_int *conf = (struct config_int *) gconf;
+
+				if (*conf->variable != 0 && *conf->variable != conf->boot_val)
+					elog(FATAL, "GUC (PGC_INT) %s, boot_val=%d, C-var=%d",
+						 conf->gen.name, conf->boot_val, *conf->variable);
+				break;
+			}
+		case PGC_REAL:
+			{
+				struct config_real *conf = (struct config_real *) gconf;
+
+				if (*conf->variable != 0.0 && *conf->variable != conf->boot_val)
+					elog(FATAL, "GUC (PGC_REAL) %s, boot_val=%g, C-var=%g",
+						 conf->gen.name, conf->boot_val, *conf->variable);
+				break;
+			}
+		case PGC_STRING:
+			{
+				struct config_string *conf = (struct config_string *) gconf;
+
+				if (*conf->variable != NULL && strcmp(*conf->variable, conf->boot_val) != 0)
+					elog(FATAL, "GUC (PGC_STRING) %s, boot_val=%s, C-var=%s",
+						 conf->gen.name, conf->boot_val ? conf->boot_val : "<null>", *conf->variable);
+				break;
+			}
+		case PGC_ENUM:
+			{
+				struct config_enum *conf = (struct config_enum *) gconf;
+
+				if (*conf->variable != conf->boot_val)
+					elog(FATAL, "GUC (PGC_ENUM) %s, boot_val=%d, C-var=%d",
+						 conf->gen.name, conf->boot_val, *conf->variable);
+				break;
+			}
+	}
+}
+#endif
 
 /*
  * Initialize GUC options during program startup.
@@ -1413,6 +1487,10 @@ InitializeGUCOptions(void)
 	hash_seq_init(&status, guc_hashtab);
 	while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
 	{
+#ifdef USE_ASSERT_CHECKING
+		sanity_check_GUC_C_var(hentry->gucvar);
+#endif
+
 		InitializeOneGUCOption(hentry->gucvar);
 	}
 
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 871be3e..0ff2b67 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -526,7 +526,7 @@ int			ssl_renegotiation_limit;
  * This really belongs in pg_shmem.c, but is defined here so that it doesn't
  * need to be duplicated in all the different implementations of pg_shmem.c.
  */
-int			huge_pages;
+int			huge_pages = HUGE_PAGES_TRY;
 int			huge_page_size;
 
 /*
-- 
1.8.3.1

