Thread
Commits
-
Fix use-after-free with multirange types in CREATE TYPE
- 922e15c47647 14.1 landed
- 5b0e7fe1d672 15.0 landed
-
Bug in DefineRange() with multiranges
Sergey Shinderuk <s.shinderuk@postgrespro.ru> — 2021-10-04T17:09:28Z
Hi, My colleague, Alex Kozhemyakin, stumbled upon a bug in DefineRange(). The problem is here: @@ -1707,7 +1707,6 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt) /* Create cast from the range type to its multirange type */ CastCreate(typoid, multirangeOid, castFuncOid, 'e', 'f', DEPENDENCY_INTERNAL); - pfree(multirangeTypeName); pfree(multirangeArrayName); return address; Given a query create type textrange1 as range(subtype=text, multirange_type_name=multirange_of_text, collation="C"); the string "multirange_of_text" in the parse tree is erroneously pfree'd. The corrupted parse tree is then passed to event triggers. There is another branch in DefineRange() that genereates a multirange type name which is fine to free. I wonder what is the proper fix. Just drop pfree() altogether or add pstrdup() instead? I see that makeMultirangeTypeName() doesn't bother freeing its buf. Here is a gdb session demonstating the bug: Breakpoint 1, ProcessUtilitySlow (pstate=0x5652e80c7730, pstmt=0x5652e80a6a40, queryString=0x5652e80a5790 "create type textrange1 as range(subtype=text, multirange_type_name=multirange_of_text, collation=\"C\");", context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, qc=0x7ffe835b4be0, dest=<optimized out>) at /pgwork/REL_14_STABLE/src/src/backend/tcop/utility.c:1621 1621 address = DefineRange((CreateRangeStmt *) parsetree); (gdb) p *(Value *)((TypeName *)((DefElem *)((CreateRangeStmt *)parsetree)->params->elements[1].ptr_value)->arg)->names->elements[0].ptr_value $1 = {type = T_String, val = {ival = -401972176, str = 0x5652e80a6430 "multirange_of_text"}} (gdb) n 1900 if (!commandCollected) (gdb) p *(Value *)((TypeName *)((DefElem *)((CreateRangeStmt *)parsetree)->params->elements[1].ptr_value)->arg)->names->elements[0].ptr_value $2 = {type = T_String, val = {ival = -401972176, str = 0x5652e80a6430 '\177' <repeats 32 times>, "\020"}} Regards, -- Sergey Shinderuk https://postgrespro.com/ -
Re: Bug in DefineRange() with multiranges
Peter Eisentraut <peter.eisentraut@enterprisedb.com> — 2021-10-10T17:12:30Z
On 04.10.21 19:09, Sergey Shinderuk wrote: > I wonder what is the proper fix. Just drop pfree() altogether or add > pstrdup() instead? I see that makeMultirangeTypeName() doesn't bother > freeing its buf. I think removing the pfree()s is a correct fix.
-
Re: Bug in DefineRange() with multiranges
Sergey Shinderuk <s.shinderuk@postgrespro.ru> — 2021-10-12T05:52:29Z
On 10.10.2021 20:12, Peter Eisentraut wrote: > On 04.10.21 19:09, Sergey Shinderuk wrote: >> I wonder what is the proper fix. Just drop pfree() altogether or add >> pstrdup() instead? I see that makeMultirangeTypeName() doesn't bother >> freeing its buf. > > I think removing the pfree()s is a correct fix. > Thanks, here is a patch. -- Sergey Shinderuk https://postgrespro.com/
-
Re: Bug in DefineRange() with multiranges
Michael Paquier <michael@paquier.xyz> — 2021-10-13T04:21:05Z
On Tue, Oct 12, 2021 at 08:52:29AM +0300, Sergey Shinderuk wrote: > Thanks, here is a patch. Looks fine seen from here, so I'll apply shortly. I was initially tempted to do pstrdup() on the object name returned by QualifiedNameGetCreationNamespace(), but just removing the pfree() is simpler. I got to wonder about similar mistakes from the other callers of QualifiedNameGetCreationNamespace(), so I have double-checked but nothing looks wrong. -- Michael
-
Re: Bug in DefineRange() with multiranges
Sergey Shinderuk <s.shinderuk@postgrespro.ru> — 2021-10-13T08:35:34Z
On 13.10.2021 07:21, Michael Paquier wrote: > Looks fine seen from here, so I'll apply shortly. Thank you! -- Sergey Shinderuk https://postgrespro.com/