From 09d37fa4f762f35f2e679ee00ce8da4fe0afc40e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Nordstr=C3=B6m?= Date: Tue, 14 Jul 2020 12:32:19 +0200 Subject: [PATCH] Fix memory issues when scanning chunk constraints A function to lookup the name of a chunk constraint returned a pointer to string without first copying the string into a safe memory context. This probably worked by chance because everything in the scan function ran in the current memory context, including the deforming of the tuple. However, returning pointers to data in deformed tuples can easily cause memory corruption with the introduction of other changes (such as improved memory management). This memory issue is fixed by explicitly reallocating the string in the memory context that should be used for any returned data. Changes are also made to avoid unnecessarily deforming tuples multiple times in the same scan function. --- src/chunk_constraint.c | 46 +++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/src/chunk_constraint.c b/src/chunk_constraint.c index 344fdece9..f7ffcdd48 100644 --- a/src/chunk_constraint.c +++ b/src/chunk_constraint.c @@ -647,28 +647,10 @@ ts_chunk_constraint_create_on_chunk(Chunk *chunk, Oid constraint_oid) static bool hypertable_constraint_matches_tuple(TupleInfo *ti, const char *hypertable_constraint_name) { - bool nulls[Natts_chunk_constraint]; - Datum values[Natts_chunk_constraint]; - bool should_free; - HeapTuple tuple = ts_scanner_fetch_heap_tuple(ti, false, &should_free); - const char *constrname; - bool matches = false; + bool isnull; + Datum name = slot_getattr(ti->slot, Anum_chunk_constraint_hypertable_constraint_name, &isnull); - heap_deform_tuple(tuple, ti->slot->tts_tupleDescriptor, values, nulls); - - if (!nulls[AttrNumberGetAttrOffset(Anum_chunk_constraint_hypertable_constraint_name)]) - { - constrname = NameStr(*DatumGetName( - values[AttrNumberGetAttrOffset(Anum_chunk_constraint_hypertable_constraint_name)])); - - if (strcmp(hypertable_constraint_name, constrname) == 0) - matches = true; - } - - if (should_free) - heap_freetuple(tuple); - - return matches; + return !isnull && namestrcmp(DatumGetName(name), hypertable_constraint_name) == 0; } static void @@ -910,20 +892,24 @@ ts_chunk_constraint_get_name_from_hypertable_constraint(Oid chunk_relid, init_scan_by_chunk_id(&iterator, DatumGetInt32(chunk_id)); ts_scanner_foreach(&iterator) { - bool nulls[Natts_chunk_constraint]; - Datum values[Natts_chunk_constraint]; - bool should_free; - HeapTuple tuple = ts_scan_iterator_fetch_heap_tuple(&iterator, false, &should_free); + TupleInfo *ti = ts_scan_iterator_tuple_info(&iterator); + MemoryContext oldmctx; + bool isnull; + Datum datum; + char *name; - if (!hypertable_constraint_matches_tuple(ts_scan_iterator_tuple_info(&iterator), - hypertable_constraint_name)) + if (!hypertable_constraint_matches_tuple(ti, hypertable_constraint_name)) continue; - heap_deform_tuple(tuple, ts_scan_iterator_tupledesc(&iterator), values, nulls); + datum = slot_getattr(ti->slot, Anum_chunk_constraint_constraint_name, &isnull); + Assert(!isnull); + oldmctx = MemoryContextSwitchTo(ti->mctx); + name = pstrdup(NameStr(*DatumGetName(datum))); + MemoryContextSwitchTo(oldmctx); ts_scan_iterator_close(&iterator); - return NameStr( - *DatumGetName(values[AttrNumberGetAttrOffset(Anum_chunk_constraint_constraint_name)])); + + return name; } return NULL; }