• Tom Lane's avatar
    Fix pfree-of-already-freed-tuple when rescanning a GiST index-only scan. · 3f074845
    Tom Lane authored
    GiST's getNextNearest() function attempts to pfree the previously-returned
    tuple if any (that is, scan->xs_hitup in HEAD, or scan->xs_itup in older
    branches).  However, if we are rescanning a plan node after ending a
    previous scan early, those tuple pointers could be pointing to garbage,
    because they would be pointing into the scan's pageDataCxt or queueCxt
    which has been reset.  In a debug build this reliably results in a crash,
    although I think it might sometimes accidentally fail to fail in
    production builds.
    
    To fix, clear the pointer field anyplace we reset a context it might
    be pointing into.  This may be overkill --- I think probably only the
    queueCxt case is involved in this bug, so that resetting in gistrescan()
    would be sufficient --- but dangling pointers are generally bad news,
    so let's avoid them.
    
    Another plausible answer might be to just not bother with the pfree in
    getNextNearest().  The reconstructed tuples would go away anyway in the
    context resets, and I'm far from convinced that freeing them a bit earlier
    really saves anything meaningful.  I'll stick with the original logic in
    this patch, but if we find more problems in the same area we should
    consider that approach.
    
    Per bug #14641 from Denis Smirnov.  Back-patch to 9.5 where this
    logic was introduced.
    
    Discussion: https://postgr.es/m/20170504072034.24366.57688@wrigleys.postgresql.org
    3f074845
gistget.c 21.6 KB