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
This commit is contained in:
Rhed Jao
2022-11-22 18:51:47 +08:00
parent 5a31efbff4
commit f98c2232a8
5 changed files with 59 additions and 0 deletions

View File

@@ -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>();

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -670,6 +670,13 @@ public class WatchedIntentFilter
return mFilter.debugCheck();
}
/**
* @see IntentFilter#checkDataPathAndSchemeSpecificParts()
*/
public boolean checkDataPathAndSchemeSpecificParts() {
return mFilter.checkDataPathAndSchemeSpecificParts();
}
/**
* @see IntentFilter#getHostsList()
*/