From a05d579957338ca30c01f780c19bed743c94dcb2 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
Date: Thu, 6 Sep 2018 09:05:57 +1200
Subject: [PATCH] Set collversion for collations that come from glibc.

On systems using glibc (most GNU/Linux distributions), we can defend
against index corruption by using the glibc version string to detect
potential changes in collation definitions.

Author: Thomas Munro
Reviewed-by:
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 configure                         |  2 +-
 configure.in                      |  2 +-
 src/backend/utils/adt/pg_locale.c | 13 +++++++++++++
 src/include/pg_config.h.in        |  3 +++
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index dd94c5bbab..faa0a067ef 100755
--- a/configure
+++ b/configure
@@ -12671,7 +12671,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h crypt.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h crypt.h fp_class.h getopt.h gnu/libc-version.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.in b/configure.in
index 3280afa0da..03cbb78bfa 100644
--- a/configure.in
+++ b/configure.in
@@ -1265,7 +1265,7 @@ AC_SUBST(UUID_LIBS)
 
 AC_HEADER_STDBOOL
 
-AC_CHECK_HEADERS([atomic.h crypt.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h crypt.h fp_class.h getopt.h gnu/libc-version.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index a3dc3be5a8..332655877e 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -68,6 +68,10 @@
 #include <unicode/ucnv.h>
 #endif
 
+#ifdef HAVE_GNU_LIBC_VERSION_H
+#include <gnu/libc-version.h>
+#endif
+
 #ifdef WIN32
 /*
  * This Windows file defines StrNCpy. We don't need it here, so we undefine
@@ -1475,6 +1479,15 @@ get_collation_actual_version(char collprovider, const char *collcollate)
 	}
 	else
 #endif
+	if (collprovider == COLLPROVIDER_LIBC)
+	{
+#ifdef HAVE_GNU_LIBC_VERSION_H
+		collversion = gnu_get_libc_version();
+#else
+		collversion = NULL;
+#endif
+	}
+	else
 		collversion = NULL;
 
 	return collversion;
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 347d5b56dc..55025090b6 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -282,6 +282,9 @@
 /* Define to 1 if you have the `gettimeofday' function. */
 #undef HAVE_GETTIMEOFDAY
 
+/* Define to 1 if you have the <gnu/libc-version.h> header file. */
+#undef HAVE_GNU_LIBC_VERSION_H
+
 /* Define to 1 if you have the <gssapi/gssapi.h> header file. */
 #undef HAVE_GSSAPI_GSSAPI_H
 
-- 
2.17.0

