aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrh <>2025-02-03 23:19:42 +0000
committerdrh <>2025-02-03 23:19:42 +0000
commit51dd67080a1bbf47d4020eb01b8111fe3188fa68 (patch)
treedd8e5e7aa4aabc053869eb0ad8b35ecd552a9ca4
parent0d9f2a15f236dd87b05d33c8c1e09df1f4612b75 (diff)
downloadsqlite-51dd67080a1bbf47d4020eb01b8111fe3188fa68.tar.gz
sqlite-51dd67080a1bbf47d4020eb01b8111fe3188fa68.zip
Fix a potential UAF in FTS3.
FossilOrigin-Name: 75f3d87448793fc7fd68d817874d561842e029a2d6c1ea4abcec39764cd38469
-rw-r--r--ext/fts3/fts3.c18
-rw-r--r--ext/fts3/fts3Int.h1
-rw-r--r--ext/fts3/fts3_snippet.c21
-rw-r--r--manifest16
-rw-r--r--manifest.uuid2
5 files changed, 49 insertions, 9 deletions
diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c
index e58f256a4..2b2c3b8d2 100644
--- a/ext/fts3/fts3.c
+++ b/ext/fts3/fts3.c
@@ -5788,6 +5788,24 @@ static void fts3EvalRestart(
}
/*
+** Expression node pExpr is an MSR phrase. This function restarts pExpr
+** so that it is a regular phrase query, not an MSR. SQLITE_OK is returned
+** if successful, or an SQLite error code otherwise.
+*/
+int sqlite3Fts3MsrCancel(Fts3Cursor *pCsr, Fts3Expr *pExpr){
+ int rc = SQLITE_OK;
+ if( pExpr->bEof==0 ){
+ i64 iDocid = pExpr->iDocid;
+ fts3EvalRestart(pCsr, pExpr, &rc);
+ while( rc==SQLITE_OK && pExpr->iDocid!=iDocid ){
+ fts3EvalNextRow(pCsr, pExpr, &rc);
+ if( pExpr->bEof ) rc = FTS_CORRUPT_VTAB;
+ }
+ }
+ return rc;
+}
+
+/*
** After allocating the Fts3Expr.aMI[] array for each phrase in the
** expression rooted at pExpr, the cursor iterates through all rows matched
** by pExpr, calling this function for each row. This function increments
diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h
index 3b236faf4..77e6737af 100644
--- a/ext/fts3/fts3Int.h
+++ b/ext/fts3/fts3Int.h
@@ -640,6 +640,7 @@ int sqlite3Fts3MsrIncrNext(
int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **);
int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
+int sqlite3Fts3MsrCancel(Fts3Cursor*, Fts3Expr*);
/* fts3_tokenize_vtab.c */
int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*));
diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c
index 80f62eb3b..c79cca4a6 100644
--- a/ext/fts3/fts3_snippet.c
+++ b/ext/fts3/fts3_snippet.c
@@ -1587,6 +1587,21 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
}
/*
+** If expression pExpr is a phrase expression that uses an MSR query,
+** restart it as a regular, non-incremental query. Return SQLITE_OK
+** if successful, or an SQLite error code otherwise.
+*/
+static int fts3ExprRestartIfCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
+ TermOffsetCtx *p = (TermOffsetCtx*)ctx;
+ int rc = SQLITE_OK;
+ if( pExpr->pPhrase && pExpr->pPhrase->bIncr ){
+ rc = sqlite3Fts3MsrCancel(p->pCsr, pExpr);
+ pExpr->pPhrase->bIncr = 0;
+ }
+ return rc;
+}
+
+/*
** Implementation of offsets() function.
*/
void sqlite3Fts3Offsets(
@@ -1622,6 +1637,12 @@ void sqlite3Fts3Offsets(
sCtx.iDocid = pCsr->iPrevId;
sCtx.pCsr = pCsr;
+ /* If a query restart will be required, do it here, rather than later of
+ ** after pointers to poslist buffers that may be invalidated by a restart
+ ** have been saved. */
+ rc = sqlite3Fts3ExprIterate(pCsr->pExpr, fts3ExprRestartIfCb, (void*)&sCtx);
+ if( rc!=SQLITE_OK ) goto offsets_out;
+
/* Loop through the table columns, appending offset information to
** string-buffer res for each column.
*/
diff --git a/manifest b/manifest
index 678cea2b4..abc313c53 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\sParse.addrExplain\sfield\sis\snever\seven\sif\sSQLITE_OMIT_EXPLAIN\sis\sdefined.
-D 2025-02-03T21:04:21.029
+C Fix\sa\spotential\sUAF\sin\sFTS3.
+D 2025-02-03T23:19:42.890
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -78,16 +78,16 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c 9f8ce82bbf4ec0636e6170e58f17b04817fa4c39b2d5126ac06f005d485f6d5e
+F ext/fts3/fts3.c b840ee915a6fb36571e3fe3c096e8a481a4a9cd8a35199a1b976b132b9f84ad3
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
-F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682
+F ext/fts3/fts3Int.h 2fe7c76dfd7d46dff964d17d3f4c53bca2116cf5d6252552ebbc22e38afdf4e0
F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3
F ext/fts3/fts3_expr.c 365849a2a1185e19028a9db2d9f1ea63efe909a3a6aca7ec86fc26a13a60bd58
F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8
-F ext/fts3/fts3_snippet.c c38117a2e4dcc9485a170a57a6134423955247b230fef7073c46fa9c51239540
+F ext/fts3/fts3_snippet.c 92196bd5941be0455f2c7e51c2f8280df49c7feb0615a0d1d4d045f2dcf60713
F ext/fts3/fts3_term.c 6a96027ad364001432545fe43322b6af04ed28bb5619ec51af1f59d0710d6d69
F ext/fts3/fts3_test.c 7a9cb3d61774134211bf4bfdf1adcb581a1a0377f2d050a121ae7ab44baef0e3
F ext/fts3/fts3_tokenize_vtab.c 7fd9ef364f257b97218b9c331f2378e307375c592f70fd541f714e747d944962
@@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 408fa57f048e05a261fb62b45ae44b8a97c97fc01e3776124cbef6595df579d4
-R 19f75289781fc56c637c4500001f3f36
+P 5d81a984c6aabb9fa9180efde8ca942b40f1ec18ff5a89f2fbb1252734f051d3
+R f1017abf167769f99bdff3069bfe9e53
U drh
-Z 6ac8bc953e7e25c0d28f52d6abec8109
+Z dd1d75c4a0f7bb799c129e975f1e95da
# Remove this line to create a well-formed Fossil manifest.
diff --git a/manifest.uuid b/manifest.uuid
index 395847753..f7f780615 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-5d81a984c6aabb9fa9180efde8ca942b40f1ec18ff5a89f2fbb1252734f051d3
+75f3d87448793fc7fd68d817874d561842e029a2d6c1ea4abcec39764cd38469