parent
f2d6883ed2
commit
d8da047b90
292
sqlite-3.26.0-fts_corrupt_db.patch
Normal file
292
sqlite-3.26.0-fts_corrupt_db.patch
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
Index: ext/fts3/fts3.c
|
||||||
|
==================================================================
|
||||||
|
--- ext/fts3/fts3.c
|
||||||
|
+++ ext/fts3/fts3.c
|
||||||
|
@@ -1819,11 +1819,11 @@
|
||||||
|
){
|
||||||
|
int rc = SQLITE_OK; /* Return code */
|
||||||
|
const char *zCsr = zNode; /* Cursor to iterate through node */
|
||||||
|
const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
|
||||||
|
char *zBuffer = 0; /* Buffer to load terms into */
|
||||||
|
- int nAlloc = 0; /* Size of allocated buffer */
|
||||||
|
+ i64 nAlloc = 0; /* Size of allocated buffer */
|
||||||
|
int isFirstTerm = 1; /* True when processing first term on page */
|
||||||
|
sqlite3_int64 iChild; /* Block id of child node to descend to */
|
||||||
|
|
||||||
|
/* Skip over the 'height' varint that occurs at the start of every
|
||||||
|
** interior node. Then load the blockid of the left-child of the b-tree
|
||||||
|
@@ -1857,18 +1857,18 @@
|
||||||
|
}
|
||||||
|
isFirstTerm = 0;
|
||||||
|
zCsr += fts3GetVarint32(zCsr, &nSuffix);
|
||||||
|
|
||||||
|
assert( nPrefix>=0 && nSuffix>=0 );
|
||||||
|
- if( &zCsr[nSuffix]>zEnd ){
|
||||||
|
+ if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
|
||||||
|
rc = FTS_CORRUPT_VTAB;
|
||||||
|
goto finish_scan;
|
||||||
|
}
|
||||||
|
- if( nPrefix+nSuffix>nAlloc ){
|
||||||
|
+ if( (i64)nPrefix+nSuffix>nAlloc ){
|
||||||
|
char *zNew;
|
||||||
|
- nAlloc = (nPrefix+nSuffix) * 2;
|
||||||
|
- zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
|
||||||
|
+ nAlloc = ((i64)nPrefix+nSuffix) * 2;
|
||||||
|
+ zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
|
||||||
|
if( !zNew ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
goto finish_scan;
|
||||||
|
}
|
||||||
|
zBuffer = zNew;
|
||||||
|
|
||||||
|
Index: ext/fts3/fts3_write.c
|
||||||
|
==================================================================
|
||||||
|
--- ext/fts3/fts3_write.c
|
||||||
|
+++ ext/fts3/fts3_write.c
|
||||||
|
@@ -1372,19 +1372,23 @@
|
||||||
|
|
||||||
|
/* Because of the FTS3_NODE_PADDING bytes of padding, the following is
|
||||||
|
** safe (no risk of overread) even if the node data is corrupted. */
|
||||||
|
pNext += fts3GetVarint32(pNext, &nPrefix);
|
||||||
|
pNext += fts3GetVarint32(pNext, &nSuffix);
|
||||||
|
- if( nPrefix<0 || nSuffix<=0
|
||||||
|
- || &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
|
||||||
|
+ if( nSuffix<=0
|
||||||
|
+ || (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
|
||||||
|
+ || nPrefix>pReader->nTermAlloc
|
||||||
|
){
|
||||||
|
return FTS_CORRUPT_VTAB;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if( nPrefix+nSuffix>pReader->nTermAlloc ){
|
||||||
|
- int nNew = (nPrefix+nSuffix)*2;
|
||||||
|
- char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
|
||||||
|
+ /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
|
||||||
|
+ ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
|
||||||
|
+ ** overflow - hence the (i64) casts. */
|
||||||
|
+ if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
|
||||||
|
+ i64 nNew = ((i64)nPrefix+nSuffix)*2;
|
||||||
|
+ char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
|
||||||
|
if( !zNew ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
pReader->zTerm = zNew;
|
||||||
|
pReader->nTermAlloc = nNew;
|
||||||
|
@@ -1402,11 +1406,11 @@
|
||||||
|
|
||||||
|
/* Check that the doclist does not appear to extend past the end of the
|
||||||
|
** b-tree node. And that the final byte of the doclist is 0x00. If either
|
||||||
|
** of these statements is untrue, then the data structure is corrupt.
|
||||||
|
*/
|
||||||
|
- if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
|
||||||
|
+ if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
|
||||||
|
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
|
||||||
|
){
|
||||||
|
return FTS_CORRUPT_VTAB;
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
@@ -3728,25 +3732,30 @@
|
||||||
|
if( bFirst==0 ){
|
||||||
|
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
|
||||||
|
}
|
||||||
|
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
|
||||||
|
|
||||||
|
+ if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
|
||||||
|
+ return SQLITE_CORRUPT_VTAB;
|
||||||
|
+ }
|
||||||
|
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
|
||||||
|
p->term.n = nPrefix+nSuffix;
|
||||||
|
p->iOff += nSuffix;
|
||||||
|
if( p->iChild==0 ){
|
||||||
|
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
|
||||||
|
+ if( (p->nNode-p->iOff)<p->nDoclist ){
|
||||||
|
+ return SQLITE_CORRUPT_VTAB;
|
||||||
|
+ }
|
||||||
|
p->aDoclist = &p->aNode[p->iOff];
|
||||||
|
p->iOff += p->nDoclist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( p->iOff<=p->nNode );
|
||||||
|
-
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Release all dynamic resources held by node-reader object *p.
|
||||||
|
|
||||||
|
ADDED test/fts3corrupt4.test
|
||||||
|
Index: test/fts3corrupt4.test
|
||||||
|
==================================================================
|
||||||
|
--- test/fts3corrupt4.test
|
||||||
|
+++ test/fts3corrupt4.test
|
||||||
|
@@ -0,0 +1,147 @@
|
||||||
|
+# 2006 September 9
|
||||||
|
+#
|
||||||
|
+# The author disclaims copyright to this source code. In place of
|
||||||
|
+# a legal notice, here is a blessing:
|
||||||
|
+#
|
||||||
|
+# May you do good and not evil.
|
||||||
|
+# May you find forgiveness for yourself and forgive others.
|
||||||
|
+# May you share freely, never taking more than you give.
|
||||||
|
+#
|
||||||
|
+#*************************************************************************
|
||||||
|
+# This file implements regression tests for SQLite library. The
|
||||||
|
+# focus of this script is testing the FTS3 module.
|
||||||
|
+#
|
||||||
|
+# $Id: fts3aa.test,v 1.1 2007/08/20 17:38:42 shess Exp $
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+set testdir [file dirname $argv0]
|
||||||
|
+source $testdir/tester.tcl
|
||||||
|
+set testprefix fts3corrupt4
|
||||||
|
+
|
||||||
|
+# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||||
|
+ifcapable !fts3 {
|
||||||
|
+ finish_test
|
||||||
|
+ return
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+do_execsql_test 1.0 {
|
||||||
|
+ BEGIN;
|
||||||
|
+ CREATE VIRTUAL TABLE ft USING fts3;
|
||||||
|
+ INSERT INTO ft VALUES('aback');
|
||||||
|
+ INSERT INTO ft VALUES('abaft');
|
||||||
|
+ INSERT INTO ft VALUES('abandon');
|
||||||
|
+ COMMIT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+proc blob {a} { binary decode hex $a }
|
||||||
|
+db func blob blob
|
||||||
|
+
|
||||||
|
+do_execsql_test 1.1 {
|
||||||
|
+ SELECT quote(root) FROM ft_segdir;
|
||||||
|
+} {X'0005616261636B03010200030266740302020003046E646F6E03030200'}
|
||||||
|
+
|
||||||
|
+do_execsql_test 1.2 {
|
||||||
|
+ UPDATE ft_segdir SET root = blob(
|
||||||
|
+ '0005616261636B03010200 FFFFFFFF0702 66740302020003046E646F6E03030200'
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+do_catchsql_test 1.3 {
|
||||||
|
+ SELECT * FROM ft WHERE ft MATCH 'abandon';
|
||||||
|
+} {1 {database disk image is malformed}}
|
||||||
|
+
|
||||||
|
+#-------------------------------------------------------------------------
|
||||||
|
+reset_db
|
||||||
|
+do_execsql_test 2.0.0 {
|
||||||
|
+ CREATE VIRTUAL TABLE ft USING fts3;
|
||||||
|
+ INSERT INTO ft(ft) VALUES('nodesize=32');
|
||||||
|
+}
|
||||||
|
+do_test 2.0.1 {
|
||||||
|
+ for {set i 0} {$i < 12} {incr i} {
|
||||||
|
+ execsql {
|
||||||
|
+ BEGIN;
|
||||||
|
+ INSERT INTO ft VALUES('abc' || $i);
|
||||||
|
+ INSERT INTO ft VALUES('abc' || $i || 'x' );
|
||||||
|
+ INSERT INTO ft VALUES('abc' || $i || 'xx' );
|
||||||
|
+ COMMIT
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ execsql {
|
||||||
|
+ SELECT count(*) FROM ft_segdir;
|
||||||
|
+ SELECT count(*) FROM ft_segments;
|
||||||
|
+ }
|
||||||
|
+} {12 0}
|
||||||
|
+
|
||||||
|
+do_execsql_test 2.1 {
|
||||||
|
+ INSERT INTO ft(ft) VALUES('merge=1,4');
|
||||||
|
+ SELECT count(*) FROM ft_segdir;
|
||||||
|
+ SELECT count(*) FROM ft_segments;
|
||||||
|
+} {12 3}
|
||||||
|
+
|
||||||
|
+do_execsql_test 2.2 {
|
||||||
|
+ SELECT quote(block) FROM ft_segments WHERE blockid=2
|
||||||
|
+} {X'00056162633130031F0200'}
|
||||||
|
+
|
||||||
|
+db func blob blob
|
||||||
|
+do_execsql_test 2.3.1 {
|
||||||
|
+ UPDATE ft_segments SET block =
|
||||||
|
+ blob('00056162633130031F0200 FFFFFFFF07FF55 66740302020003046E646F6E03030200')
|
||||||
|
+ WHERE blockid=2;
|
||||||
|
+} {}
|
||||||
|
+do_catchsql_test 2.3.2 {
|
||||||
|
+ INSERT INTO ft(ft) VALUES('merge=1,4');
|
||||||
|
+} {1 {database disk image is malformed}}
|
||||||
|
+
|
||||||
|
+do_execsql_test 2.4.1 {
|
||||||
|
+ UPDATE ft_segments SET block =
|
||||||
|
+ blob('00056162633130031F0200 02FFFFFFFF07 66740302020003046E646F6E03030200')
|
||||||
|
+ WHERE blockid=2;
|
||||||
|
+} {}
|
||||||
|
+do_catchsql_test 2.4.2 {
|
||||||
|
+ INSERT INTO ft(ft) VALUES('merge=1,4');
|
||||||
|
+} {1 {database disk image is malformed}}
|
||||||
|
+
|
||||||
|
+do_execsql_test 2.5.1 {
|
||||||
|
+ UPDATE ft_segments SET block =
|
||||||
|
+ blob('00056162633130031F0200 0202 6674 FFFFFF070302020003046E646F6E030200')
|
||||||
|
+ WHERE blockid=2;
|
||||||
|
+} {}
|
||||||
|
+do_catchsql_test 2.5.2 {
|
||||||
|
+ INSERT INTO ft(ft) VALUES('merge=1,4');
|
||||||
|
+} {1 {database disk image is malformed}}
|
||||||
|
+
|
||||||
|
+#-------------------------------------------------------------------------
|
||||||
|
+reset_db
|
||||||
|
+do_execsql_test 3.0.0 {
|
||||||
|
+ CREATE VIRTUAL TABLE ft USING fts3;
|
||||||
|
+ INSERT INTO ft(ft) VALUES('nodesize=32');
|
||||||
|
+}
|
||||||
|
+do_test 3.0.1 {
|
||||||
|
+ execsql BEGIN
|
||||||
|
+ for {set i 0} {$i < 20} {incr i} {
|
||||||
|
+ execsql { INSERT INTO ft VALUES('abc' || $i) }
|
||||||
|
+ }
|
||||||
|
+ execsql {
|
||||||
|
+ COMMIT;
|
||||||
|
+ SELECT count(*) FROM ft_segdir;
|
||||||
|
+ SELECT count(*) FROM ft_segments;
|
||||||
|
+ }
|
||||||
|
+} {1 5}
|
||||||
|
+
|
||||||
|
+do_execsql_test 3.1 {
|
||||||
|
+ SELECT quote(root) FROM ft_segdir
|
||||||
|
+} {X'0101056162633132040136030132030136'}
|
||||||
|
+
|
||||||
|
+db func blob blob
|
||||||
|
+do_execsql_test 3.2 {
|
||||||
|
+ UPDATE ft_segdir
|
||||||
|
+ SET root = blob('0101056162633132FFFFFFFF070236030132030136');
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+do_catchsql_test 3.1 {
|
||||||
|
+ SELECT * FROM ft WHERE ft MATCH 'abc20'
|
||||||
|
+} {1 {database disk image is malformed}}
|
||||||
|
+
|
||||||
|
+finish_test
|
||||||
|
+
|
||||||
|
+
|
||||||
|
|
||||||
|
Index: test/permutations.test
|
||||||
|
==================================================================
|
||||||
|
--- test/permutations.test
|
||||||
|
+++ test/permutations.test
|
||||||
|
@@ -260,10 +260,11 @@
|
||||||
|
fts3ae.test fts3af.test fts3ag.test fts3ah.test
|
||||||
|
fts3ai.test fts3aj.test fts3ak.test fts3al.test
|
||||||
|
fts3am.test fts3an.test fts3ao.test fts3atoken.test
|
||||||
|
fts3auto.test fts3aux1.test fts3aux2.test fts3b.test
|
||||||
|
fts3comp1.test fts3conf.test fts3corrupt2.test fts3corrupt.test
|
||||||
|
+ fts3corrupt4.test
|
||||||
|
fts3cov.test fts3c.test fts3defer2.test fts3defer3.test
|
||||||
|
fts3defer.test fts3drop.test fts3d.test fts3e.test
|
||||||
|
fts3expr2.test fts3expr3.test fts3expr4.test fts3expr5.test
|
||||||
|
fts3expr.test fts3fault2.test fts3fault.test fts3first.test
|
||||||
|
fts3join.test fts3malloc.test fts3matchinfo.test fts3near.test
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
Summary: Library that implements an embeddable SQL database engine
|
Summary: Library that implements an embeddable SQL database engine
|
||||||
Name: sqlite
|
Name: sqlite
|
||||||
Version: %{rpmver}
|
Version: %{rpmver}
|
||||||
Release: 4%{?dist}
|
Release: 5%{?dist}
|
||||||
License: Public Domain
|
License: Public Domain
|
||||||
Group: Applications/Databases
|
Group: Applications/Databases
|
||||||
URL: http://www.sqlite.org/
|
URL: http://www.sqlite.org/
|
||||||
@ -43,6 +43,8 @@ Patch10: sqlite-3.22.0-fts3rank-big-endian.patch
|
|||||||
Patch11: sqlite-3.22.0-walro2-filesize.patch
|
Patch11: sqlite-3.22.0-walro2-filesize.patch
|
||||||
# Upstream: https://www.sqlite.org/cgi/src/timeline?r=corrupt-schema
|
# Upstream: https://www.sqlite.org/cgi/src/timeline?r=corrupt-schema
|
||||||
Patch12: sqlite-3.22.0-corrupt-schema.patch
|
Patch12: sqlite-3.22.0-corrupt-schema.patch
|
||||||
|
# Upstream: https://www.sqlite.org/src/info/d44318f59044162e
|
||||||
|
Patch13: sqlite-3.26.0-fts_corrupt_db.patch
|
||||||
|
|
||||||
BuildRequires: ncurses-devel readline-devel glibc-devel
|
BuildRequires: ncurses-devel readline-devel glibc-devel
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
@ -150,6 +152,7 @@ This package contains the analysis program for %{name}.
|
|||||||
%patch10 -p0
|
%patch10 -p0
|
||||||
%patch11 -p0
|
%patch11 -p0
|
||||||
%patch12 -p0
|
%patch12 -p0
|
||||||
|
%patch13 -p0
|
||||||
|
|
||||||
autoconf # Rerun with new autoconf to add support for aarm64
|
autoconf # Rerun with new autoconf to add support for aarm64
|
||||||
|
|
||||||
@ -251,6 +254,9 @@ make test
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Dec 17 2018 Petr Kubat <pkubat@redhat.com> - 3.22.0-5
|
||||||
|
- Fixed fts3/4 corrupt database exploit (#1659677)
|
||||||
|
|
||||||
* Wed Mar 21 2018 Petr Kubat <pkubat@redhat.com> - 3.22.0-4
|
* Wed Mar 21 2018 Petr Kubat <pkubat@redhat.com> - 3.22.0-4
|
||||||
- Fixed CVE-2018-8740 (#1558809)
|
- Fixed CVE-2018-8740 (#1558809)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user