Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e894177d authored by Song Chun Fan's avatar Song Chun Fan
Browse files

[ADI][7/N] only the current verifier can call VerificationSession APIs

Only the current verifier bound by the system can call
VerificationSession APIs and the PackageInstaller API to change the
verification policy. This makes sure that even if there are multiple
verifiers installed on the device, only the one bound by the system can
affect the ongoing installations.

+ Removes @RequiresPermission from VerificationSession APIs because we
  no longer directly check for caller permission (instead, we are
checking for UID matches)
+ Add shell commands to get/set the global policy (for testing)
+ Improve error handling when binding to the verifier has failed
+ Some code polish

FLAG: android.content.pm.verification_service

BUG: 360129657
Test: cts tests to be added
API-Coverage-Bug: 367776952

Reverted changes: /q/submissionid:30469933-revert_verification_service_main

Merged-In: Ie42a47d545f8ed9ed8ea0f47a914d2d18d5d814c
Change-Id: Ie42a47d545f8ed9ed8ea0f47a914d2d18d5d814c
parent d4ef73ec
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -4730,7 +4730,7 @@ package android.content.pm.verify.pkg {
  @FlaggedApi("android.content.pm.verification_service") public final class VerificationSession implements android.os.Parcelable {
    method public int describeContents();
    method @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public long extendTimeRemaining(long);
    method public long extendTimeRemaining(long);
    method @NonNull public java.util.List<android.content.pm.SharedLibraryInfo> getDeclaredLibraries();
    method @NonNull public android.os.PersistableBundle getExtensionParams();
    method public int getId();
@@ -4738,12 +4738,12 @@ package android.content.pm.verify.pkg {
    method @NonNull public String getPackageName();
    method @NonNull public android.content.pm.SigningInfo getSigningInfo();
    method @NonNull public android.net.Uri getStagedPackageUri();
    method @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public long getTimeoutTime();
    method public long getTimeoutTime();
    method public int getVerificationPolicy();
    method @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public void reportVerificationComplete(@NonNull android.content.pm.verify.pkg.VerificationStatus);
    method @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public void reportVerificationComplete(@NonNull android.content.pm.verify.pkg.VerificationStatus, @NonNull android.os.PersistableBundle);
    method @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public void reportVerificationIncomplete(int);
    method @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public boolean setVerificationPolicy(int);
    method public void reportVerificationComplete(@NonNull android.content.pm.verify.pkg.VerificationStatus);
    method public void reportVerificationComplete(@NonNull android.content.pm.verify.pkg.VerificationStatus, @NonNull android.os.PersistableBundle);
    method public void reportVerificationIncomplete(int);
    method public boolean setVerificationPolicy(int);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.verify.pkg.VerificationSession> CREATOR;
    field public static final int VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE = 1; // 0x1
+2 −2
Original line number Diff line number Diff line
@@ -94,9 +94,9 @@ interface IPackageInstaller {
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES,android.Manifest.permission.REQUEST_INSTALL_PACKAGES})")
    void reportUnarchivalStatus(int unarchiveId, int status, long requiredStorageBytes, in PendingIntent userActionIntent, in UserHandle userHandle);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)")
    @EnforcePermission("VERIFICATION_AGENT")
    int getVerificationPolicy();

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)")
    @EnforcePermission("VERIFICATION_AGENT")
    boolean setVerificationPolicy(int policy);
}
+1 −8
Original line number Diff line number Diff line
@@ -24,16 +24,9 @@ import android.os.PersistableBundle;
 * @hide
 */
interface IVerificationSessionInterface {
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)")
    long getTimeoutTime(int verificationId);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)")
    long extendTimeRemaining(int verificationId, long additionalMs);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)")
    boolean setVerificationPolicy(int verificationId, int policy);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)")
    void reportVerificationIncomplete(int verificationId, int reason);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)")
    void reportVerificationComplete(int verificationId, in VerificationStatus status);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)")
    void reportVerificationCompleteWithExtensionResponse(int verificationId, in VerificationStatus status, in PersistableBundle response);
    void reportVerificationComplete(int verificationId, in VerificationStatus status, in @nullable PersistableBundle extensionResponse);
}
 No newline at end of file
+10 −11
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package android.content.pm.verify.pkg;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.pm.Flags;
import android.content.pm.PackageInstaller;
@@ -166,8 +165,8 @@ public final class VerificationSession implements Parcelable {
    /**
     * Get the value of Clock.elapsedRealtime() at which time this verification
     * will timeout as incomplete if no other verification response is provided.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     */
    @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
    public long getTimeoutTime() {
        try {
            return mSession.getTimeoutTime(mId);
@@ -190,8 +189,8 @@ public final class VerificationSession implements Parcelable {
    /**
     * Override the verification policy for this session.
     * @return True if the override was successful, False otherwise.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     */
    @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
    public boolean setVerificationPolicy(@PackageInstaller.VerificationPolicy int policy) {
        if (mVerificationPolicy == policy) {
            // No effective policy change
@@ -215,8 +214,8 @@ public final class VerificationSession implements Parcelable {
     * This may be called multiple times. If the request would bypass any max
     * duration by the system, the method will return a lower value than the
     * requested amount that indicates how much the time was extended.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     */
    @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
    public long extendTimeRemaining(long additionalMs) {
        try {
            return mSession.extendTimeRemaining(mId, additionalMs);
@@ -227,9 +226,9 @@ public final class VerificationSession implements Parcelable {

    /**
     * Report to the system that verification could not be completed along
     * with an approximate reason to pass on to the installer.
     * with an approximate reason to pass on to the installer.]
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     */
    @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
    public void reportVerificationIncomplete(@VerificationIncompleteReason int reason) {
        try {
            mSession.reportVerificationIncomplete(mId, reason);
@@ -242,11 +241,11 @@ public final class VerificationSession implements Parcelable {
     * Report to the system that the verification has completed and the
     * install process may act on that status to either block in the case
     * of failure or continue to process the install in the case of success.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     */
    @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
    public void reportVerificationComplete(@NonNull VerificationStatus status) {
        try {
            mSession.reportVerificationComplete(mId, status);
            mSession.reportVerificationComplete(mId, status,  /* extensionResponse= */ null);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -256,12 +255,12 @@ public final class VerificationSession implements Parcelable {
     * Same as {@link #reportVerificationComplete(VerificationStatus)}, but also provide
     * a result to the extension params provided in the request, which will be passed to the
     * installer in the installation result.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     */
    @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
    public void reportVerificationComplete(@NonNull VerificationStatus status,
            @NonNull PersistableBundle response) {
            @NonNull PersistableBundle extensionResponse) {
        try {
            mSession.reportVerificationCompleteWithExtensionResponse(mId, status, response);
            mSession.reportVerificationComplete(mId, status, extensionResponse);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+2 −2
Original line number Diff line number Diff line
@@ -141,10 +141,10 @@ public class VerificationSessionTest {
                new VerificationStatus.Builder().setVerified(true).build();
        mTestSession.reportVerificationComplete(status);
        verify(mTestSessionInterface, times(1)).reportVerificationComplete(
                eq(TEST_ID), eq(status));
                eq(TEST_ID), eq(status), eq(null));
        mTestSession.reportVerificationComplete(status, response);
        verify(mTestSessionInterface, times(1))
                .reportVerificationCompleteWithExtensionResponse(
                .reportVerificationComplete(
                        eq(TEST_ID), eq(status), eq(response));

        final int reason = VerificationSession.VERIFICATION_INCOMPLETE_UNKNOWN;
Loading