Hi,
I was doing some research about adding native SHA3 support to PostgreSQL
(to be discussed another day) and encountered a compilation failure with
LibreSSL 3.7.2 on macOS/arm64. The compilation failure is caused by
explicit_bzero symbo that exported by the library, but not declared by
the public headers. The existing configure check only determines whether
the symbol can be linked. Because libcrypto is already present in LIBS,
that check succeeds and HAVE_EXPLICIT_BZERO is defined.
PostgreSQL then assumes that the function is also declared and
suppresses the declaration of its fallback implementation in port.h.
Code using explicit_bzero, such as cryptohash_openssl.c, consequently
fails to compile because no prototype is visible.
The attached patch checks separately whether explicit_bzero is declared
by <string.h>. If it is not declared, PostgreSQL uses its own
src/port/explicit_bzero.c implementation, regardless of whether a linked
library happens to export an undeclared symbol. If it is declared, the
existing function-availability check is retained. Equivalent logic is
included for both Autoconf and Meson builds.
This avoids depending on what is effectively an incidental, non-public
LibreSSL export while preserving the existing behavior on platforms
where explicit_bzero is part of the public system interface.
This patch is intended for application to master and is attached as
pg-explicit-bzero-declaration.patch.
I tested it with LibreSSL 3.7.2 using both Autoconf and Meson. The full
builds completed successfully, and the Autoconf build passed all 245
core regression tests. All tests enabled in the Meson configuration
passed; TAP-only tests were not enabled in that configuration.
I also tested full Autoconf and Meson builds on Debian Bookworm with
glibc 2.36. There, explicit_bzero is both declared and available, and
PostgreSQL correctly continued to use the system implementation. A
normal macOS build against Homebrew OpenSSL 3.6.3 also completed
successfully.
The change is not platform-specific and introduces no user-visible
interface or expected performance change.
Regards,
--
Timo J. Rinne <[email protected]>
From 8717f78997197a6cf28a01b2ef7f4ca0d1481b1b Mon Sep 17 00:00:00 2001
From: "Timo J. Rinne" <[email protected]>
Date: Mon, 20 Jul 2026 17:36:30 +0300
Subject: [PATCH] Require a declaration before using explicit_bzero
A linked library can export explicit_bzero without declaring it in its public headers. In that case the symbol check succeeds, but callers cannot compile because no prototype is available.
Check for the declaration separately and use PostgreSQL's replacement when it is absent. Keep Autoconf and Meson behavior consistent.
Author: Timo J. Rinne <[email protected]>
---
configure | 27 ++++++++++++++++++++++++++-
configure.ac | 10 +++++++++-
meson.build | 5 ++++-
src/include/pg_config.h.in | 4 ++++
4 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/configure b/configure
index d42a7a794ff..04da7b7fee9 100755
--- a/configure
+++ b/configure
@@ -16347,6 +16347,18 @@ cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_TIMINGSAFE_BCMP $ac_have_decl
_ACEOF
+ac_fn_c_check_decl "$LINENO" "explicit_bzero" "ac_cv_have_decl_explicit_bzero" "#include <string.h>
+"
+if test "x$ac_cv_have_decl_explicit_bzero" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_EXPLICIT_BZERO $ac_have_decl
+_ACEOF
+
# We can't use AC_CHECK_FUNCS to detect these functions, because it
# won't handle deployment target restrictions on macOS
@@ -16414,7 +16426,10 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero"
+# A linked library may export explicit_bzero without declaring it. Do not
+# rely on such a symbol; use our replacement instead.
+if test "$ac_cv_have_decl_explicit_bzero" = yes; then
+ ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero"
if test "x$ac_cv_func_explicit_bzero" = xyes; then :
$as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h
@@ -16427,6 +16442,16 @@ esac
fi
+
+else
+ case " $LIBOBJS " in
+ *" explicit_bzero.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS explicit_bzero.$ac_objext"
+ ;;
+esac
+
+fi
+
ac_fn_c_check_func "$LINENO" "getopt" "ac_cv_func_getopt"
if test "x$ac_cv_func_getopt" = xyes; then :
$as_echo "#define HAVE_GETOPT 1" >>confdefs.h
diff --git a/configure.ac b/configure.ac
index a331749fcb5..7e721094fb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1900,6 +1900,7 @@ AC_CHECK_DECLS(posix_fadvise, [], [], [#include <fcntl.h>])
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
AC_CHECK_DECLS([strlcat, strlcpy, strsep, timingsafe_bcmp])
+AC_CHECK_DECLS([explicit_bzero], [], [], [#include <string.h>])
# We can't use AC_CHECK_FUNCS to detect these functions, because it
# won't handle deployment target restrictions on macOS
@@ -1912,8 +1913,15 @@ AC_CHECK_DECLS([memset_s], [], [], [#define __STDC_WANT_LIB_EXT1__ 1
# This is probably only present on macOS, but may as well check always
AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
+# A linked library may export explicit_bzero without declaring it. Do not
+# rely on such a symbol; use our replacement instead.
+if test "$ac_cv_have_decl_explicit_bzero" = yes; then
+ AC_REPLACE_FUNCS([explicit_bzero])
+else
+ AC_LIBOBJ([explicit_bzero])
+fi
+
AC_REPLACE_FUNCS(m4_normalize([
- explicit_bzero
getopt
getpeereid
inet_aton
diff --git a/meson.build b/meson.build
index f4cde249242..63ecf6d8291 100644
--- a/meson.build
+++ b/meson.build
@@ -2886,6 +2886,7 @@ endforeach
decl_checks = [
['F_FULLFSYNC', 'fcntl.h'],
+ ['explicit_bzero', 'string.h'],
['fdatasync', 'unistd.h'],
['posix_fadvise', 'fcntl.h'],
['strlcat', 'string.h'],
@@ -3197,7 +3198,9 @@ func_checks = [
# required. Just checking for dlsym() ought to suffice.
['dlsym', {'dependencies': [dl_dep], 'define': false}],
['elf_aux_info'],
- ['explicit_bzero'],
+ # A linked library may export explicit_bzero without declaring it. Do not
+ # rely on such a symbol; use our replacement instead.
+ ['explicit_bzero', {'skip': cdata.get('HAVE_DECL_EXPLICIT_BZERO') == 0}],
['explicit_memset'],
['getauxval'],
['getifaddrs'],
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 661c4a9b168..4b8e88718d3 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -77,6 +77,10 @@
similar. */
#undef HAVE_CXX_TYPEOF_UNQUAL
+/* Define to 1 if you have the declaration of `explicit_bzero', and to 0 if
+ you don't. */
+#undef HAVE_DECL_EXPLICIT_BZERO
+
/* Define to 1 if you have the declaration of `fdatasync', and to 0 if you
don't. */
#undef HAVE_DECL_FDATASYNC
--
2.50.1 (Apple Git-155)