]> granicus.if.org Git - postgresql/commitdiff
Plug race in dsa_attach.
authorRobert Haas <rhaas@postgresql.org>
Wed, 29 Mar 2017 13:44:29 +0000 (09:44 -0400)
committerRobert Haas <rhaas@postgresql.org>
Wed, 29 Mar 2017 13:48:39 +0000 (09:48 -0400)
With sufficiently bad luck, it was possible for a parallel worker to
attempt attach to a DSA area after all other backends have detached
from it, which is not legal.  If the worker had waited a little longer
to get started, the DSM itself would have been destroyed, which is why
this wasn't noticed before.

Thomas Munro, per a report from Andreas Seltenreich

Discussion: http://postgr.es/m/87h92g83t3.fsf@credativ.de

src/backend/utils/mmgr/dsa.c

index 6d5d12a6c9deff5b6c0139cd48901f930aa630ad..d08317249bbe1aed1d3618c17a013dee8ba5dc1f 100644 (file)
@@ -1314,6 +1314,13 @@ attach_internal(void *place, dsm_segment *segment, dsa_handle handle)
 
        /* Bump the reference count. */
        LWLockAcquire(DSA_AREA_LOCK(area), LW_EXCLUSIVE);
+       if (control->refcnt == 0)
+       {
+               /* We can't attach to a DSA area that has already been destroyed. */
+               ereport(ERROR,
+                               (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+                                errmsg("could not attach to dsa_area")));
+       }
        ++control->refcnt;
        LWLockRelease(DSA_AREA_LOCK(area));