Out-of-memory in sqlite3_prepare_v2_fuzzer |
||||
Issue descriptionDetailed report: https://clusterfuzz.com/testcase?key=5119659933433856 Fuzzer: libFuzzer_sqlite3_prepare_v2_fuzzer Job Type: libfuzzer_chrome_msan Platform Id: linux Crash Type: Out-of-memory (exceeds 2048 MB) Crash Address: Crash State: sqlite3_prepare_v2_fuzzer Sanitizer: memory (MSAN) Regressed: https://clusterfuzz.com/revisions?job=libfuzzer_chrome_msan&range=458079:458169 Reproducer Testcase: https://clusterfuzz.com/download?testcase_id=5119659933433856 Issue filed automatically. See https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md for more information.
,
Aug 30 2017
,
Sep 1 2017
It repros easily, here's the repro as a TEST() fixture. Each 'sqlite3_step' gobbles up more memory, this must have to do with the zeroblobs() in the fuzzed_sql.
#include "third_party/sqlite/sqlite3.h"
TEST(FuzzerTest, sqlite3_prepare_v2_fuzzer) {
sqlite3* db;
int return_code = sqlite3_open_v2(
"db.db",
&db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0);
if (SQLITE_OK != return_code)
return;
const char fuzzed_sql[] = R"(SELECT""in(?,zeroblob(49E6),65543)in(?,zeroblob(17E6),31086)``WHERE``|``IS``|``|``|``|``|``|``|``|``<``<``)";
sqlite3_stmt* statement = NULL;
int result = sqlite3_prepare_v2(db, fuzzed_sql,
strlen(fuzzed_sql), &statement, NULL);
if (result == SQLITE_OK) {
// Use selector value to randomize number of iterations.
for (int i = 0; i < 255; i++) {
if (sqlite3_step(statement) != SQLITE_ROW)
break;
}
sqlite3_finalize(statement);
}
sqlite3_close(db);
}
,
Sep 1 2017
All it takes is one call to sqlite3_step() and gigabytes are consumed, in increments, and then the function returns SQLITE_ROW.
sqlite3_prepare_v2(db, fuzzed_sql,
strlen(fuzzed_sql), &statement, NULL);
sqlite3_step(statement);
sqlite3_finalize(statement);
sqlite3_close(db);
The memory is freed up in finalize().
,
Sep 1 2017
SELECT ZEROBLOB(1000000000), ZEROBLOB(1000000000) Will consume ~2G. The limit for an indiviual blob is 1000000000, which is also the max size of a row in the db, however apparently this limit is not applied to a resultant row. /* ** The maximum length of a TEXT or BLOB in bytes. This also ** limits the size of a row in a table or index. ** ** The hard limit is the ability of a 32-bit signed integer ** to count the size: 2^31-1 or 2147483647. */ #ifndef SQLITE_MAX_LENGTH # define SQLITE_MAX_LENGTH 1000000000 #endif I'm not sure this is much different than allocating large ArrayBuffers from javascript?
,
Sep 1 2017
I don't think this is a P1, but if i'm wrong please push back. It might make sense to have a SQLITE_MAX_RESULT_LENGTH and to have sqlite3_step() fail with SQLITE_TOOBIG if the sum of the values in the resulting row exceeds that length in bytes. I don't think there is anything like that atm, sqliteLimit.h defines these sort of limits. I think that feature would require modifications to sqlite.
,
Oct 24 2017
For more information, please see https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reference.md. The link referenced in the description is no longer valid.
,
Feb 23 2018
ClusterFuzz testcase 5119659933433856 is flaky and no longer crashes, so closing issue. If this is incorrect, please add ClusterFuzz-Wrong label and re-open the issue. |
||||
►
Sign in to add a comment |
||||
Comment 1 by msrchandra@chromium.org
, Aug 29 2017Labels: M-61 Test-Predator-Wrong
Owner: michaeln@chromium.org
Status: Assigned (was: Untriaged)