We can use either of these to implement a missing explicit_bzero().

explicit_memset() is supported on NetBSD. NetBSD hitherto didn't have a way to implement explicit_bzero() other than the fallback variant.

memset_explicit() is the C23 standard, so we use it as first preference. It is currently supported on:

- NetBSD 11
- FreeBSD 15
- glibc 2.43

It doesn't provide additional coverage, but as it's the new standard, its availability will presumably grow, and eventually we'll be able to remove some of the fallback variants.
From 26ded3d346656a5072061422e9f5349b66d3e533 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Mon, 23 Feb 2026 08:03:08 +0100
Subject: [PATCH] Check for memset_explicit() and explicit_memset()

We can use either of these to implement a missing explicit_bzero().

explicit_memset() is supported on NetBSD.  NetBSD hitherto didn't have
a way to implement explicit_bzero() other than the fallback variant.

memset_explicit() is the C23 standard, so we use it as first
preference.  It is currently supported on:

- NetBSD 11
- FreeBSD 15
- glibc 2.43

It doesn't provide additional coverage, but as it's the new standard,
its availability will presumably grow.
---
 configure                  |  2 +-
 configure.ac               |  2 ++
 meson.build                |  2 ++
 src/include/pg_config.h.in |  6 ++++++
 src/port/explicit_bzero.c  | 18 +++++++++++++++++-
 5 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index e1a08129974..43f87b3f7b9 100755
--- a/configure
+++ b/configure
@@ -15632,7 +15632,7 @@ fi
 LIBS_including_readline="$LIBS"
 LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
-for ac_func in backtrace_symbols copyfile copy_file_range elf_aux_info 
getauxval getifaddrs getpeerucred inet_pton kqueue localeconv_l mbstowcs_l 
posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast 
strsignal syncfs sync_file_range uselocale wcstombs_l
+for ac_func in backtrace_symbols copyfile copy_file_range elf_aux_info 
explicit_memset getauxval getifaddrs getpeerucred inet_pton kqueue localeconv_l 
mbstowcs_l memset_explicit posix_fallocate ppoll pthread_is_threaded_np 
setproctitle setproctitle_fast strsignal syncfs sync_file_range uselocale 
wcstombs_l
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/configure.ac b/configure.ac
index cc85c233c03..816a418db2b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1825,6 +1825,7 @@ AC_CHECK_FUNCS(m4_normalize([
        copyfile
        copy_file_range
        elf_aux_info
+       explicit_memset
        getauxval
        getifaddrs
        getpeerucred
@@ -1832,6 +1833,7 @@ AC_CHECK_FUNCS(m4_normalize([
        kqueue
        localeconv_l
        mbstowcs_l
+       memset_explicit
        posix_fallocate
        ppoll
        pthread_is_threaded_np
diff --git a/meson.build b/meson.build
index 055e96315d0..a59ef31bf43 100644
--- a/meson.build
+++ b/meson.build
@@ -2944,6 +2944,7 @@ func_checks = [
   ['dlsym', {'dependencies': [dl_dep], 'define': false}],
   ['elf_aux_info'],
   ['explicit_bzero'],
+  ['explicit_memset'],
   ['getauxval'],
   ['getifaddrs'],
   ['getopt', {'dependencies': [getopt_dep, gnugetopt_dep], 'skip': 
always_replace_getopt}],
@@ -2955,6 +2956,7 @@ func_checks = [
   ['kqueue'],
   ['localeconv_l'],
   ['mbstowcs_l'],
+  ['memset_explicit'],
   ['mkdtemp'],
   ['posix_fadvise'],
   ['posix_fallocate'],
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 3824a5571bb..6e340c6772c 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -131,6 +131,9 @@
 /* Define to 1 if you have the `explicit_bzero' function. */
 #undef HAVE_EXPLICIT_BZERO
 
+/* Define to 1 if you have the `explicit_memset' function. */
+#undef HAVE_EXPLICIT_MEMSET
+
 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
 #undef HAVE_FSEEKO
 
@@ -280,6 +283,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
+/* Define to 1 if you have the `memset_explicit' function. */
+#undef HAVE_MEMSET_EXPLICIT
+
 /* Define to 1 if you have the `mkdtemp' function. */
 #undef HAVE_MKDTEMP
 
diff --git a/src/port/explicit_bzero.c b/src/port/explicit_bzero.c
index 2147fc3b315..6be7660d28f 100644
--- a/src/port/explicit_bzero.c
+++ b/src/port/explicit_bzero.c
@@ -16,7 +16,23 @@
 
 #include "c.h"
 
-#if HAVE_DECL_MEMSET_S
+#if defined(HAVE_MEMSET_EXPLICIT)
+
+void
+explicit_bzero(void *buf, size_t len)
+{
+       (void) memset_explicit(buf, 0, len);
+}
+
+#elif defined(HAVE_EXPLICIT_MEMSET)
+
+void
+explicit_bzero(void *buf, size_t len)
+{
+       (void) explicit_memset(buf, 0, len);
+}
+
+#elif HAVE_DECL_MEMSET_S
 
 void
 explicit_bzero(void *buf, size_t len)
-- 
2.53.0

Reply via email to