v3-0002-Support-getrandom-as-random-source-where-availabl.patch
application/octet-stream
Filename: v3-0002-Support-getrandom-as-random-source-where-availabl.patch
Type: application/octet-stream
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v3-0002
Subject: Support getrandom() as random source where available.
| File | + | − |
|---|---|---|
| configure | 5 | 2 |
| configure.ac | 4 | 1 |
| meson.build | 1 | 0 |
| src/include/pg_config.h.in | 3 | 0 |
| src/port/pg_strong_random.c | 36 | 5 |
From a65ac70e886bf3573483709bcb248b2328e7b32a Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Tue, 21 Oct 2025 17:35:15 -0700
Subject: [PATCH v3 2/2] Support getrandom() as random source where available.
Use glibc's getrandom() function when strong_random_source is set to
'system' on Linux and Unix-like operating systems. This method is much
faster than reading from /dev/urandom. In particular, recent Linux
kernels support a vDSO implementation of getrandom(), which our
performance tests showed to be approximately 10x faster.
Reviewed-by:
Discussion: https://postgr.es/m/
---
configure | 7 +++++--
configure.ac | 5 ++++-
meson.build | 1 +
src/include/pg_config.h.in | 3 +++
src/port/pg_strong_random.c | 41 ++++++++++++++++++++++++++++++++-----
5 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/configure b/configure
index 28df8d20139..91135999d9d 100755
--- a/configure
+++ b/configure
@@ -15576,7 +15576,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 getauxval getifaddrs getpeerucred getrandom 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
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"
@@ -18459,6 +18459,9 @@ else
if test x"$PORTNAME" = x"win32" ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Windows native" >&5
$as_echo "Windows native" >&6; }
+ elif test x"$ac_cv_func_getrandom" = x"yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: getrandom" >&5
+$as_echo "getrandom" >&6; }
elif test x"$cross_compiling" = x"yes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming /dev/urandom" >&5
$as_echo "assuming /dev/urandom" >&6; }
@@ -18488,7 +18491,7 @@ fi
if test x"$ac_cv_file__dev_urandom" = x"no" ; then
as_fn_error $? "
no source of strong random numbers was found
-PostgreSQL can use OpenSSL, native Windows API or /dev/urandom as a source of random numbers." "$LINENO" 5
+PostgreSQL can use OpenSSL, native Windows API, getrandom, or /dev/urandom as a source of random numbers." "$LINENO" 5
fi
fi
diff --git a/configure.ac b/configure.ac
index c86083b2c74..8adc8bc0f66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1781,6 +1781,7 @@ AC_CHECK_FUNCS(m4_normalize([
getauxval
getifaddrs
getpeerucred
+ getrandom
inet_pton
kqueue
localeconv_l
@@ -2319,6 +2320,8 @@ else
# be used.
if test x"$PORTNAME" = x"win32" ; then
AC_MSG_RESULT([Windows native])
+ elif test x"$ac_cv_func_getrandom" = x"yes" ; then
+ AC_MSG_RESULT(getrandom)
elif test x"$cross_compiling" = x"yes"; then
AC_MSG_RESULT([assuming /dev/urandom])
else
@@ -2328,7 +2331,7 @@ else
if test x"$ac_cv_file__dev_urandom" = x"no" ; then
AC_MSG_ERROR([
no source of strong random numbers was found
-PostgreSQL can use OpenSSL, native Windows API or /dev/urandom as a source of random numbers.])
+PostgreSQL can use OpenSSL, native Windows API, getrandom, or /dev/urandom as a source of random numbers.])
fi
fi
AC_DEFINE([STRONG_RANDOM_SOURCE_SYSTEM], 1, [Define to 1 to use system native source for strong random number generation])
diff --git a/meson.build b/meson.build
index ce28ac4c616..d835e338917 100644
--- a/meson.build
+++ b/meson.build
@@ -2911,6 +2911,7 @@ func_checks = [
['getopt_long', {'dependencies': [getopt_dep, gnugetopt_dep], 'skip': always_replace_getopt_long}],
['getpeereid'],
['getpeerucred'],
+ ['getrandom'],
['inet_aton'],
['inet_pton'],
['kqueue'],
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 9bcc9c54ff8..bd658364253 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -179,6 +179,9 @@
/* Define to 1 if you have the `getpeerucred' function. */
#undef HAVE_GETPEERUCRED
+/* Define to 1 if you have the `getrandom' function. */
+#undef HAVE_GETRANDOM
+
/* Define to 1 if you have the <gssapi_ext.h> header file. */
#undef HAVE_GSSAPI_EXT_H
diff --git a/src/port/pg_strong_random.c b/src/port/pg_strong_random.c
index cc6f598ac67..817ff6388bf 100644
--- a/src/port/pg_strong_random.c
+++ b/src/port/pg_strong_random.c
@@ -40,7 +40,8 @@
*
* 1. OpenSSL's RAND_bytes()
* 2. Windows' CryptGenRandom() function
- * 3. /dev/urandom
+ * 3. glibc's getrandom() function
+ * 4. /dev/urandom
*
* Returns true on success, and false if none of the sources
* were available. NB: It is important to check the return value!
@@ -134,12 +135,42 @@ pg_strong_random(void *buf, size_t len)
return false;
}
-#else /* STRONG_RANDOM_SOURCE_SYSTEM and not WIN32 */
+#elif HAVE_GETRANDOM /* STRONG_RANDOM_SOURCE_SYSTEM and
+ * HAVE_GETRANDOM */
+#include <sys/random.h>
-/*
- * Without OpenSSL or Win32 support, just read /dev/urandom ourselves.
- */
+void
+pg_strong_random_init(void)
+{
+ /* No initialization needed */
+}
+
+bool
+pg_strong_random(void *buf, size_t len)
+{
+ char *p = buf;
+ ssize_t res;
+
+ while (len)
+ {
+ /* Get random data from the urandom source in blocking mode */
+ res = getrandom(p, len, 0);
+ if (res <= 0)
+ {
+ if (errno == EINTR)
+ continue; /* interrupted by signal, just retry */
+
+ return false;
+ }
+
+ p += res;
+ len -= res;
+ }
+
+ return true;
+}
+#else /* not OpenSSL, WIN32, or HAVE_GETRANDOM */
void
pg_strong_random_init(void)
{
--
2.47.3