[automerge] Fix duplicate permission privilege escalation 2p: 548edbb850

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18002380

Bug: 213323615
Change-Id: I80db06143d4caa7b304894ac6ab2ac78fe15eb50
Merged-In: I9bc839836786a0876e67fd73c05f8944bb532249
This commit is contained in:
Manjeet Rulhania
2022-05-13 21:57:02 +00:00
committed by Presubmit Automerger Backend
2 changed files with 58 additions and 0 deletions

View File

@@ -20,6 +20,7 @@ import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; 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_INCONSISTENT_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
@@ -905,6 +906,13 @@ public class ParsingPackageUtils {
); );
} }
if (ParsedPermissionUtils.declareDuplicatePermission(pkg)) {
return input.error(
INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
"Declare duplicate permissions with different protection levels or group."
);
}
convertNewPermissions(pkg); convertNewPermissions(pkg);
convertSplitPermissions(pkg); convertSplitPermissions(pkg);

View File

@@ -25,6 +25,8 @@ import android.content.pm.parsing.result.ParseResult;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.content.res.XmlResourceParser; import android.content.res.XmlResourceParser;
import android.util.ArrayMap;
import android.util.EventLog;
import android.util.Slog; import android.util.Slog;
import com.android.internal.R; import com.android.internal.R;
@@ -32,6 +34,8 @@ import com.android.internal.R;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.Objects;
/** @hide */ /** @hide */
public class ParsedPermissionUtils { public class ParsedPermissionUtils {
@@ -233,4 +237,50 @@ public class ParsedPermissionUtils {
return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permissionGroup, return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permissionGroup,
input); input);
} }
/**
* Determines if a duplicate permission is malformed .i.e. defines different protection level
* or group
*/
private static boolean isMalformedDuplicate(ParsedPermission p1, ParsedPermission p2) {
// 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 (p1 == null || p2 == null || p1.isTree() || p2.isTree()) {
return false;
}
if (p1.getProtectionLevel() != p2.getProtectionLevel()) {
return true;
}
if (!Objects.equals(p1.getGroup(), p2.getGroup())) {
return true;
}
return false;
}
/**
* @return {@code true} if the package declares malformed duplicate permissions.
*
*/
public static boolean declareDuplicatePermission(@NonNull ParsingPackage pkg) {
final List<ParsedPermission> permissions = pkg.getPermissions();
final int size = permissions.size();
if (size > 0) {
final ArrayMap<String, ParsedPermission> 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);
if (isMalformedDuplicate(parsedPermission, perm)) {
// Fix for b/213323615
EventLog.writeEvent(0x534e4554, "213323615",
"The package " + pkg.getPackageName() + " seems malicious");
return true;
}
checkDuplicatePerm.put(name, parsedPermission);
}
}
return false;
}
} }