summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rhed Jao <rhedjao@google.com> 2022-12-19 02:33:37 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-19 02:33:37 +0000
commit2e8ec835909e23c0728491abceed4bd2091bcd9a (patch)
treec8429cd9e9608ae9039e2118d27b7ed1eb494b95
parentb9b844866be534a828f7157b1fa194320604e591 (diff)
parentf98c2232a8ea3312cddd202577c25c4436e1afd9 (diff)
Merge "Fix permanent denial of service via apis with illegal intent filter" into tm-qpr-dev
-rw-r--r--core/java/android/content/IntentFilter.java23
-rw-r--r--core/java/android/os/PatternMatcher.java18
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java5
-rw-r--r--services/core/java/com/android/server/pm/PreferredActivityHelper.java6
-rw-r--r--services/core/java/com/android/server/pm/WatchedIntentFilter.java7
5 files changed, 59 insertions, 0 deletions
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index b3435b1180c2..63f7b8e785aa 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -2405,6 +2405,29 @@ public class IntentFilter implements Parcelable {
*/
}
+ /**
+ * Perform a check on data paths and scheme specific parts of the intent filter.
+ * Return true if it passed.
+ * @hide
+ */
+ public boolean checkDataPathAndSchemeSpecificParts() {
+ final int numDataPath = mDataPaths == null
+ ? 0 : mDataPaths.size();
+ final int numDataSchemeSpecificParts = mDataSchemeSpecificParts == null
+ ? 0 : mDataSchemeSpecificParts.size();
+ for (int i = 0; i < numDataPath; i++) {
+ if (!mDataPaths.get(i).check()) {
+ return false;
+ }
+ }
+ for (int i = 0; i < numDataSchemeSpecificParts; i++) {
+ if (!mDataSchemeSpecificParts.get(i).check()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
/** @hide */
public IntentFilter(Parcel source) {
mActions = new ArrayList<String>();
diff --git a/core/java/android/os/PatternMatcher.java b/core/java/android/os/PatternMatcher.java
index 631c98af07bf..b5425b43fe7e 100644
--- a/core/java/android/os/PatternMatcher.java
+++ b/core/java/android/os/PatternMatcher.java
@@ -16,6 +16,7 @@
package android.os;
+import android.util.Log;
import android.util.proto.ProtoOutputStream;
import java.util.Arrays;
@@ -151,6 +152,23 @@ public class PatternMatcher implements Parcelable {
proto.end(token);
}
+ /**
+ * Perform a check on the matcher for the pattern type of {@link #PATTERN_ADVANCED_GLOB}.
+ * Return true if it passed.
+ * @hide
+ */
+ public boolean check() {
+ try {
+ if (mType == PATTERN_ADVANCED_GLOB) {
+ return Arrays.equals(mParsedPattern, parseAndVerifyAdvancedPattern(mPattern));
+ }
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "Failed to verify advanced pattern: " + e.getMessage());
+ return false;
+ }
+ return true;
+ }
+
public int describeContents() {
return 0;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1ea09849cf61..8d2714cacf10 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3395,6 +3395,11 @@ public class PackageManagerService implements PackageSender, TestUtilityService
enforceOwnerRights(snapshot, ownerPackage, callingUid);
PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
+ if (!intentFilter.checkDataPathAndSchemeSpecificParts()) {
+ EventLog.writeEvent(0x534e4554, "246749936", callingUid);
+ throw new IllegalArgumentException("Invalid intent data paths or scheme specific parts"
+ + " in the filter.");
+ }
if (intentFilter.countActions() == 0) {
Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
return;
diff --git a/services/core/java/com/android/server/pm/PreferredActivityHelper.java b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
index 9befd6e09eb4..2b092b9a257c 100644
--- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java
+++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
@@ -37,6 +37,7 @@ import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.EventLog;
import android.util.Log;
import android.util.LogPrinter;
import android.util.PrintStreamPrinter;
@@ -388,6 +389,11 @@ final class PreferredActivityHelper {
throw new SecurityException(
"addPersistentPreferredActivity can only be run by the system");
}
+ if (!filter.checkDataPathAndSchemeSpecificParts()) {
+ EventLog.writeEvent(0x534e4554, "246749702", callingUid);
+ throw new IllegalArgumentException("Invalid intent data paths or scheme specific parts"
+ + " in the filter.");
+ }
if (filter.countActions() == 0) {
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
diff --git a/services/core/java/com/android/server/pm/WatchedIntentFilter.java b/services/core/java/com/android/server/pm/WatchedIntentFilter.java
index 5d7a2a3bd426..09cf0945d582 100644
--- a/services/core/java/com/android/server/pm/WatchedIntentFilter.java
+++ b/services/core/java/com/android/server/pm/WatchedIntentFilter.java
@@ -671,6 +671,13 @@ public class WatchedIntentFilter
}
/**
+ * @see IntentFilter#checkDataPathAndSchemeSpecificParts()
+ */
+ public boolean checkDataPathAndSchemeSpecificParts() {
+ return mFilter.checkDataPathAndSchemeSpecificParts();
+ }
+
+ /**
* @see IntentFilter#getHostsList()
*/
public ArrayList<String> getHostsList() {