diff options
| author | 2022-11-22 18:51:47 +0800 | |
|---|---|---|
| committer | 2022-11-24 04:54:56 +0000 | |
| commit | f98c2232a8ea3312cddd202577c25c4436e1afd9 (patch) | |
| tree | 4f5265583dd89fffb2d5cfb5d1b46450be91f018 | |
| parent | 5a31efbff4af7b34d9a29a681ebea08dd6ead189 (diff) | |
Fix permanent denial of service via apis with illegal intent filter
Bug: 246749702
Bug: 246749764
Bug: 246749936
Bug: 246750467
Bug: 249094310
Test: atest android.security.cts.PackageManagerBadIntentFilterTest
Change-Id: I632ebd1342e0f39da494a02ffabc690ad242e14a
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 b7b332621e7f..47610e7b61b0 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3373,6 +3373,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() { |