blob: c34a5f53ae95656dcd00be9fc690963f34f3365b [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database.sqlite.cts;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabaseCorruptException;
import android.test.AndroidTestCase;
/**
* This CTS test verifies Magellan SQLite Security Vulnerability.
* Without the fix, the last statement in each test case triggers a segmentation fault and the test
* fails.
* With the fix, the last statement in each test case triggers SQLiteDatabaseCorruptException with
* message "database disk image is malformed (code 267 SQLITE_CORRUPT_VTAB)", this is expected
* behavior that we are crashing and we are not leaking data.
*/
public class SQLiteSecurityTest extends AndroidTestCase {
private static final String DATABASE_NAME = "database_test.db";
private SQLiteDatabase mDatabase;
@Override
protected void setUp() throws Exception {
super.setUp();
getContext().deleteDatabase(DATABASE_NAME);
mDatabase = getContext().openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE,
null);
assertNotNull(mDatabase);
}
@Override
protected void tearDown() throws Exception {
mDatabase.close();
getContext().deleteDatabase(DATABASE_NAME);
super.tearDown();
}
public void testScript1() {
mDatabase.beginTransaction();
mDatabase.execSQL("CREATE VIRTUAL TABLE ft USING fts3;");
mDatabase.execSQL("INSERT INTO ft_content VALUES(1,'aback');");
mDatabase.execSQL("INSERT INTO ft_content VALUES(2,'abaft');");
mDatabase.execSQL("INSERT INTO ft_content VALUES(3,'abandon');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES(0,0,0,0,'0 29',X"
+ "'0005616261636b03010200ffffffff070266740302020003046e646f6e03030200');");
mDatabase.setTransactionSuccessful();
mDatabase.endTransaction();
try {
mDatabase.execSQL("SELECT * FROM ft WHERE ft MATCH 'abandon';");
} catch (SQLiteDatabaseCorruptException e) {
return;
}
fail("Expecting a SQLiteDatabaseCorruptException");
}
public void testScript2() {
mDatabase.beginTransaction();
mDatabase.execSQL("CREATE VIRTUAL TABLE ft USING fts3;");
mDatabase.execSQL("INSERT INTO ft_segments VALUES(1,"
+ "X'0004616263300301020003013103020200040130030b0200040131030c0200');");
mDatabase.execSQL("INSERT INTO ft_segments VALUES(2,"
+ "X'00056162633132030d0200040133030e0200040134030f020004013503100200');");
mDatabase.execSQL("INSERT INTO ft_segments VALUES(3,"
+ "X'0005616263313603110200040137031202000401380313020004013903140200');");
mDatabase.execSQL("INSERT INTO ft_segments VALUES(4,"
+ "X'00046162633203030200030133030402000301340305020003013503060200');");
mDatabase.execSQL("INSERT INTO ft_segments VALUES(5,"
+ "X'000461626336030702000301370308020003013803090200030139030a0200');");
mDatabase.execSQL("INSERT INTO ft_segdir "
+ "VALUES(0,0,1,5,'5 157',X'0101056162633132ffffffff070236030132030136');");
mDatabase.setTransactionSuccessful();
mDatabase.endTransaction();
try {
mDatabase.execSQL("SELECT * FROM ft WHERE ft MATCH 'abc20';");
} catch (SQLiteDatabaseCorruptException e) {
return;
}
fail("Expecting a SQLiteDatabaseCorruptException");
}
public void testScript3() {
mDatabase.beginTransaction();
mDatabase.execSQL("CREATE VIRTUAL TABLE ft USING fts4;");
mDatabase.execSQL("INSERT INTO ft_segments VALUES"
+ "(1,X'00046162633003010200040178030202000501780303020003013103040200');");
mDatabase.execSQL("INSERT INTO ft_segments VALUES"
+ "(2,X'00056162633130031f0200ffffffff07ff5566740302020003046e646f6e03030200');");
mDatabase.execSQL("INSERT INTO ft_segments VALUES(384,NULL);");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,0,0,0,'0 24',X'000561626331780305020005017803060200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ " (0,1,0,0,'0 24',X'000461626332030702000401780308020005017803090200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,2,0,0,'0 24',X'000461626333030a0200040178030b0200050178030c0200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES" +
"(0,3,0,0,'0 24',X'000461626334030d0200040178030e0200050178030f0200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,4,0,0,'0 24',X'000461626335031002000401780311020005017803120200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,5,0,0,'0 24',X'000461626336031302000401780314020005017803150200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,6,0,0,'0 24',X'000461626337031602000401780317020005017803180200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,7,0,0,'0 24',X'00046162633803190200040178031a0200050178031b0200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,8,0,0,'0 24',X'000461626339031c0200040178031d0200050178031e0200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,9,0,0,'0 25',X'00066162633130780320020006017803210200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
+ "(0,10,0,0,'0 25',X'00056162633131032202000501780323020006017803240200');");
mDatabase.execSQL("INSERT INTO ft_segdir VALUES(1,0,1,2,'384 -42',X'0101056162633130');");
mDatabase.execSQL("INSERT INTO ft_stat VALUES(1,X'000b');");
mDatabase.execSQL("PRAGMA writable_schema=OFF;");
mDatabase.setTransactionSuccessful();
mDatabase.endTransaction();
try {
mDatabase.execSQL("INSERT INTO ft(ft) VALUES('merge=1,4');");
} catch (SQLiteDatabaseCorruptException e) {
return;
}
fail("Expecting a SQLiteDatabaseCorruptException");
}
}