diff --git a/configure b/configure index b0308a2b9e7..2eca3122a03 100755 --- a/configure +++ b/configure @@ -16321,6 +16321,16 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNLEN $ac_have_decl _ACEOF +ac_fn_c_check_decl "$LINENO" "timingsafe_bcmp" "ac_cv_have_decl_timingsafe_bcmp" "$ac_includes_default" +if test "x$ac_cv_have_decl_timingsafe_bcmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TIMINGSAFE_BCMP $ac_have_decl +_ACEOF # We can't use AC_REPLACE_FUNCS to replace these functions, because it @@ -16513,6 +16523,19 @@ esac fi +ac_fn_c_check_func "$LINENO" "timingsafe_bcmp" "ac_cv_func_timingsafe_bcmp" +if test "x$ac_cv_func_timingsafe_bcmp" = xyes; then : + $as_echo "#define HAVE_TIMINGSAFE_BCMP 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" timingsafe_bcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS timingsafe_bcmp.$ac_objext" + ;; +esac + +fi + if test "$enable_thread_safety" = yes; then diff --git a/configure.ac b/configure.ac index 9eefefd6804..c4cd6fd1c0f 100644 --- a/configure.ac +++ b/configure.ac @@ -1842,7 +1842,7 @@ AC_CHECK_DECLS(posix_fadvise, [], [], [#include ]) ]) # fi AC_CHECK_DECLS(fdatasync, [], [], [#include ]) -AC_CHECK_DECLS([strlcat, strlcpy, strnlen]) +AC_CHECK_DECLS([strlcat, strlcpy, strnlen, timingsafe_bcmp]) # We can't use AC_REPLACE_FUNCS to replace these functions, because it # won't handle deployment target restrictions on macOS @@ -1864,6 +1864,7 @@ AC_REPLACE_FUNCS(m4_normalize([ strlcat strlcpy strnlen + timingsafe_bcmp ])) if test "$enable_thread_safety" = yes; then diff --git a/meson.build b/meson.build index 517f44d107c..718132cd738 100644 --- a/meson.build +++ b/meson.build @@ -2341,6 +2341,7 @@ decl_checks = [ ['strlcat', 'string.h'], ['strlcpy', 'string.h'], ['strnlen', 'string.h'], + ['timingsafe_bcmp', 'string.h'], ] # Need to check for function declarations for these functions, because @@ -2630,6 +2631,7 @@ func_checks = [ ['strsignal'], ['sync_file_range'], ['syncfs'], + ['timingsafe_bcmp'], ['uselocale'], ['wcstombs_l'], ] diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index d06c49a8942..f6355cc923e 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -148,6 +148,10 @@ don't. */ #undef HAVE_DECL_STRNLEN +/* Define to 1 if you have the declaration of `timingsafe_bcmp', and to 0 if + you don't. */ +#undef HAVE_DECL_TIMINGSAFE_BCMP + /* Define to 1 if you have the header file. */ #undef HAVE_EDITLINE_HISTORY_H @@ -483,6 +487,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_TERMIOS_H +/* Define to 1 if you have the `timingsafe_bcmp' function. */ +#undef HAVE_TIMINGSAFE_BCMP + /* Define to 1 if your compiler understands `typeof' or something similar. */ #undef HAVE_TYPEOF diff --git a/src/include/port.h b/src/include/port.h index 2b2ea07ce5e..3e277d7e308 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -465,6 +465,10 @@ extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen); extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen); #endif +#if !HAVE_DECL_TIMINGSAFE_BCMP +extern int timingsafe_bcmp(const void *b1, const void *b2, size_t len); +#endif + extern void pg_qsort(void *base, size_t nel, size_t elsize, int (*cmp) (const void *, const void *)); extern int pg_qsort_strcmp(const void *a, const void *b); diff --git a/src/port/meson.build b/src/port/meson.build index 825bd4d1cb2..2fefd19068d 100644 --- a/src/port/meson.build +++ b/src/port/meson.build @@ -72,6 +72,7 @@ replace_funcs_neg = [ ['strlcat'], ['strlcpy'], ['strnlen'], + ['timingsafe_bcmp'], ] if host_system != 'windows' diff --git a/src/port/timingsafe_bcmp.c b/src/port/timingsafe_bcmp.c new file mode 100644 index 00000000000..288865f50d1 --- /dev/null +++ b/src/port/timingsafe_bcmp.c @@ -0,0 +1,43 @@ +/* + * src/port/timingsafe_bcmp.c + * + * $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ + */ + +/* + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "c.h" + +#ifdef USE_SSL +#include +#endif + +int +timingsafe_bcmp(const void *b1, const void *b2, size_t n) +{ +#ifdef USE_SSL + return CRYPTO_memcmp(b1, b2, n); +#else + const unsigned char *p1 = b1, + *p2 = b2; + int ret = 0; + + for (; n > 0; n--) + ret |= *p1++ ^ *p2++; + return (ret != 0); +#endif +} diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index e224f8d7480..ce0e2588512 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -107,7 +107,7 @@ sub mkvcbuild preadv.c pwritev.c pg_bitutils.c pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c - strerror.c tar.c + strerror.c tar.c timingsafe_bcmp.c win32common.c win32dlopen.c win32env.c win32error.c diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index c0ba9076b31..ea440c3453d 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -246,6 +246,7 @@ sub GenerateFiles HAVE_DECL_STRLCAT => 0, HAVE_DECL_STRLCPY => 0, HAVE_DECL_STRNLEN => 1, + HAVE_DECL_TIMINGSAFE_BCMP => 0, HAVE_EDITLINE_HISTORY_H => undef, HAVE_EDITLINE_READLINE_H => undef, HAVE_EXECINFO_H => undef, @@ -356,6 +357,7 @@ sub GenerateFiles HAVE_SYS_TYPES_H => 1, HAVE_SYS_UCRED_H => undef, HAVE_TERMIOS_H => undef, + HAVE_TIMINGSAFE_BCMP => undef, HAVE_TYPEOF => undef, HAVE_UCRED_H => undef, HAVE_UINT64 => undef,