0001-PoC-Select-random-source-type.patch
application/octet-stream
Filename: 0001-PoC-Select-random-source-type.patch
Type: application/octet-stream
Part: 0
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 0001
Subject: PoC: Select random source type.
| File | + | − |
|---|---|---|
| src/backend/utils/misc/guc_parameters.dat | 8 | 0 |
| src/backend/utils/misc/guc_tables.c | 1 | 0 |
| src/backend/utils/misc/Makefile | 1 | 0 |
| src/backend/utils/misc/meson.build | 1 | 0 |
| src/backend/utils/misc/postgresql.conf.sample | 1 | 0 |
| src/backend/utils/misc/random_source.c | 59 | 0 |
| src/bin/initdb/initdb.c | 13 | 0 |
| src/include/port.h | 29 | 2 |
| src/include/utils/guc.h | 1 | 0 |
| src/include/utils/guc_hooks.h | 1 | 0 |
| src/include/utils/random_source.h | 32 | 0 |
| src/port/pg_strong_random.c | 27 | 10 |
From 2e1f3ef7233f9ecafc0f4bfccdb1195bdebbf256 Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Mon, 22 Sep 2025 23:20:06 -0700
Subject: [PATCH 1/2] PoC: Select random source type.
---
src/backend/utils/misc/Makefile | 1 +
src/backend/utils/misc/guc_parameters.dat | 8 +++
src/backend/utils/misc/guc_tables.c | 1 +
src/backend/utils/misc/meson.build | 1 +
src/backend/utils/misc/postgresql.conf.sample | 1 +
src/backend/utils/misc/random_source.c | 59 +++++++++++++++++++
src/bin/initdb/initdb.c | 13 ++++
src/include/port.h | 31 +++++++++-
src/include/utils/guc.h | 1 +
src/include/utils/guc_hooks.h | 1 +
src/include/utils/random_source.h | 32 ++++++++++
src/port/pg_strong_random.c | 37 ++++++++----
12 files changed, 174 insertions(+), 12 deletions(-)
create mode 100644 src/backend/utils/misc/random_source.c
create mode 100644 src/include/utils/random_source.h
diff --git a/src/backend/utils/misc/Makefile b/src/backend/utils/misc/Makefile
index b362ae43771..96686c50e5f 100644
--- a/src/backend/utils/misc/Makefile
+++ b/src/backend/utils/misc/Makefile
@@ -27,6 +27,7 @@ OBJS = \
pg_rusage.o \
ps_status.o \
queryenvironment.o \
+ random_source.o \
rls.o \
sampling.o \
stack_depth.o \
diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat
index 6bc6be13d2a..22e9aa7dbab 100644
--- a/src/backend/utils/misc/guc_parameters.dat
+++ b/src/backend/utils/misc/guc_parameters.dat
@@ -3475,4 +3475,12 @@
assign_hook => 'assign_io_method',
},
+{ name => 'random_source_type', type => 'enum', context => 'PGC_BACKEND', group => 'RESOURCES_KERNEL',
+ short_desc => 'Selects the random data generation function.',
+ variable => 'random_source_type',
+ boot_val => 'DEFAULT_RANDOM_SOURCE_TYPE',
+ options => 'random_source_type_options',
+ assign_hook => 'assign_random_source_type',
+},
+
]
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 00c8376cf4d..0bdc144a155 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -99,6 +99,7 @@
#include "utils/pg_locale.h"
#include "utils/plancache.h"
#include "utils/ps_status.h"
+#include "utils/random_source.h"
#include "utils/rls.h"
#include "utils/xml.h"
diff --git a/src/backend/utils/misc/meson.build b/src/backend/utils/misc/meson.build
index 9e389a00d05..6b03998b942 100644
--- a/src/backend/utils/misc/meson.build
+++ b/src/backend/utils/misc/meson.build
@@ -12,6 +12,7 @@ backend_sources += files(
'pg_rusage.c',
'ps_status.c',
'queryenvironment.c',
+ 'random_source.c',
'rls.c',
'sampling.c',
'stack_depth.c',
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index c36fcb9ab61..c148b06bd27 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -772,6 +772,7 @@ autovacuum_worker_slots = 16 # autovacuum worker slots to allocate
#gin_pending_list_limit = 4MB
#createrole_self_grant = '' # set and/or inherit
#event_triggers = on
+#random_source_type = 'system'
# - Locale and Formatting -
diff --git a/src/backend/utils/misc/random_source.c b/src/backend/utils/misc/random_source.c
new file mode 100644
index 00000000000..8ae67cf8d85
--- /dev/null
+++ b/src/backend/utils/misc/random_source.c
@@ -0,0 +1,59 @@
+/*-------------------------------------------------------------------------
+ *
+ * random_source.c
+ *
+ * Dynamically setup random generation function based on random_source_type
+ * GUC parameter.
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994-5, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/utils/misc/random_source.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "port.h"
+#include "utils/random_source.h"
+#include "utils/guc.h"
+#include "utils/guc_hooks.h"
+
+const struct config_enum_entry random_source_type_options[] = {
+ {"system", RANDOM_SOURCE_TYPE_SYSTEM, false},
+#ifdef USE_OPENSSL
+ {"openssl", RANDOM_SOURCE_TYPE_OSSL, false},
+#endif
+ {NULL, 0, false}
+};
+
+static const struct
+{
+ pg_strong_random_init_fn initfn;
+ pg_strong_random_fn genfn;
+} random_source_type_table[] = {
+
+ [RANDOM_SOURCE_TYPE_SYSTEM] = {
+ .initfn = pg_strong_random_init_system,
+ .genfn = pg_strong_random_system,
+ },
+#ifdef USE_OPENSSL
+ [RANDOM_SOURCE_TYPE_OSSL] = {
+ .initfn = pg_strong_random_init_openssl,
+ .genfn = pg_strong_random_openssl,
+ },
+#endif
+};
+
+int random_source_type = DEFAULT_RANDOM_SOURCE_TYPE;
+
+/* Assign hook for random_source_type */
+void
+assign_random_source_type(int newval, void *extra)
+{
+ pg_strong_random_init_impl = random_source_type_table[newval].initfn;
+ pg_strong_random_impl = random_source_type_table[newval].genfn;
+}
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 92fe2f531f7..bcf7fb0f20c 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1109,6 +1109,16 @@ choose_dsm_implementation(void)
#endif
}
+static const char *
+choose_random_source_type(void)
+{
+#ifdef USE_OPENSSL
+ return "openssl";
+#else
+ return "system";
+#endif
+}
+
/*
* Determine platform-specific config settings
*
@@ -1356,6 +1366,9 @@ setup_config(void)
conflines = replace_guc_value(conflines, "dynamic_shared_memory_type",
dynamic_shared_memory_type, false);
+ conflines = replace_guc_value(conflines, "random_source_type",
+ choose_random_source_type(), false);
+
/* Caution: these depend on wal_segment_size_mb, they're not constants */
conflines = replace_guc_value(conflines, "min_wal_size",
pretty_wal_size(DEFAULT_MIN_WAL_SEGS), false);
diff --git a/src/include/port.h b/src/include/port.h
index 3964d3b1293..d7464c231a5 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -509,8 +509,35 @@ extern char *pg_inet_net_ntop(int af, const void *src, int bits,
char *dst, size_t size);
/* port/pg_strong_random.c */
-extern void pg_strong_random_init(void);
-extern bool pg_strong_random(void *buf, size_t len);
+extern void pg_strong_random_init_system(void);
+extern bool pg_strong_random_system(void *buf, size_t len);
+#ifdef USE_OPENSSL
+extern void pg_strong_random_init_openssl(void);
+extern bool pg_strong_random_openssl(void *buf, size_t len);
+#endif
+
+typedef void (*pg_strong_random_init_fn) (void);
+typedef bool (*pg_strong_random_fn) (void *buf, size_t len);
+
+/* Function pointers to the random data generation implementations */
+extern pg_strong_random_init_fn pg_strong_random_init_impl;
+extern pg_strong_random_fn pg_strong_random_impl;
+
+/*
+ * Public functions to generate strong random data. The functions invoked
+ * from these function can be replaced by setting function pointers.
+ */
+static pg_attribute_always_inline void
+pg_strong_random_init(void)
+{
+ (*pg_strong_random_init_impl) ();
+}
+
+static pg_attribute_always_inline bool
+pg_strong_random(void *buf, size_t len)
+{
+ return (*pg_strong_random_impl) (buf, len);
+}
/*
* pg_backend_random used to be a wrapper for pg_strong_random before
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index f21ec37da89..c64e99318fa 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -343,6 +343,7 @@ extern PGDLLIMPORT bool optimize_bounded_sort;
extern PGDLLIMPORT const struct config_enum_entry archive_mode_options[];
extern PGDLLIMPORT const struct config_enum_entry dynamic_shared_memory_options[];
extern PGDLLIMPORT const struct config_enum_entry io_method_options[];
+extern PGDLLIMPORT const struct config_enum_entry random_source_type_options[];
extern PGDLLIMPORT const struct config_enum_entry recovery_target_action_options[];
extern PGDLLIMPORT const struct config_enum_entry wal_level_options[];
extern PGDLLIMPORT const struct config_enum_entry wal_sync_method_options[];
diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h
index 82ac8646a8d..7bc8f6217ce 100644
--- a/src/include/utils/guc_hooks.h
+++ b/src/include/utils/guc_hooks.h
@@ -96,6 +96,7 @@ extern bool check_primary_slot_name(char **newval, void **extra,
GucSource source);
extern bool check_random_seed(double *newval, void **extra, GucSource source);
extern void assign_random_seed(double newval, void *extra);
+extern void assign_random_source_type(int newval, void *extra);
extern const char *show_random_seed(void);
extern bool check_recovery_prefetch(int *new_value, void **extra,
GucSource source);
diff --git a/src/include/utils/random_source.h b/src/include/utils/random_source.h
new file mode 100644
index 00000000000..b4f8a88db43
--- /dev/null
+++ b/src/include/utils/random_source.h
@@ -0,0 +1,32 @@
+/*-------------------------------------------------------------------------
+ *
+ * random_source.h
+ *
+ * Copyright (c) 2007-2025, PostgreSQL Global Development Group
+ *
+ * src/include/utils/random_source.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef RANDOM_SOURCE_H
+#define RANDOM_SOURCE_H
+
+typedef enum RandomSourceType
+{
+ RANDOM_SOURCE_TYPE_SYSTEM = 0,
+#ifdef USE_OPENSSL
+ RANDOM_SOURCE_TYPE_OSSL,
+#endif
+} RandomSourceType;
+
+#ifdef USE_OPENSSL
+#define DEFAULT_RANDOM_SOURCE_TYPE RANDOM_SOURCE_TYPE_OSSL
+#else
+#define DEFAULT_RANDOM_SOURCE_TYPE RANDOM_SOURCE_TYPE_SYSTEM
+#endif
+
+/* GUC */
+extern PGDLLIMPORT int random_source_type;
+
+#endif /* RANDOM_SOURCE_H */
diff --git a/src/port/pg_strong_random.c b/src/port/pg_strong_random.c
index ea6780dcc9f..231995e42af 100644
--- a/src/port/pg_strong_random.c
+++ b/src/port/pg_strong_random.c
@@ -25,7 +25,7 @@
#include <sys/time.h>
/*
- * pg_strong_random & pg_strong_random_init
+ * pg_strong_random & pg_strong_random_init implementations.
*
* Generate requested number of random bytes. The returned bytes are
* cryptographically secure, suitable for use e.g. in authentication.
@@ -48,6 +48,21 @@
* would lead to predictable keys and security issues.
*/
+/*
+ * Set default implementations.
+ *
+ * The pg_strong_random and pg_strong_random_init implementations are fixed to
+ * the implementations follows in FRONTEND builds. On non-FRONTEND builds (i.e.,
+ * backends) the implementations could be replaced by random_source_type GUC
+ * parameter.
+ */
+#ifdef USE_OPENSSL
+pg_strong_random_init_fn pg_strong_random_init_impl = pg_strong_random_init_openssl;
+pg_strong_random_fn pg_strong_random_impl = pg_strong_random_openssl;
+#else
+pg_strong_random_init_fn pg_strong_random_init_impl = pg_strong_random_init_system;
+pg_strong_random_fn pg_strong_random_impl = pg_strong_random_system;
+#endif
#ifdef USE_OPENSSL
@@ -55,13 +70,13 @@
#include <openssl/rand.h>
void
-pg_strong_random_init(void)
+pg_strong_random_init_openssl(void)
{
/* No initialization needed */
}
bool
-pg_strong_random(void *buf, size_t len)
+pg_strong_random_openssl(void *buf, size_t len)
{
int i;
@@ -92,7 +107,9 @@ pg_strong_random(void *buf, size_t len)
return false;
}
-#elif WIN32
+#endif
+
+#if WIN32
#include <wincrypt.h>
/*
@@ -102,13 +119,13 @@ pg_strong_random(void *buf, size_t len)
static HCRYPTPROV hProvider = 0;
void
-pg_strong_random_init(void)
+pg_strong_random_init_system(void)
{
/* No initialization needed on WIN32 */
}
bool
-pg_strong_random(void *buf, size_t len)
+pg_strong_random_system(void *buf, size_t len)
{
if (hProvider == 0)
{
@@ -134,20 +151,20 @@ pg_strong_random(void *buf, size_t len)
return false;
}
-#else /* not USE_OPENSSL or WIN32 */
+#else /* not WIN32 */
/*
- * Without OpenSSL or Win32 support, just read /dev/urandom ourselves.
+ * On Unix-like platforms, just read /dev/urandom ourselves.
*/
void
-pg_strong_random_init(void)
+pg_strong_random_init_system(void)
{
/* No initialization needed */
}
bool
-pg_strong_random(void *buf, size_t len)
+pg_strong_random_system(void *buf, size_t len)
{
int f;
char *p = buf;
--
2.47.3