diff options
author | Hall Liu <hallliu@google.com> | 2020-01-27 15:34:04 -0800 |
---|---|---|
committer | Hall Liu <hallliu@google.com> | 2020-07-14 20:43:06 +0000 |
commit | 008f8bfa9d1025f108c686d547e3c953d4fae30b (patch) | |
tree | bd9b8c56ae2a3ce6072cc30b90ed2c77264ff52f /src | |
parent | 5d6aa2b56393594a52e65ffe216e5df0c560b712 (diff) | |
download | ContactsProvider-008f8bfa9d1025f108c686d547e3c953d4fae30b.tar.gz |
Enforce strict grammar when querying the call log
Disallow subqueries and suspicious tokens when querying from the
call log database. Also add a column to the projection so that the token
detector doesn't throw a false positive.
Bug: 143230980
Test: atest android.provider.cts.contacts.CallLogProviderTest
Change-Id: I54d2d399f449ea47aa8fb4197c718f9038da25bf
Merged-In: I54d2d399f449ea47aa8fb4197c718f9038da25bf
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/providers/contacts/CallLogProvider.java | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java index ec1d40e9..ebe111f1 100644 --- a/src/com/android/providers/contacts/CallLogProvider.java +++ b/src/com/android/providers/contacts/CallLogProvider.java @@ -138,6 +138,7 @@ public class CallLogProvider extends ContentProvider { sCallsProjectionMap.put(Calls.FEATURES, Calls.FEATURES); sCallsProjectionMap.put(Calls.PHONE_ACCOUNT_COMPONENT_NAME, Calls.PHONE_ACCOUNT_COMPONENT_NAME); sCallsProjectionMap.put(Calls.PHONE_ACCOUNT_ID, Calls.PHONE_ACCOUNT_ID); + sCallsProjectionMap.put(Calls.PHONE_ACCOUNT_HIDDEN, Calls.PHONE_ACCOUNT_HIDDEN); sCallsProjectionMap.put(Calls.PHONE_ACCOUNT_ADDRESS, Calls.PHONE_ACCOUNT_ADDRESS); sCallsProjectionMap.put(Calls.NEW, Calls.NEW); sCallsProjectionMap.put(Calls.VOICEMAIL_URI, Calls.VOICEMAIL_URI); @@ -324,6 +325,13 @@ public class CallLogProvider extends ContentProvider { qb.setTables(Tables.CALLS); qb.setProjectionMap(sCallsProjectionMap); qb.setStrict(true); + // If the caller doesn't have READ_VOICEMAIL, make sure they can't + // do any SQL shenanigans to get access to the voicemails. If the caller does have the + // READ_VOICEMAIL permission, then they have sufficient permissions to access any data in + // the database, so the strict check is unnecessary. + if (!mVoicemailPermissions.callerHasReadAccess(getCallingPackage())) { + qb.setStrictGrammar(true); + } final SelectionBuilder selectionBuilder = new SelectionBuilder(selection); checkVoicemailPermissionAndAddRestriction(uri, selectionBuilder, true /*isQuery*/); @@ -529,6 +537,18 @@ public class CallLogProvider extends ContentProvider { SelectionBuilder selectionBuilder = new SelectionBuilder(selection); checkVoicemailPermissionAndAddRestriction(uri, selectionBuilder, false /*isQuery*/); + final SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(Tables.CALLS); + qb.setProjectionMap(sCallsProjectionMap); + qb.setStrict(true); + // If the caller doesn't have READ_VOICEMAIL, make sure they can't + // do any SQL shenanigans to get access to the voicemails. If the caller does have the + // READ_VOICEMAIL permission, then they have sufficient permissions to access any data in + // the database, so the strict check is unnecessary. + if (!mVoicemailPermissions.callerHasReadAccess(getCallingPackage())) { + qb.setStrictGrammar(true); + } + final SQLiteDatabase db = mDbHelper.getWritableDatabase(); final int matchedUriId = sURIMatcher.match(uri); switch (matchedUriId) { @@ -543,8 +563,7 @@ public class CallLogProvider extends ContentProvider { throw new UnsupportedOperationException("Cannot update URL: " + uri); } - return createDatabaseModifier(db).update(uri, Tables.CALLS, values, selectionBuilder.build(), - selectionArgs); + return qb.update(db, values, selectionBuilder.build(), selectionArgs); } private int deleteInternal(Uri uri, String selection, String[] selectionArgs) { @@ -559,14 +578,25 @@ public class CallLogProvider extends ContentProvider { SelectionBuilder selectionBuilder = new SelectionBuilder(selection); checkVoicemailPermissionAndAddRestriction(uri, selectionBuilder, false /*isQuery*/); + final SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(Tables.CALLS); + qb.setProjectionMap(sCallsProjectionMap); + qb.setStrict(true); + // If the caller doesn't have READ_VOICEMAIL, make sure they can't + // do any SQL shenanigans to get access to the voicemails. If the caller does have the + // READ_VOICEMAIL permission, then they have sufficient permissions to access any data in + // the database, so the strict check is unnecessary. + if (!mVoicemailPermissions.callerHasReadAccess(getCallingPackage())) { + qb.setStrictGrammar(true); + } + final SQLiteDatabase db = mDbHelper.getWritableDatabase(); final int matchedUriId = sURIMatcher.match(uri); switch (matchedUriId) { case CALLS: // TODO: Special case - We may want to forward the delete request on user 0 to the // shadow provider too. - return createDatabaseModifier(db).delete(Tables.CALLS, - selectionBuilder.build(), selectionArgs); + return qb.delete(db, selectionBuilder.build(), selectionArgs); default: throw new UnsupportedOperationException("Cannot delete that URL: " + uri); } |