v1-0001-Fix-guc_malloc-calls-to-check-for-OOM-and-return-.patch
application/octet-stream
Filename: v1-0001-Fix-guc_malloc-calls-to-check-for-OOM-and-return-.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 v1-0001
Subject: Fix guc_malloc calls to check for OOM and return false
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlog.c | 3 | 1 |
| src/backend/commands/user.c | 2 | 0 |
| src/backend/replication/slot.c | 2 | 0 |
| src/backend/tcop/backend_startup.c | 3 | 1 |
| src/backend/tcop/postgres.c | 3 | 1 |
| src/backend/utils/error/elog.c | 6 | 2 |
From 39de8e1567ff0631ab30ac010f6393a028ecdac4 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <dgustafsson@postgresql.org>
Date: Fri, 14 Mar 2025 22:56:58 +0100
Subject: [PATCH v1] Fix guc_malloc calls to check for OOM and return false
check_createrole_self_grant and check_synchronized_standby_slots
were allocating memory on a LOG elevel without checking if the
allocation succeeded or not, which would have led to a segfault
if it didn't. The remaining calls were using the ERROR level
and relied on erroring out rather than returnin false to let
the GUC machinery handle it gracefully.
Author: Daniel Gustafsson <daniel@yesql.se>
Reported-by: Nikita <pm91.arapov@gmail.com>
Bug: #18845
Discussion: https://postgr.es/m/18845-582c6e10247377ec@postgresql.org
---
src/backend/access/transam/xlog.c | 4 +++-
src/backend/commands/user.c | 2 ++
src/backend/replication/slot.c | 2 ++
src/backend/tcop/backend_startup.c | 4 +++-
src/backend/tcop/postgres.c | 4 +++-
src/backend/utils/error/elog.c | 8 ++++++--
6 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 799fc739e18..0c4c5b9a368 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -4791,7 +4791,9 @@ check_wal_consistency_checking(char **newval, void **extra, GucSource source)
list_free(elemlist);
/* assign new value */
- *extra = guc_malloc(ERROR, (RM_MAX_ID + 1) * sizeof(bool));
+ *extra = guc_malloc(LOG, (RM_MAX_ID + 1) * sizeof(bool));
+ if (!*extra)
+ return false;
memcpy(*extra, newwalconsistency, (RM_MAX_ID + 1) * sizeof(bool));
return true;
}
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 8ae510c623b..0d638e29d00 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -2566,6 +2566,8 @@ check_createrole_self_grant(char **newval, void **extra, GucSource source)
list_free(elemlist);
result = (unsigned *) guc_malloc(LOG, sizeof(unsigned));
+ if (!result)
+ return false;
*result = options;
*extra = result;
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 719e531eb90..646ba2a78fa 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -2730,6 +2730,8 @@ check_synchronized_standby_slots(char **newval, void **extra, GucSource source)
/* GUC extra value must be guc_malloc'd, not palloc'd */
config = (SyncStandbySlotsConfigData *) guc_malloc(LOG, size);
+ if (!config)
+ return false;
/* Transform the data into SyncStandbySlotsConfigData */
config->nslotnames = list_length(elemlist);
diff --git a/src/backend/tcop/backend_startup.c b/src/backend/tcop/backend_startup.c
index 27c0b3c2b04..a07c59ece01 100644
--- a/src/backend/tcop/backend_startup.c
+++ b/src/backend/tcop/backend_startup.c
@@ -1078,7 +1078,9 @@ check_log_connections(char **newval, void **extra, GucSource source)
* We succeeded, so allocate `extra` and save the flags there for use by
* assign_log_connections().
*/
- *extra = guc_malloc(ERROR, sizeof(int));
+ *extra = guc_malloc(LOG, sizeof(int));
+ if (!*extra)
+ return false;
*((int *) *extra) = flags;
return true;
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 55ab2da299b..0950a7bd1a2 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3617,7 +3617,9 @@ check_restrict_nonsystem_relation_kind(char **newval, void **extra, GucSource so
list_free(elemlist);
/* Save the flags in *extra, for use by the assign function */
- *extra = guc_malloc(ERROR, sizeof(int));
+ *extra = guc_malloc(LOG, sizeof(int));
+ if (!*extra)
+ return false;
*((int *) *extra) = flags;
return true;
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 860bbd40d42..b891dab3bf6 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -2198,7 +2198,9 @@ check_backtrace_functions(char **newval, void **extra, GucSource source)
* whitespace chars to save some memory, but it doesn't seem worth the
* trouble.
*/
- someval = guc_malloc(ERROR, newvallen + 1 + 1);
+ someval = guc_malloc(LOG, newvallen + 1 + 1);
+ if (!someval)
+ return false;
for (i = 0, j = 0; i < newvallen; i++)
{
if ((*newval)[i] == ',')
@@ -2283,7 +2285,9 @@ check_log_destination(char **newval, void **extra, GucSource source)
pfree(rawstring);
list_free(elemlist);
- myextra = (int *) guc_malloc(ERROR, sizeof(int));
+ myextra = (int *) guc_malloc(LOG, sizeof(int));
+ if (!myextra)
+ return false;
*myextra = newlogdest;
*extra = myextra;
--
2.39.3 (Apple Git-146)