agora inbox for pgsql-bugs@postgresql.org
help / color / mirror / Atom feedFrom: Pierre Forstmann <pierre.forstmann@gmail.com>
To: pgsql-bugs@lists.postgresql.org
Cc: hackerzheng666@gmail.com
Subject: Re: BUG #19634: Hash partition with large MODULUS causes "invalid memory alloc request size"
Date: Fri, 21 Aug 2026 14:04:09 +0200
Message-ID: <19d59133-7a9b-4d9f-a439-201d143bdb5f@gmail.com> (raw)
In-Reply-To: <19634-c18dfa96a8edc306@postgresql.org>
References: <19634-c18dfa96a8edc306@postgresql.org>
Hello,
I propose following patch that adds the check to new_partition_bound
routine:
postgres=# CREATE TABLE t (id int) PARTITION BY HASH (id);
CREATE TABLE
postgres=# CREATE TABLE t_p0 PARTITION OF t FOR VALUES WITH (MODULUS
268435457,
REMAINDER 0);
ERROR: hash partitions bounds are too large
DETAIL: Creating hash partitions for modulus 268435457 would require
too much memory.
HINT: Reduce the number of partitions.
postgres=#
Regards,
Pierre Forstmann
Le 21/08/2026 à 05:44, PG Bug reporting form a écrit :
> The following bug has been logged on the website:
>
> Bug reference: 19634
> Logged by: Zheng Hacker
> Email address: hackerzheng666@gmail.com
> PostgreSQL version: 19beta3
> Operating system: Linux x86_64
> Description:
>
> Creating a hash partition with MODULUS >= 268435457 causes an internal error
> "invalid memory alloc request size" on any subsequent query against the
> partitioned table. The table becomes permanently unusable — SELECT,
> INSERT,
> and all other operations fail with the same error. Only DROP TABLE works.
>
> Minimal reproducer (tested on PG 20devel commit 609f969, 2026-08-21):
>
> CREATE TABLE t (id int) PARTITION BY HASH (id);
> CREATE TABLE t_p0 PARTITION OF t FOR VALUES WITH (MODULUS 268435457,
> REMAINDER 0);
> SELECT * FROM t; -- ERROR: invalid memory alloc request size 1073741828
>
> Root cause:
> In src/backend/partitioning/partbounds.c, create_hash_bounds() (line 390)
> allocates an array indexed by greatest_modulus:
>
> boundinfo->nindexes = greatest_modulus;
> boundinfo->indexes = palloc_array(int, greatest_modulus);
>
> When greatest_modulus >= 268435457, this requests 268435457 * 4 =
> 1073741828
> bytes, exceeding MaxAllocSize (1073741823 = 1GB - 1). No bounds check
> exists
> on the modulus value before this allocation.
>
> The validation in check_new_partition_bound() (line ~2927) runs AFTER
> create_hash_bounds() is called during partition descriptor loading, so it
> never gets a chance to reject the invalid modulus.
>
> Impact:
> - Affects all versions since hash partitioning was introduced (PG 11+)
> - The partition is created successfully (CREATE TABLE succeeds)
> - But any access to the parent table fails permanently
> - Only DROP TABLE recovers the table
> - Any unprivileged user with CREATE TABLE permission can trigger this
>
> Suggested fix:
> Add a bounds check in create_hash_bounds() before the allocation, or
> validate modulus against MaxAllocSize in check_new_partition_bound()
> before partition descriptor loading.
>
> PostgreSQL version: 20devel (commit 609f969)
> OS: Ubuntu 22.04 x86_64
>
>
>
>
Attachments:
[text/x-patch] 0001-v1-0001-Fix-memory-allocation-check.patch (1.6K, ../19d59133-7a9b-4d9f-a439-201d143bdb5f@gmail.com/2-0001-v1-0001-Fix-memory-allocation-check.patch)
download | inline diff:
From 7ca80f33b806e2b322e9631e01046173b276e87e Mon Sep 17 00:00:00 2001
From: Pierre Forstmann <pierre.forstmann@gmail.com>
Date: Fri, 21 Aug 2026 13:56:29 +0200
Subject: [PATCH] v1-0001-Fix-memory-allocation-check
---
src/backend/partitioning/partbounds.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index 865a92c8561..15ab0f715d4 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -2918,6 +2918,14 @@ check_new_partition_bound(char *relname, Relation parent,
Assert(spec->strategy == PARTITION_STRATEGY_HASH);
Assert(spec->remainder >= 0 && spec->remainder < spec->modulus);
+ /* Check needed memory that will be allocated in create_hash_bounds() */
+ if (spec->modulus * sizeof(int) > MaxAllocSize)
+ ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ (errmsg("hash partitions bounds are too large"),
+ errdetail("Creating hash partitions for modulus %d would require too much memory.", spec->modulus),
+ errhint("Reduce the number of partitions."))));
+
+
if (partdesc->nparts > 0)
{
int greatest_modulus;
@@ -3030,8 +3038,10 @@ check_new_partition_bound(char *relname, Relation parent,
}
remainder += spec->modulus;
} while (remainder < greatest_modulus);
+
}
+
break;
}
--
2.47.3
view thread (3+ messages) latest in thread
Message-ID: <19d59133-7a9b-4d9f-a439-201d143bdb5f@gmail.com>
Permalink: ../19d59133-7a9b-4d9f-a439-201d143bdb5f@gmail.com/
Also on: postgresql.org/message-id/19d59133-7a9b-4d9f-a439-201d143bdb5f@gmail.com
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: pierre.forstmann@gmail.com, pgsql-bugs@lists.postgresql.org, hackerzheng666@gmail.com
Subject: Re: BUG #19634: Hash partition with large MODULUS causes "invalid memory alloc request size"
In-Reply-To: <19d59133-7a9b-4d9f-a439-201d143bdb5f@gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox