From: Alexander Lakhin <exclusion@gmail.com>
To: pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #17950: Incorrect memory access in gtsvector_picksplit()
Date: Sat, 17 Jun 2023 17:00:00 +0300
Message-ID: <da453149-fa9e-67fc-fbce-80cca399bce5@gmail.com> (raw)
In-Reply-To: <17950-6c80a8d2b94ec695@postgresql.org>
References: <17950-6c80a8d2b94ec695@postgresql.org>
29.05.2023 23:00, PG Bug reporting form wrote:
> The following bug has been logged on the website:
>
> Bug reference: 17950
I managed to reduce the reproducer to the following:
CREATE TABLE tst(t tsvector);
INSERT INTO tst SELECT array_to_string(array(SELECT 'a' || x::text FROM generate_series(1, 125) x), ' ')::tsvector FROM
generate_series(1, 3000);
INSERT INTO tst SELECT '' FROM generate_series(1, 100);
CREATE INDEX gistidx ON tst USING gist (t tsvector_ops(siglen=1));
(Sorry for the previous messy script.)
A trivial fix for the issue is attached.
BTW, when looking at the index contents (page 0) using pageinspect, I saw:
itemoffset | ctid | itemlen | dead | keys
------------+-------------+---------+------+-----------------------------------
1 | (367,65535) | 16 | f | (a)=("0 true bits, 0 false bits")
2 | (368,65535) | 16 | f | (a)=("0 true bits, 0 false bits")
The text describing keys looks confusing, just as if siglen was 0, but it's
not the case.
This is explained by the code:
int siglen = GETSIGLEN(key);
int cnttrue = (ISALLTRUE(key)) ? SIGLENBIT(siglen) : sizebitvec(GETSIGN(key), siglen);
sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT(siglen) - cnttrue);
When ISALLTRUE, the code tries to calculate bit count from siglen, but
siglen is 0 in this case.
So maybe fix it in passing too...
Best regards,
Alexander
Attachments:
[text/x-patch] v1-01-fix-gtsvector_picksplit.patch (718B, ../da453149-fa9e-67fc-fbce-80cca399bce5@gmail.com/2-v1-01-fix-gtsvector_picksplit.patch)
download | inline diff:diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.cindex f0cd2866ff..12a4111e99 100644--- a/src/backend/utils/adt/tsgistidx.c+++ b/src/backend/utils/adt/tsgistidx.c@@ -730,7 +730,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
size_alpha = SIGLENBIT(siglen) -
sizebitvec((cache[j].allistrue) ?
GETSIGN(datum_l) :
- GETSIGN(cache[j].sign),+ cache[j].sign,
siglen);
}
else
@@ -744,7 +744,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
size_beta = SIGLENBIT(siglen) -
sizebitvec((cache[j].allistrue) ?
GETSIGN(datum_r) :
- GETSIGN(cache[j].sign),+ cache[j].sign,
siglen);
}
else
[text/x-patch] v1-02-fix-gtsvectorout.patch (836B, ../da453149-fa9e-67fc-fbce-80cca399bce5@gmail.com/3-v1-02-fix-gtsvectorout.patch)
download | inline diff:diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.cindex 12a4111e99..2722c02457 100644--- a/src/backend/utils/adt/tsgistidx.c+++ b/src/backend/utils/adt/tsgistidx.c@@ -115,10 +115,15 @@ gtsvectorout(PG_FUNCTION_ARGS)
sprintf(outbuf, ARROUTSTR, (int) ARRNELEM(key));
else
{
- int siglen = GETSIGLEN(key);- int cnttrue = (ISALLTRUE(key)) ? SIGLENBIT(siglen) : sizebitvec(GETSIGN(key), siglen);+ if (ISALLTRUE(key))+ sprintf(outbuf, "all true bits");+ else+ {+ int siglen = GETSIGLEN(key);+ int cnttrue = (ISALLTRUE(key)) ? SIGLENBIT(siglen) : sizebitvec(GETSIGN(key), siglen);- sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT(siglen) - cnttrue);+ sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT(siglen) - cnttrue);+ }
}
PG_FREE_IF_COPY(key, 0);
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: exclusion@gmail.com, pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #17950: Incorrect memory access in gtsvector_picksplit()
In-Reply-To: <da453149-fa9e-67fc-fbce-80cca399bce5@gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox