Avoid buffer overreads and false OOM error reports that could be caused by corrupted sample records in the sqlite_stat4 table.

FossilOrigin-Name: 9f85b6a52a0b9b1524daa6f24d85257e7f591e95
This commit is contained in:
dan 2013-08-16 14:09:43 +00:00
parent 61b3440603
commit c367d4c052
4 changed files with 45 additions and 12 deletions

@ -1,5 +1,5 @@
C Fix\sa\spotential\ssegfault\sfollowing\san\sOOM\swhile\srunning\sANALYZE.
D 2013-08-16T13:34:50.978
C Avoid\sbuffer\soverreads\sand\sfalse\sOOM\serror\sreports\sthat\scould\sbe\scaused\sby\scorrupted\ssample\srecords\sin\sthe\ssqlite_stat4\stable.
D 2013-08-16T14:09:43.262
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
F src/analyze.c 0427f9ea0b74fa90fc9b372b7f4ca136b48bb6b5
F src/analyze.c 30dd8962a6b95ed62793dc1e488ddec440c8a589
F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
@ -308,7 +308,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
F test/analyze6.test 19151da2c4e918905d2081b74ac5c4d47fc850ab
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88
F test/analyze9.test b73f9514af962a139d2c61d7741b0ba090789ea2
F test/analyze9.test baeb1ac3f2a6ee8bc740721f3e85b84f5ec35002
F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
@ -1107,7 +1107,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P c69b512af276a438399747af22659415af3a5d4d
R 1d895af259827a89f1c38733ddab2eab
U drh
Z 7fb242ddc62e8a326599f76c33fd34fe
P 0118797823c9093e68113578f3f3aae65de41453
R be7b1ba9d391582f66fe114108e327e7
U dan
Z daee3e03dcffd75664c2937dc08ce654

@ -1 +1 @@
0118797823c9093e68113578f3f3aae65de41453
9f85b6a52a0b9b1524daa6f24d85257e7f591e95

@ -1411,18 +1411,25 @@ static int loadStatTbl(
initAvgEq(pPrevIdx);
pPrevIdx = pIdx;
}
pSample = &pIdx->aSample[pIdx->nSample++];
pSample = &pIdx->aSample[pIdx->nSample];
decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0);
decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0);
decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0);
/* Take a copy of the sample. Add two 0x00 bytes the end of the buffer.
** This is in case the sample record is corrupted. In that case, the
** sqlite3VdbeRecordCompare() may read up to two varints past the
** end of the allocated buffer before it realizes it is dealing with
** a corrupt record. Adding the two 0x00 bytes prevents this from causing
** a buffer overread. */
pSample->n = sqlite3_column_bytes(pStmt, 4);
pSample->p = sqlite3DbMallocZero(db, pSample->n);
pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
if( pSample->p==0 ){
sqlite3_finalize(pStmt);
return SQLITE_NOMEM;
}
memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
pIdx->nSample++;
}
rc = sqlite3_finalize(pStmt);
if( rc==SQLITE_OK ) initAvgEq(pPrevIdx);

@ -291,7 +291,7 @@ do_execsql_test 5.1 {
}
#-------------------------------------------------------------------------
# This was also crashing.
# This was also crashing (corrupt sqlite_stat4 table).
#
reset_db
do_execsql_test 6.1 {
@ -317,5 +317,31 @@ do_execsql_test 6.2 {
SELECT * FROM t1 WHERE a = 'abc';
}
#-------------------------------------------------------------------------
# The following tests experiment with adding corrupted records to the
# 'sample' column of the sqlite_stat4 table.
#
reset_db
sqlite3_db_config_lookaside db 0 0 0
do_execsql_test 7.1 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b);
INSERT INTO t1 VALUES(1, 1);
INSERT INTO t1 VALUES(2, 2);
INSERT INTO t1 VALUES(3, 3);
INSERT INTO t1 VALUES(4, 4);
INSERT INTO t1 VALUES(5, 5);
ANALYZE;
UPDATE sqlite_stat4 SET sample = X'' WHERE rowid = 1;
ANALYZE sqlite_master;
}
do_execsql_test 7.2 {
UPDATE sqlite_stat4 SET sample = X'FFFF';
ANALYZE sqlite_master;
SELECT * FROM t1 WHERE a = 1;
} {1 1}
finish_test