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

Commit 2a91bbfb authored by Craig Lafayette's avatar Craig Lafayette Committed by Android (Google) Code Review
Browse files

Merge "Reset protection in PersistentDataBlockManager"

parents a3e28e69 66445a63
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -30271,6 +30271,7 @@ package android.service.persistentdata {
    method public abstract byte[] read() throws android.os.RemoteException;
    method public abstract void setOemUnlockEnabled(boolean) throws android.os.RemoteException;
    method public abstract void wipe() throws android.os.RemoteException;
    method public abstract void wipeIfAllowed(android.os.Bundle, android.app.PendingIntent) throws android.os.RemoteException;
    method public abstract int write(byte[]) throws android.os.RemoteException;
  }
@@ -30282,7 +30283,14 @@ package android.service.persistentdata {
    method public byte[] read();
    method public void setOemUnlockEnabled(boolean);
    method public void wipe();
    method public void wipeIfAllowed(android.os.Bundle, android.app.PendingIntent);
    method public int write(byte[]);
    field public static final java.lang.String ACTION_WIPE_IF_ALLOWED = "android.service.persistentdata.action.WIPE_IF_ALLOWED";
    field public static final java.lang.String EXTRA_WIPE_IF_ALLOWED_CALLBACK = "android.service.persistentdata.extra.WIPE_IF_ALLOWED_CALLBACK";
    field public static final int STATUS_ERROR_NETWORK_ERROR = 2; // 0x2
    field public static final int STATUS_ERROR_NOT_COMPLIANT = 3; // 0x3
    field public static final int STATUS_ERROR_REMOTE_EXCEPTION = 1; // 0x1
    field public static final int STATUS_SUCCESS = 0; // 0x0
  }
}
+3 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.service.persistentdata;

import android.app.PendingIntent;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;

/**
@@ -30,6 +32,7 @@ interface IPersistentDataBlockService {
    int write(in byte[] data);
    byte[] read();
    void wipe();
    void wipeIfAllowed(in Bundle bundle, in PendingIntent pi);
    int getDataBlockSize();
    long getMaximumDataBlockSize();

+74 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package android.service.persistentdata;

import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Slog;

@@ -41,6 +43,56 @@ import android.util.Slog;
@SystemApi
public class PersistentDataBlockManager {
    private static final String TAG = PersistentDataBlockManager.class.getSimpleName();

    /**
     * Broadcast action that will be called when the {@link #wipeIfAllowed(Bundle,PendingIntent)}
     * method is called.  A broadcast with this action will be sent to the package allowed to write
     * to the persistent data block. Packages receiving this broadcasts should respond by using the
     * {@link android.app.PendingIntent} sent in the {@link #EXTRA_WIPE_IF_ALLOWED_CALLBACK} extra.
     */
    public static final String ACTION_WIPE_IF_ALLOWED
            = "android.service.persistentdata.action.WIPE_IF_ALLOWED";

    /**
     * A {@link android.os.Parcelable} extra of type {@link android.app.PendingIntent} used to
     * response to {@link #wipeIfAllowed(Bundle,PendingIntent)}. This extra will set in broadcasts
     * with an action of {@link #ACTION_WIPE_IF_ALLOWED}.
     */
    public static final String EXTRA_WIPE_IF_ALLOWED_CALLBACK
            = "android.service.persistentdata.extra.WIPE_IF_ALLOWED_CALLBACK";

    /**
     * Result code indicating that the data block was wiped.
     *
     * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to
     * {@link #wipeIfAllowed(Bundle,PendingIntent)}
     */
    public static final int STATUS_SUCCESS = 0;

    /**
     * Result code indicating that a remote exception was received while processing the request.
     *
     * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to
     * {@link #wipeIfAllowed(Bundle,PendingIntent)}
     */
    public static final int STATUS_ERROR_REMOTE_EXCEPTION = 1;

    /**
     * Result code indicating that a network error occurred while processing the request.
     *
     * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to
     * {@link #wipeIfAllowed(Bundle,PendingIntent)}
     */
    public static final int STATUS_ERROR_NETWORK_ERROR = 2;

    /**
     * Result code indicating that the data block could not be cleared with the provided data.
     *
     * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to
     * {@link #wipeIfAllowed(Bundle,PendingIntent)}
     */
    public static final int STATUS_ERROR_NOT_COMPLIANT = 3;

    private IPersistentDataBlockService sService;

    public PersistentDataBlockManager(IPersistentDataBlockService service) {
@@ -117,6 +169,28 @@ public class PersistentDataBlockManager {
        }
    }

    /**
     * Attempt to wipe the data block by sending a broadcast to the package allowed to modify the
     * datablock. The allowed package can refuse to wipe the data block based on the contents of
     * the specified bundle. This bundle may contain data used by the allowed package to wipe the
     * partition such as account credentials or an authorization token.
     * @param bundle data used to wipe the data block. The contents of this bundle depend on the
     *    allowed package receiving the data.
     * @param pi intent called when attempt finished. The result code of this intent will be set
     *    to one of {@link #STATUS_SUCCESS}, {@link #STATUS_ERROR_REMOTE_EXCEPTION},
     *    {@link #STATUS_ERROR_NETWORK_ERROR}, or {@link #STATUS_ERROR_NOT_COMPLIANT}.
     */
    public void wipeIfAllowed(Bundle bundle, PendingIntent pi) {
        if (pi == null) {
            throw new NullPointerException();
        }
        try {
            sService.wipeIfAllowed(bundle, pi);
        } catch (RemoteException e) {
            onError("wiping persistent partition");
        }
    }

    /**
     * Writes a byte enabling or disabling the ability to "OEM unlock" the device.
     */
+2 −0
Original line number Diff line number Diff line
@@ -309,6 +309,8 @@

    <protected-broadcast android:name="android.internal.policy.action.BURN_IN_PROTECTION" />

    <protected-broadcast android:name="android.service.persistentdata.action.WIPE_IF_ALLOWED" />

    <!-- ====================================== -->
    <!-- Permissions for things that cost money -->
    <!-- ====================================== -->
+35 −4
Original line number Diff line number Diff line
@@ -18,14 +18,18 @@ package com.android.server;

import android.Manifest;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager;
import android.util.Slog;

import com.android.internal.R;
@@ -427,6 +431,29 @@ public class PersistentDataBlockService extends SystemService {
            }
        }

        @Override
        public void wipeIfAllowed(Bundle bundle, PendingIntent pi) {
            // Should only be called by owner
            if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
                throw new SecurityException("Only the Owner is allowed to wipe");
            }
            // Caller must be able to query the the state of the PersistentDataBlock
            enforcePersistentDataBlockAccess();
            String allowedPackage = mContext.getResources()
                    .getString(R.string.config_persistentDataPackageName);
            Intent intent = new Intent();
            intent.setPackage(allowedPackage);
            intent.setAction(PersistentDataBlockManager.ACTION_WIPE_IF_ALLOWED);
            intent.putExtras(bundle);
            intent.putExtra(PersistentDataBlockManager.EXTRA_WIPE_IF_ALLOWED_CALLBACK, pi);
            long id = Binder.clearCallingIdentity();
            try {
                mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
            } finally {
                restoreCallingIdentity(id);
            }
        }

        @Override
        public void setOemUnlockEnabled(boolean enabled) {
            // do not allow monkey to flip the flag
@@ -450,10 +477,7 @@ public class PersistentDataBlockService extends SystemService {

        @Override
        public int getDataBlockSize() {
            if (mContext.checkCallingPermission(Manifest.permission.ACCESS_PDB_STATE)
                    != PackageManager.PERMISSION_GRANTED) {
                enforceUid(Binder.getCallingUid());
            }
            enforcePersistentDataBlockAccess();

            DataInputStream inputStream;
            try {
@@ -475,6 +499,13 @@ public class PersistentDataBlockService extends SystemService {
            }
        }

        private void enforcePersistentDataBlockAccess() {
            if (mContext.checkCallingPermission(Manifest.permission.ACCESS_PDB_STATE)
                    != PackageManager.PERMISSION_GRANTED) {
                enforceUid(Binder.getCallingUid());
            }
        }

        @Override
        public long getMaximumDataBlockSize() {
            long actualSize = getBlockDeviceSize() - HEADER_SIZE - 1;