Validate ltree siglen GiST option to be int-aligned
authorAlexander Korotkov
Sun, 23 Apr 2023 10:58:25 +0000 (13:58 +0300)
committerAlexander Korotkov
Sun, 23 Apr 2023 11:31:11 +0000 (14:31 +0300)
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

contrib/ltree/expected/ltree.out
contrib/ltree/ltree_gist.c
contrib/ltree/sql/ltree.sql
doc/src/sgml/ltree.sgml

index c6d8f3ef75e6f44d3f4ae7b1128bca57a7edcb66..28c321a4cf1c8e1e79a3027c2afec32614698aaf 100644 (file)
@@ -7821,10 +7821,15 @@ SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
 drop index tstidx;
 create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=0));
 ERROR:  value 0 out of bounds for option "siglen"
-DETAIL:  Valid values are between "1" and "2024".
+DETAIL:  Valid values are between "4" and "2024".
 create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2025));
 ERROR:  value 2025 out of bounds for option "siglen"
-DETAIL:  Valid values are between "1" and "2024".
+DETAIL:  Valid values are between "4" and "2024".
+create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2028));
+ERROR:  value 2028 out of bounds for option "siglen"
+DETAIL:  Valid values are between "4" and "2024".
+create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2019));
+ERROR:  siglen value must be a multiple of 4
 create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2024));
 SELECT count(*) FROM ltreetest WHERE t <  '12.3';
  count 
index d384e1f5762d89e473b328b29cdd838e594e57c5..f5b4155594df0393cb90dd8869f90fdd66faf342 100644 (file)
@@ -716,6 +716,18 @@ ltree_consistent(PG_FUNCTION_ARGS)
    PG_RETURN_BOOL(res);
 }
 
+static void
+ltree_gist_relopts_validator(void *parsed_options, relopt_value *vals,
+                            int nvals)
+{
+   LtreeGistOptions *options = (LtreeGistOptions *) parsed_options;
+
+   if (options->siglen != INTALIGN(options->siglen))
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("siglen value must be a multiple of %d", ALIGNOF_INT)));
+}
+
 Datum
 ltree_gist_options(PG_FUNCTION_ARGS)
 {
@@ -724,8 +736,11 @@ ltree_gist_options(PG_FUNCTION_ARGS)
    init_local_reloptions(relopts, sizeof(LtreeGistOptions));
    add_local_int_reloption(relopts, "siglen",
                            "signature length in bytes",
-                           LTREE_SIGLEN_DEFAULT, 1, LTREE_SIGLEN_MAX,
+                           LTREE_SIGLEN_DEFAULT,
+                           INTALIGN(1),
+                           LTREE_SIGLEN_MAX,
                            offsetof(LtreeGistOptions, siglen));
+   register_reloptions_validator(relopts, ltree_gist_relopts_validator);
 
    PG_RETURN_VOID();
 }
index bf733ed17b9332d350d218b157ae86e55e2b522e..2a612e347de81b3e16f97a0b0ae1cffc2c5d6695 100644 (file)
@@ -325,6 +325,8 @@ SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
 drop index tstidx;
 create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=0));
 create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2025));
+create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2028));
+create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2019));
 create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2024));
 
 SELECT count(*) FROM ltreetest WHERE t <  '12.3';
index 436be76bfaa4162e0bce095c264b954e85995a55..e7b4cdec17d4d6cb08fd6c3d123bcee2a16dd52a 100644 (file)
@@ -636,7 +636,8 @@ Europe & Russia*@ & !Transportation
      path labels as a bitmap signature.  Its optional integer parameter
      siglen determines the
      signature length in bytes.  The default signature length is 8 bytes.
-     Valid values of signature length are between 1 and 2024 bytes.  Longer
+     The length must be a positive multiple of int alignment
+     (4 bytes on most machines)) up to 2024.  Longer
      signatures lead to a more precise search (scanning a smaller fraction of the index and
      fewer heap pages), at the cost of a larger index.