0001-Use-mul_size-for-allocation-products-potentially-to-.patch
application/octet-stream
Filename: 0001-Use-mul_size-for-allocation-products-potentially-to-.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: Use mul_size for allocation products potentially to overflow
| File | + | − |
|---|---|---|
| src/backend/backup/basebackup_gzip.c | 2 | 1 |
| src/backend/catalog/namespace.c | 2 | 1 |
| src/backend/storage/buffer/bufmgr.c | 3 | 1 |
| src/backend/utils/adt/tsgistidx.c | 4 | 3 |
| src/fe_utils/astreamer_gzip.c | 7 | 1 |
From e58cc264e32bfcf968847e3eec68d07fcc170390 Mon Sep 17 00:00:00 2001
From: Xing Guo <higuoxing@gmail.com>
Date: Thu, 9 Apr 2026 11:00:54 +0800
Subject: [PATCH] Use mul_size for allocation products potentially to overflow
Several call sites multiplied runtime factors before palloc; use mul_size()
in the backend and pg_mul_size_overflow() in the frontend gzip allocator.
---
src/backend/backup/basebackup_gzip.c | 3 ++-
src/backend/catalog/namespace.c | 3 ++-
src/backend/storage/buffer/bufmgr.c | 4 +++-
src/backend/utils/adt/tsgistidx.c | 7 ++++---
src/fe_utils/astreamer_gzip.c | 8 +++++++-
5 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/src/backend/backup/basebackup_gzip.c b/src/backend/backup/basebackup_gzip.c
index c5e4c4143e8..1ec2c13ea7f 100644
--- a/src/backend/backup/basebackup_gzip.c
+++ b/src/backend/backup/basebackup_gzip.c
@@ -17,6 +17,7 @@
#endif
#include "backup/basebackup_sink.h"
+#include "storage/shmem.h"
#ifdef HAVE_LIBZ
typedef struct bbsink_gzip
@@ -297,7 +298,7 @@ bbsink_gzip_manifest_contents(bbsink *sink, size_t len)
static void *
gzip_palloc(void *opaque, unsigned items, unsigned size)
{
- return palloc(items * size);
+ return palloc(mul_size(size, items));
}
/*
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 56b87d878e8..d251cd302ff 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -48,6 +48,7 @@
#include "nodes/makefuncs.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
+#include "storage/shmem.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/acl.h"
@@ -1994,7 +1995,7 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok,
2 * sizeof(Oid))
if (catlist->n_members > 0)
- resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
+ resultSpace = palloc(mul_size(SPACE_PER_OP, catlist->n_members));
for (i = 0; i < catlist->n_members; i++)
{
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 3cc0b0bdd92..b738c053830 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -62,6 +62,7 @@
#include "storage/proclist.h"
#include "storage/procsignal.h"
#include "storage/read_stream.h"
+#include "storage/shmem.h"
#include "storage/smgr.h"
#include "storage/standby.h"
#include "utils/memdebug.h"
@@ -4925,7 +4926,8 @@ DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators)
* forks.
*/
block = (BlockNumber (*)[MAX_FORKNUM + 1])
- palloc(sizeof(BlockNumber) * n * (MAX_FORKNUM + 1));
+ palloc(mul_size(mul_size(sizeof(BlockNumber), (MAX_FORKNUM + 1)),
+ n));
/*
* We can avoid scanning the entire buffer pool if we know the exact size
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index e35a25797a0..38a80ad72d2 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -18,6 +18,7 @@
#include "access/heaptoast.h"
#include "access/reloptions.h"
#include "common/int.h"
+#include "storage/shmem.h"
#include "lib/qunique.h"
#include "port/pg_bitutils.h"
#include "tsearch/ts_utils.h"
@@ -625,7 +626,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
size_beta;
int32 size_waste,
waste = -1;
- int32 nbytes;
+ Size nbytes;
OffsetNumber seed_1 = 0,
seed_2 = 0;
OffsetNumber *left,
@@ -638,12 +639,12 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
SPLITCOST *costvector;
maxoff = entryvec->n - 2;
- nbytes = (maxoff + 2) * sizeof(OffsetNumber);
+ nbytes = mul_size(sizeof(OffsetNumber), (maxoff + 2));
v->spl_left = (OffsetNumber *) palloc(nbytes);
v->spl_right = (OffsetNumber *) palloc(nbytes);
cache = palloc_array(CACHESIGN, maxoff + 2);
- cache_sign = palloc(siglen * (maxoff + 2));
+ cache_sign = palloc(mul_size(siglen, (maxoff + 2)));
for (j = 0; j < maxoff + 2; j++)
cache[j].sign = &cache_sign[siglen * j];
diff --git a/src/fe_utils/astreamer_gzip.c b/src/fe_utils/astreamer_gzip.c
index bc3d53076e1..ffc41a75219 100644
--- a/src/fe_utils/astreamer_gzip.c
+++ b/src/fe_utils/astreamer_gzip.c
@@ -32,6 +32,7 @@
#include <zlib.h>
#endif
+#include "common/int.h"
#include "common/logging.h"
#include "fe_utils/astreamer.h"
@@ -382,7 +383,12 @@ astreamer_gzip_decompressor_free(astreamer *streamer)
static void *
gzip_palloc(void *opaque, unsigned items, unsigned size)
{
- return palloc(items * size);
+ size_t nbytes;
+
+ if (pg_mul_size_overflow((size_t) size, (size_t) items, &nbytes))
+ pg_fatal("gzip library requested invalid allocation size");
+
+ return palloc(nbytes);
}
/*
--
2.50.1 (Apple Git-155)