Revert "DO NOT MERGE Check access to user and password fields in APN db"
am: 5a848ed65a
Change-Id: I48aeb31f12c26b25c75f8481dd389ba6a5190041
diff --git a/src/com/android/providers/telephony/SqlTokenFinder.java b/src/com/android/providers/telephony/SqlTokenFinder.java
deleted file mode 100644
index 9be49fe..0000000
--- a/src/com/android/providers/telephony/SqlTokenFinder.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.providers.telephony;
-
-import android.annotation.Nullable;
-
-import java.util.function.Consumer;
-
-/**
- * Simple SQL parser to check statements for usage of prohibited/sensitive fields. Mostly copied
- * from
- * packages/providers/ContactsProvider/src/com/android/providers/contacts/sqlite/SqlChecker.java
- */
-public class SqlTokenFinder{
- private static boolean isAlpha(char ch) {
- return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || (ch == '_');
- }
-
- private static boolean isNum(char ch) {
- return ('0' <= ch && ch <= '9');
- }
-
- private static boolean isAlNum(char ch) {
- return isAlpha(ch) || isNum(ch);
- }
-
- private static boolean isAnyOf(char ch, String set) {
- return set.indexOf(ch) >= 0;
- }
-
- private static char peek(String s, int index) {
- return index < s.length() ? s.charAt(index) : '\0';
- }
-
- /**
- * SQL Tokenizer specialized to extract tokens from SQL (snippets).
- *
- * Based on sqlite3GetToken() in tokenzie.c in SQLite.
- *
- * Source for v3.8.6 (which android uses): http://www.sqlite.org/src/artifact/ae45399d6252b4d7
- * (Latest source as of now: http://www.sqlite.org/src/artifact/78c8085bc7af1922)
- *
- * Also draft spec: http://www.sqlite.org/draft/tokenreq.html
- */
- public static void findTokens(@Nullable String sql, Consumer<String> checker) {
- if (sql == null) {
- return;
- }
- int pos = 0;
- final int len = sql.length();
- while (pos < len) {
- final char ch = peek(sql, pos);
-
- // Regular token.
- if (isAlpha(ch)) {
- final int start = pos;
- pos++;
- while (isAlNum(peek(sql, pos))) {
- pos++;
- }
- final int end = pos;
-
- final String token = sql.substring(start, end);
- checker.accept(token);
-
- continue;
- }
-
- // Handle quoted tokens
- if (isAnyOf(ch, "'\"`")) {
- final int quoteStart = pos;
- pos++;
-
- for (;;) {
- pos = sql.indexOf(ch, pos);
- if (pos < 0) {
- throw new IllegalArgumentException("Unterminated quote in" + sql);
- }
- if (peek(sql, pos + 1) != ch) {
- break;
- }
- // Quoted quote char -- e.g. "abc""def" is a single string.
- pos += 2;
- }
- final int quoteEnd = pos;
- pos++;
-
- if (ch != '\'') {
- // Extract the token
- final String tokenUnquoted = sql.substring(quoteStart + 1, quoteEnd);
-
- final String token;
-
- // Unquote if needed. i.e. "aa""bb" -> aa"bb
- if (tokenUnquoted.indexOf(ch) >= 0) {
- token = tokenUnquoted.replaceAll(
- String.valueOf(ch) + ch, String.valueOf(ch));
- } else {
- token = tokenUnquoted;
- }
- checker.accept(token);
- }
- continue;
- }
- // Handle tokens enclosed in [...]
- if (ch == '[') {
- final int quoteStart = pos;
- pos++;
-
- pos = sql.indexOf(']', pos);
- if (pos < 0) {
- throw new IllegalArgumentException("Unterminated quote in" + sql);
- }
- final int quoteEnd = pos;
- pos++;
-
- final String token = sql.substring(quoteStart + 1, quoteEnd);
-
- checker.accept(token);
- continue;
- }
-
- // Detect comments.
- if (ch == '-' && peek(sql, pos + 1) == '-') {
- pos += 2;
- pos = sql.indexOf('\n', pos);
- if (pos < 0) {
- // We disallow strings ending in an inline comment.
- throw new IllegalArgumentException("Unterminated comment in" + sql);
- }
- pos++;
-
- continue;
- }
- if (ch == '/' && peek(sql, pos + 1) == '*') {
- pos += 2;
- pos = sql.indexOf("*/", pos);
- if (pos < 0) {
- throw new IllegalArgumentException("Unterminated comment in" + sql);
- }
- pos += 2;
-
- continue;
- }
-
- // Semicolon is never allowed.
- if (ch == ';') {
- throw new IllegalArgumentException("Semicolon is not allowed in " + sql);
- }
-
- // For this purpose, we can simply ignore other characters.
- // (Note it doesn't handle the X'' literal properly and reports this X as a token,
- // but that should be fine...)
- pos++;
- }
- }
-}
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 56e9c8b..8225de3 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -106,7 +106,6 @@
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.text.TextUtils;
-import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
import android.util.Xml;
@@ -207,10 +206,6 @@
private static final String DEFAULT_PROTOCOL = "IP";
private static final String DEFAULT_ROAMING_PROTOCOL = "IP";
- // Used to check if certain queries contain subqueries that may attempt to access sensitive
- // fields in the carriers db.
- private static final String SQL_SELECT_TOKEN = "select";
-
private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final ContentValues s_currentNullMap;
@@ -2807,7 +2802,7 @@
List<String> constraints = new ArrayList<String>();
int match = s_urlMatcher.match(url);
- checkQueryPermission(match, projectionIn, selection, sort);
+ checkQueryPermission(match, projectionIn);
switch (match) {
case URL_TELEPHONY_USING_SUBID: {
subIdString = url.getLastPathSegment();
@@ -3016,29 +3011,8 @@
return ret;
}
- private void checkQueryPermission(int match, String[] projectionIn, String selection,
- String sort) {
- // Determine if we need to do a check for fields in the selection
- boolean selectionOrSortContainsSensitiveFields;
- try {
- selectionOrSortContainsSensitiveFields = containsSensitiveFields(selection);
- selectionOrSortContainsSensitiveFields |= containsSensitiveFields(sort);
- } catch (IllegalArgumentException e) {
- // Malformed sql, check permission anyway and return.
- checkPermission();
- return;
- }
-
- if (selectionOrSortContainsSensitiveFields) {
- try {
- checkPermission();
- } catch (SecurityException e) {
- EventLog.writeEvent(0x534e4554, "124107808", Binder.getCallingUid());
- throw e;
- }
- }
-
- if (match != URL_SIMINFO && match != URL_SIMINFO_USING_SUBID) {
+ private void checkQueryPermission(int match, String[] projectionIn) {
+ if (match != URL_SIMINFO && match != URL_SIMINFO_USING_SUBID) {
if (projectionIn != null) {
for (String column : projectionIn) {
if (TYPE.equals(column) ||
@@ -3048,6 +3022,7 @@
MVNO_TYPE.equals(column) ||
MVNO_MATCH_DATA.equals(column) ||
APN.equals(column)) {
+ // noop
} else {
checkPermission();
break;
@@ -3063,22 +3038,6 @@
}
}
- private boolean containsSensitiveFields(String sqlStatement) {
- try {
- SqlTokenFinder.findTokens(sqlStatement, s -> {
- switch (s.toLowerCase()) {
- case USER:
- case PASSWORD:
- case SQL_SELECT_TOKEN:
- throw new SecurityException();
- }
- });
- } catch (SecurityException e) {
- return true;
- }
- return false;
- }
-
/**
* To find the current sim APN. Query APN based on {MCC, MNC, MVNO} to support backward
* compatibility but will move to carrier id in the future.