Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8bbd0cc

Browse files
committed
Validate ltree siglen GiST option to be int-aligned
Unaligned siglen could lead to an unaligned access to subsequent key fields. Backpatch to 13, where opclass options were introduced. Reported-by: Alexander Lakhin Bug: 17847 Discussion: https://postgr.es/m/17847-171232970bea406b%40postgresql.org Reviewed-by: Tom Lane, Pavel Borisov, Alexander Lakhin Backpatch-through: 13
1 parent cd115c3 commit 8bbd0cc

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

contrib/ltree/expected/ltree.out

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7835,10 +7835,15 @@ SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
78357835
drop index tstidx;
78367836
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=0));
78377837
ERROR: value 0 out of bounds for option "siglen"
7838-
DETAIL: Valid values are between "1" and "2024".
7838+
DETAIL: Valid values are between "4" and "2024".
78397839
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2025));
78407840
ERROR: value 2025 out of bounds for option "siglen"
7841-
DETAIL: Valid values are between "1" and "2024".
7841+
DETAIL: Valid values are between "4" and "2024".
7842+
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2028));
7843+
ERROR: value 2028 out of bounds for option "siglen"
7844+
DETAIL: Valid values are between "4" and "2024".
7845+
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2019));
7846+
ERROR: siglen value must be a multiple of 4
78427847
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2024));
78437848
SELECT count(*) FROM ltreetest WHERE t < '12.3';
78447849
count

contrib/ltree/ltree_gist.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,18 @@ ltree_consistent(PG_FUNCTION_ARGS)
719719
PG_RETURN_BOOL(res);
720720
}
721721

722+
static void
723+
ltree_gist_relopts_validator(void *parsed_options, relopt_value *vals,
724+
int nvals)
725+
{
726+
LtreeGistOptions *options = (LtreeGistOptions *) parsed_options;
727+
728+
if (options->siglen != INTALIGN(options->siglen))
729+
ereport(ERROR,
730+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
731+
errmsg("siglen value must be a multiple of %d", ALIGNOF_INT)));
732+
}
733+
722734
Datum
723735
ltree_gist_options(PG_FUNCTION_ARGS)
724736
{
@@ -727,8 +739,11 @@ ltree_gist_options(PG_FUNCTION_ARGS)
727739
init_local_reloptions(relopts, sizeof(LtreeGistOptions));
728740
add_local_int_reloption(relopts, "siglen",
729741
"signature length in bytes",
730-
LTREE_SIGLEN_DEFAULT, 1, LTREE_SIGLEN_MAX,
742+
LTREE_SIGLEN_DEFAULT,
743+
INTALIGN(1),
744+
LTREE_SIGLEN_MAX,
731745
offsetof(LtreeGistOptions, siglen));
746+
register_reloptions_validator(relopts, ltree_gist_relopts_validator);
732747

733748
PG_RETURN_VOID();
734749
}

contrib/ltree/sql/ltree.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
331331
drop index tstidx;
332332
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=0));
333333
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2025));
334+
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2028));
335+
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2019));
334336
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2024));
335337

336338
SELECT count(*) FROM ltreetest WHERE t < '12.3';

doc/src/sgml/ltree.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,8 @@ Europe &amp; Russia*@ &amp; !Transportation
637637
path labels as a bitmap signature. Its optional integer parameter
638638
<literal>siglen</literal> determines the
639639
signature length in bytes. The default signature length is 8 bytes.
640-
Valid values of signature length are between 1 and 2024 bytes. Longer
640+
The length must be a positive multiple of <type>int</type> alignment
641+
(4 bytes on most machines)) up to 2024. Longer
641642
signatures lead to a more precise search (scanning a smaller fraction of the index and
642643
fewer heap pages), at the cost of a larger index.
643644
</para>

0 commit comments

Comments
 (0)