xref: /aosp_15_r20/cts/tests/tests/database/src/android/database/sqlite/cts/SQLiteSecurityTest.java (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.database.sqlite.cts;
18 
19 
20 import android.content.Context;
21 import android.database.sqlite.SQLiteDatabase;
22 import android.database.sqlite.SQLiteDatabaseCorruptException;
23 import android.test.AndroidTestCase;
24 
25 /**
26  * This CTS test verifies Magellan SQLite Security Vulnerability.
27  * Without the fix, the last statement in each test case triggers a segmentation fault and the test
28  * fails.
29  * With the fix, the last statement in each test case triggers SQLiteDatabaseCorruptException with
30  * message "database disk image is malformed (code 267 SQLITE_CORRUPT_VTAB)", this is expected
31  * behavior that we are crashing and we are not leaking data.
32  */
33 public class SQLiteSecurityTest extends AndroidTestCase {
34     private static final String DATABASE_NAME = "database_test.db";
35 
36     private SQLiteDatabase mDatabase;
37 
38     @Override
setUp()39     protected void setUp() throws Exception {
40         super.setUp();
41 
42         getContext().deleteDatabase(DATABASE_NAME);
43         mDatabase = getContext().openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE,
44               null);
45         assertNotNull(mDatabase);
46     }
47 
48     @Override
tearDown()49     protected void tearDown() throws Exception {
50         mDatabase.close();
51         getContext().deleteDatabase(DATABASE_NAME);
52 
53         super.tearDown();
54     }
55 
testScript1()56     public void testScript1() {
57         mDatabase.beginTransaction();
58         mDatabase.execSQL("CREATE VIRTUAL TABLE ft USING fts3;");
59         mDatabase.execSQL("INSERT INTO ft_content VALUES(1,'aback');");
60         mDatabase.execSQL("INSERT INTO ft_content VALUES(2,'abaft');");
61         mDatabase.execSQL("INSERT INTO ft_content VALUES(3,'abandon');");
62         mDatabase.execSQL("INSERT INTO ft_segdir VALUES(0,0,0,0,'0 29',X"
63             + "'0005616261636b03010200ffffffff070266740302020003046e646f6e03030200');");
64         mDatabase.setTransactionSuccessful();
65         mDatabase.endTransaction();
66         try {
67             mDatabase.execSQL("SELECT * FROM ft WHERE ft MATCH 'abandon';");
68         } catch (SQLiteDatabaseCorruptException e) {
69             return;
70         }
71         fail("Expecting a SQLiteDatabaseCorruptException");
72     }
73 
testScript2()74     public void testScript2() {
75       mDatabase.beginTransaction();
76       mDatabase.execSQL("CREATE VIRTUAL TABLE ft USING fts3;");
77       mDatabase.execSQL("INSERT INTO ft_segments VALUES(1,"
78           + "X'0004616263300301020003013103020200040130030b0200040131030c0200');");
79       mDatabase.execSQL("INSERT INTO ft_segments VALUES(2,"
80           + "X'00056162633132030d0200040133030e0200040134030f020004013503100200');");
81       mDatabase.execSQL("INSERT INTO ft_segments VALUES(3,"
82           + "X'0005616263313603110200040137031202000401380313020004013903140200');");
83       mDatabase.execSQL("INSERT INTO ft_segments VALUES(4,"
84           + "X'00046162633203030200030133030402000301340305020003013503060200');");
85       mDatabase.execSQL("INSERT INTO ft_segments VALUES(5,"
86           + "X'000461626336030702000301370308020003013803090200030139030a0200');");
87       mDatabase.execSQL("INSERT INTO ft_segdir "
88           + "VALUES(0,0,1,5,'5 157',X'0101056162633132ffffffff070236030132030136');");
89       mDatabase.setTransactionSuccessful();
90       mDatabase.endTransaction();
91       try {
92           mDatabase.execSQL("SELECT * FROM ft WHERE ft MATCH 'abc20';");
93       } catch (SQLiteDatabaseCorruptException e) {
94           return;
95       }
96       fail("Expecting a SQLiteDatabaseCorruptException");
97     }
98 
testScript3()99     public void testScript3() {
100       mDatabase.beginTransaction();
101       mDatabase.execSQL("CREATE VIRTUAL TABLE ft USING fts4;");
102       mDatabase.execSQL("INSERT INTO ft_segments VALUES"
103           + "(1,X'00046162633003010200040178030202000501780303020003013103040200');");
104       mDatabase.execSQL("INSERT INTO ft_segments VALUES"
105           + "(2,X'00056162633130031f0200ffffffff07ff5566740302020003046e646f6e03030200');");
106       mDatabase.execSQL("INSERT INTO ft_segments VALUES(384,NULL);");
107       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
108           + "(0,0,0,0,'0 24',X'000561626331780305020005017803060200');");
109       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
110           + " (0,1,0,0,'0 24',X'000461626332030702000401780308020005017803090200');");
111       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
112           + "(0,2,0,0,'0 24',X'000461626333030a0200040178030b0200050178030c0200');");
113       mDatabase.execSQL("INSERT INTO ft_segdir VALUES" +
114           "(0,3,0,0,'0 24',X'000461626334030d0200040178030e0200050178030f0200');");
115       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
116           + "(0,4,0,0,'0 24',X'000461626335031002000401780311020005017803120200');");
117       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
118           + "(0,5,0,0,'0 24',X'000461626336031302000401780314020005017803150200');");
119       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
120           + "(0,6,0,0,'0 24',X'000461626337031602000401780317020005017803180200');");
121       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
122           + "(0,7,0,0,'0 24',X'00046162633803190200040178031a0200050178031b0200');");
123       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
124           + "(0,8,0,0,'0 24',X'000461626339031c0200040178031d0200050178031e0200');");
125       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
126           + "(0,9,0,0,'0 25',X'00066162633130780320020006017803210200');");
127       mDatabase.execSQL("INSERT INTO ft_segdir VALUES"
128           + "(0,10,0,0,'0 25',X'00056162633131032202000501780323020006017803240200');");
129       mDatabase.execSQL("INSERT INTO ft_segdir VALUES(1,0,1,2,'384 -42',X'0101056162633130');");
130       mDatabase.execSQL("INSERT INTO ft_stat VALUES(1,X'000b');");
131       mDatabase.execSQL("PRAGMA writable_schema=OFF;");
132       mDatabase.setTransactionSuccessful();
133       mDatabase.endTransaction();
134       try {
135           mDatabase.execSQL("INSERT INTO ft(ft) VALUES('merge=1,4');");
136       } catch (SQLiteDatabaseCorruptException e) {
137           return;
138       }
139       fail("Expecting a SQLiteDatabaseCorruptException");
140     }
141 }
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153