]> granicus.if.org Git - postgresql/commitdiff
Initialize padding bytes in btree_gist varbit support.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 13 May 2014 11:16:28 +0000 (14:16 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 13 May 2014 12:27:21 +0000 (15:27 +0300)
The code expands a varbit gist leaf key to a node key by copying the bit
data twice in a varlen datum, as both the lower and upper key. The lower key
was expanded to INTALIGN size, but the padding bytes were not initialized.
That's a problem because when the lower/upper keys are compared, the padding
bytes are used compared too, when the values are otherwise equal. That could
lead to incorrect query results.

REINDEX is advised for any btree_gist indexes on bit or bit varying data
type, to fix any garbage padding bytes on disk.

Per Valgrind, reported by Andres Freund. Backpatch to all supported
versions.

contrib/btree_gist/btree_bit.c

index 5c0d198b09049e579d8016c0675496717a0c4d8b..0f6b70eb0ea6f9358792df46e6602f5627e25314 100644 (file)
@@ -83,10 +83,14 @@ static bytea *
 gbt_bit_xfrm(bytea *leaf)
 {
        bytea      *out = leaf;
-       int                     s = INTALIGN(VARBITBYTES(leaf) + VARHDRSZ);
-
-       out = palloc(s);
-       SET_VARSIZE(out, s);
+       int                     sz = VARBITBYTES(leaf) + VARHDRSZ;
+       int                     padded_sz = INTALIGN(sz);
+
+       out = (bytea *) palloc(padded_sz);
+       /* initialize the padding bytes to zero */
+       while (sz < padded_sz)
+               ((char *) out)[sz++] = 0;
+       SET_VARSIZE(out, padded_sz);
        memcpy((void *) VARDATA(out), (void *) VARBITS(leaf), VARBITBYTES(leaf));
        return out;
 }