agora inbox for pgsql-bugs@postgresql.org  
help / color / mirror / Atom feed
From: Alexander Lakhin <exclusion@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
To: Andrey Rachitskiy <pl0h0yp1@gmail.com>
Cc: michaelmalis2@gmail.com
Cc: pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #19595: Three memory-safety defects in src/backend/tsearch/spell.c (dictionary loader), PG 18.3
Date: Sun, 2 Aug 2026 23:00:01 +0300
Message-ID: <0f3ddeb5-0dbd-479c-9d0e-ae254758e624@gmail.com> (raw)
In-Reply-To: <325748.1785691547@sss.pgh.pa.us>
References: <19595-7dc18b4e212c4757@postgresql.org>
	<CAB8bMiun+cTqTnv-cTfxvTbnOLxWunRgyZeUZ88YMSLLXub4mg@mail.gmail.com>
	<325748.1785691547@sss.pgh.pa.us>

Hello Tom,

02.08.2026 20:25, Tom Lane wrote:
> Andrey Rachitskiy<pl0h0yp1@gmail.com> writes:
>> Hi, Michael!
>> Patch attached.
> I pushed these code changes with one minor tweak: adjusting the
> new error message in NIImportOOAffixes to look more like the
> existing one about too many aliases.
>
> I left out the test cases.  I don't think we need them, and
> I certainly don't think we want to install intentionally-broken
> files as sample data, as this patch would have done.

I'm not sure it's directly related to this bug report, but maybe you'd
like to fix one more memory-safety defect in tsearch in passing...

With the oom-simulation patch applied, the following script:
for i in {1..10}; do
echo "
SELECT COUNT(*) FROM pg_ts_dict;

CREATE TEXT SEARCH DICTIONARY thesaurus (Template=thesaurus, DictFile=thesaurus_sample, Dictionary=english_stem);

CREATE TEXT SEARCH CONFIGURATION tst (COPY=english);
SELECT to_tsvector('tst', 'Test test');

DROP TEXT SEARCH CONFIGURATION tst;
DROP TEXT SEARCH DICTIONARY thesaurus;
" | psql

grep 'was terminated' server.log && break;
done

fails for me as below:
2026-08-02 19:48:45.625 UTC [560023] LOG:  client backend (PID 560036) was terminated by signal 11: Segmentation fault

Core was generated by `postgres: law regression [local] SELECT                        '.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055aecffd519e in MemoryContextSetIdentifier (context=0x7f7f7f7f7f7f7f7f, id=0x0) at mcxt.c:667
667             Assert(MemoryContextIsValid(context));
(gdb) bt
#0  0x000055aecffd519e in MemoryContextSetIdentifier (context=0x7f7f7f7f7f7f7f7f, id=0x0) at mcxt.c:667
#1  0x000055aecff863c1 in lookup_ts_dictionary_cache (dictId=13336) at ts_cache.c:307
#2  0x000055aecfd87f00 in LexizeExec (ld=0x7ffe75617c20, correspondLexem=0x0) at ts_parse.c:204
#3  0x000055aecfd88741 in parsetext (cfgId=16385, prs=0x7ffe75617cc0, buf=0x55aeee42bba4 "Test test~\177\1770", 
buflen=9) at ts_parse.c:402
#4  0x000055aecfd8667d in to_tsvector_byid (fcinfo=0x55aeee5188c0) at to_tsany.c:260
#5  0x000055aecfa2a399 in ExecInterpExpr (state=0x55aeee5187e0, econtext=0x55aeee518d20, isnull=0x7ffe75618064) at 
execExprInterp.c:1011
#6  0x000055aecfa2cf0b in ExecInterpExprStillValid (state=0x55aeee5187e0, econtext=0x55aeee518d20, 
isNull=0x7ffe75618064) at execExprInterp.c:2309
#7  0x000055aecfbfba26 in ExecEvalExprSwitchContext (state=0x55aeee5187e0, econtext=0x55aeee518d20, isNull=0x7ffe75618064)
     at ../../../../src/include/executor/executor.h:452

Plain `make check` triggers similar crashes as well...

Best regards,
Alexander

Attachments:

  [text/x-patch] lookup_ts_dictionary_cache-oom.patch (2.4K, ../0f3ddeb5-0dbd-479c-9d0e-ae254758e624@gmail.com/2-lookup_ts_dictionary_cache-oom.patch)
  download | inline diff:
diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c
index 9e29f1386b0..dbbba687aaf 100644
--- a/src/backend/utils/cache/ts_cache.c
+++ b/src/backend/utils/cache/ts_cache.c
@@ -291,10 +291,12 @@ lookup_ts_dictionary_cache(Oid dictId)
 							HASH_ENTER, &found);
 			Assert(!found);		/* it wasn't there a moment ago */
 
+oom_prob = 0.5;
 			/* Create private memory context the first time through */
 			saveCtx = AllocSetContextCreate(CacheMemoryContext,
 											"TS dictionary",
 											ALLOCSET_SMALL_SIZES);
+oom_prob = 0;
 			MemoryContextCopyAndSetIdentifier(saveCtx, NameStr(dict->dictname));
 		}
 		else
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index 6a9ea367107..5883ec7fb99 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -51,6 +51,7 @@
 #include "utils/memutils.h"
 #include "utils/memutils_internal.h"
 #include "utils/memutils_memorychunk.h"
+#include "common/pg_prng.h"
 
 /*--------------------
  * Chunk freelist k holds chunks of size 1 << (k + ALLOC_MINBITS),
@@ -441,7 +442,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
 	 * Allocate the initial block.  Unlike other aset.c blocks, it starts with
 	 * the context header and its block header follows that.
 	 */
-	set = (AllocSet) malloc(firstBlockSize);
+	set = (pg_prng_double(&pg_global_prng_state) < oom_prob) ? NULL : (AllocSet) malloc(firstBlockSize);
 	if (set == NULL)
 	{
 		if (TopMemoryContext)
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 930fc457328..af050ed870d 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -46,6 +46,7 @@
 #include "utils/memutils_internal.h"
 #include "utils/memutils_memorychunk.h"
 
+double oom_prob = 0;
 
 static void BogusFree(void *pointer);
 static void *BogusRealloc(void *pointer, Size size, int flags);
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index 0e934158b60..90033ddc5a3 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -163,5 +163,6 @@ extern char *pchomp(const char *in);
 /* sprintf into a palloc'd buffer --- these are in psprintf.c */
 extern char *psprintf(const char *fmt, ...) pg_attribute_printf(1, 2);
 extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0);
+extern double oom_prob;
 
 #endif							/* PALLOC_H */


view thread (15+ messages)  latest in thread

Message-ID: <0f3ddeb5-0dbd-479c-9d0e-ae254758e624@gmail.com>
Permalink:  ../0f3ddeb5-0dbd-479c-9d0e-ae254758e624@gmail.com/
Also on:    postgresql.org/message-id/0f3ddeb5-0dbd-479c-9d0e-ae254758e624@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: exclusion@gmail.com, tgl@sss.pgh.pa.us, pl0h0yp1@gmail.com, michaelmalis2@gmail.com, pgsql-bugs@lists.postgresql.org
  Subject: Re: BUG #19595: Three memory-safety defects in src/backend/tsearch/spell.c (dictionary loader), PG 18.3
  In-Reply-To: <0f3ddeb5-0dbd-479c-9d0e-ae254758e624@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