Make our usage of memset_s() conform strictly to the C11 standard.
authorTom Lane <[email protected]>
Sun, 18 May 2025 16:45:55 +0000 (12:45 -0400)
committerTom Lane <[email protected]>
Sun, 18 May 2025 16:45:55 +0000 (12:45 -0400)
Per the letter of the C11 standard, one must #define
__STDC_WANT_LIB_EXT1__ as 1 before including <string.h> in order to
have access to memset_s().  It appears that many platforms are lenient
about this, because we weren't doing it and yet the code appeared to
work anyway.  But we now find that with -std=c11, macOS is strict and
doesn't declare memset_s, leading to compile failures since we try to
use it anyway.  (Given the lack of prior reports, perhaps this is new
behavior in the latest SDK?  No matter, we're clearly in the wrong.)

In addition to the immediate problem, which could be fixed merely by
adding the needed #define to explicit_bzero.c, it seems possible that
our configure-time probe for memset_s() could fail in case a platform
implements the function in some odd way due to this spec requirement.
This concern can be fixed in largely the same way that we dealt with
strchrnul() in 6da2ba1d8: switch to using a declaration-based
configure probe instead of a does-it-link probe.

Back-patch to v13 where we started using memset_s().

Reported-by: Lakshmi Narayana Velayudam <[email protected]>
Author: Tom Lane <[email protected]>
Discussion: https://postgr.es/m/CAA4pTnLcKGG78xeOjiBr5yS7ZeE-Rh=FaFQQGOO=nPzA1L8yEA@mail.gmail.com
Backpatch-through: 13

configure
configure.in
src/include/pg_config.h.in
src/port/explicit_bzero.c
src/tools/msvc/Solution.pm

index 0b1a8f550a93fde9126cac1e18d0afcea7f575c5..29f40977f3eed37fdd1dfdf9078bcc1b3e25262e 100755 (executable)
--- a/configure
+++ b/configure
@@ -15789,7 +15789,7 @@ fi
 LIBS_including_readline="$LIBS"
 LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
-for ac_func in backtrace_symbols clock_gettime copyfile fdatasync getifaddrs getpeerucred getrlimit kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pstat pthread_is_threaded_np readlink setproctitle setproctitle_fast setsid shm_open strsignal symlink sync_file_range uselocale wcstombs_l
+for ac_func in backtrace_symbols clock_gettime copyfile fdatasync getifaddrs getpeerucred getrlimit kqueue mbstowcs_l poll posix_fallocate ppoll pstat pthread_is_threaded_np readlink setproctitle setproctitle_fast setsid shm_open strsignal symlink 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"
@@ -16321,6 +16321,19 @@ cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_STRCHRNUL $ac_have_decl
 _ACEOF
 
+ac_fn_c_check_decl "$LINENO" "memset_s" "ac_cv_have_decl_memset_s" "#define __STDC_WANT_LIB_EXT1__ 1
+#include <string.h>
+"
+if test "x$ac_cv_have_decl_memset_s" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_MEMSET_S $ac_have_decl
+_ACEOF
+
 
 # This is probably only present on macOS, but may as well check always
 ac_fn_c_check_decl "$LINENO" "F_FULLFSYNC" "ac_cv_have_decl_F_FULLFSYNC" "#include <fcntl.h>
index 127f552258e13f7f471e6d18d2e0d2877b0ece7c..c17342b1ba0b31d1a726e2d5ae7265e925bf7d08 100644 (file)
@@ -1750,7 +1750,6 @@ AC_CHECK_FUNCS(m4_normalize([
    getrlimit
    kqueue
    mbstowcs_l
-   memset_s
    poll
    posix_fallocate
    ppoll
@@ -1799,6 +1798,8 @@ AC_CHECK_DECLS([strlcat, strlcpy, strnlen])
 # We can't use AC_REPLACE_FUNCS to replace these functions, because it
 # won't handle deployment target restrictions on macOS
 AC_CHECK_DECLS([strchrnul], [], [], [#include <string.h>])
+AC_CHECK_DECLS([memset_s], [], [], [#define __STDC_WANT_LIB_EXT1__ 1
+#include <string.h>])
 
 # This is probably only present on macOS, but may as well check always
 AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
index d7c7ecd5e30bb75a2ac948c6261e1cf22e65b002..b351a0b95823199a30ede2f8e62a37d428c442f4 100644 (file)
    to 0 if you don't. */
 #undef HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
 
+/* Define to 1 if you have the declaration of `memset_s', and to 0 if you
+   don't. */
+#undef HAVE_DECL_MEMSET_S
+
 /* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you
    don't. */
 #undef HAVE_DECL_POSIX_FADVISE
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
-/* Define to 1 if you have the `memset_s' function. */
-#undef HAVE_MEMSET_S
-
 /* Define to 1 if the system has the type `MINIDUMP_TYPE'. */
 #undef HAVE_MINIDUMP_TYPE
 
index 6bd8b0dd9d23887432f8ef389890041bdf5078b0..37db95691ed3d4749069900eb0186c25b4a545bc 100644 (file)
  *-------------------------------------------------------------------------
  */
 
+#define __STDC_WANT_LIB_EXT1__ 1   /* needed to access memset_s() */
+
 #include "c.h"
 
-#if defined(HAVE_MEMSET_S)
+#if HAVE_DECL_MEMSET_S
 
 void
 explicit_bzero(void *buf, size_t len)
index d0f406afbbda4174177ff7cebe9e08b44dd6554a..e4ff4fc342423c588a0a442612231974a7788861 100644 (file)
@@ -240,6 +240,7 @@ sub GenerateFiles
        HAVE_DECL_LLVMGETHOSTCPUNAME                => 0,
        HAVE_DECL_LLVMGETHOSTCPUFEATURES            => 0,
        HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN         => 0,
+       HAVE_DECL_MEMSET_S                          => 0,
        HAVE_DECL_POSIX_FADVISE                     => 0,
        HAVE_DECL_RTLD_GLOBAL                       => 0,
        HAVE_DECL_RTLD_NOW                          => 0,
@@ -313,7 +314,6 @@ sub GenerateFiles
        HAVE_MBARRIER_H             => undef,
        HAVE_MBSTOWCS_L             => 1,
        HAVE_MEMORY_H               => 1,
-       HAVE_MEMSET_S               => undef,
        HAVE_MINIDUMP_TYPE          => 1,
        HAVE_MKDTEMP                => undef,
        HAVE_NETINET_TCP_H          => undef,