From 86e8e8042dbcea6aaeef0aa38247c77a1b6f3f09 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Fri, 15 Sep 2017 18:26:29 +1200 Subject: [PATCH] Fix crash in shared_record_typmod_registry_worker_detach(). It's not safe to access memory in the per-session DSA area in the per-session DSM segment's detach hook, because it might happen to point to another segment that has already been unmapped. A bugfix for commit cc5f81366c36b3dd8f02bd9be1cf75b2cc8482bd, per buildfarm. Author: Thomas Munro Discussion: https://postgr.es/m/E1dsguX-00056N-9x%40gemulon.postgresql.org --- src/backend/utils/cache/typcache.c | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index 9b94f1b3c39..b4e43705a0c 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -2389,33 +2389,13 @@ shared_record_typmod_registry_worker_detach(dsm_segment *segment, Datum datum) */ if (RecordCacheArray != NULL) { - int32 i; - - for (i = 0; i < RecordCacheArrayLen; ++i) - { - if (RecordCacheArray[i] != NULL) - { - TupleDesc tupdesc = RecordCacheArray[i]; - - /* - * Pointers to tuple descriptors in shared memory are not - * reference counted, so we are not responsible for freeing - * them. They'll survive as long as the shared session - * exists, which should be as long as the owning leader - * backend exists. In theory we do need to free local - * reference counted tuple descriptors however, and we can't - * do that with DescTupleDescRefCount() because we aren't - * using a resource owner. In practice we don't expect to - * find any non-shared TupleDesc object in a worker. - */ - if (tupdesc->tdrefcount != -1) - { - Assert(tupdesc->tdrefcount > 0); - if (--tupdesc->tdrefcount == 0) - FreeTupleDesc(tupdesc); - } - } - } + /* + * XXX If we do actually support the reuse of workers in future, we + * might want to consider resetting a memory context holding + * session-specific cache data. For now, the following is somewhat + * theoretical, but we don't want to retain any pointers into the + * shared session we're detaching from as a matter of principle. + */ pfree(RecordCacheArray); RecordCacheArray = NULL; } -- 2.13.2