diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 16deaa05afcea..f336672ffefae 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -21,6 +21,7 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED; @@ -934,6 +935,13 @@ public class ParsingPackageUtils { ); } + if (ParsedPermissionUtils.declareDuplicatePermission(pkg)) { + return input.error( + INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, + "Declare duplicate permissions with different protection levels." + ); + } + convertCompatPermissions(pkg); convertSplitPermissions(pkg); diff --git a/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java b/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java index 66e9d3ddca1f1..86c8f02f9fd94 100644 --- a/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java @@ -27,6 +27,7 @@ import android.content.pm.parsing.result.ParseResult; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; +import android.util.ArrayMap; import android.util.Slog; import com.android.internal.R; @@ -34,6 +35,7 @@ import com.android.internal.R; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.util.List; /** @hide */ public class ParsedPermissionUtils { @@ -271,4 +273,29 @@ public class ParsedPermissionUtils { } return size; } + + /** + * @return {@code true} if the package declares duplicate permissions with different + * protection levels. + */ + public static boolean declareDuplicatePermission(@NonNull ParsingPackage pkg) { + final List permissions = pkg.getPermissions(); + final int size = permissions.size(); + if (size > 0) { + final ArrayMap checkDuplicatePerm = new ArrayMap<>(size); + for (int i = 0; i < size; i++) { + final ParsedPermission parsedPermission = permissions.get(i); + final String name = parsedPermission.getName(); + final ParsedPermission perm = checkDuplicatePerm.get(name); + // Since a permission tree is also added as a permission with normal protection + // level, we need to skip if the parsedPermission is a permission tree. + if (perm != null && !(perm.isTree() || parsedPermission.isTree()) + && perm.getProtectionLevel() != parsedPermission.getProtectionLevel()) { + return true; + } + checkDuplicatePerm.put(name, parsedPermission); + } + } + return false; + } }