OSDN Git Service

Delay touching disks when secure keyguard showing.
authorJeff Sharkey <jsharkey@android.com>
Fri, 15 Dec 2017 05:15:14 +0000 (22:15 -0700)
committerJeff Sharkey <jsharkey@android.com>
Fri, 15 Dec 2017 20:44:59 +0000 (13:44 -0700)
We've tried our best to protect against malicious storage devices
with limited SELinux domains, but let's be even more paranoid and
refuse to look at disks inserted while a secure keyguard is
showing.  We'll gladly scan them right away once the user confirms
their credentials.

Test: builds, boots, manual testing
Bug: 68054513
Change-Id: I19b7446e855176921ed477ef6d07bc9a2cc0ef9a

core/java/android/app/ActivityManagerInternal.java
services/core/java/com/android/server/StorageManagerService.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/vr/VrManagerInternal.java
services/core/java/com/android/server/vr/VrManagerService.java

index 6666fcc..998d77f 100644 (file)
@@ -309,4 +309,11 @@ public abstract class ActivityManagerInternal {
      * Returns {@code true} if {@code uid} is running an activity from {@code packageName}.
      */
     public abstract boolean hasRunningActivity(int uid, @Nullable String packageName);
+
+    public interface ScreenObserver {
+        public void onAwakeStateChanged(boolean isAwake);
+        public void onKeyguardStateChanged(boolean isShowing);
+    }
+
+    public abstract void registerScreenObserver(ScreenObserver observer);
 }
index 7f0b508..7ecb9ce 100644 (file)
@@ -31,8 +31,11 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG;
 import android.Manifest;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerInternal.ScreenObserver;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
+import android.app.KeyguardManager;
 import android.app.usage.StorageStatsManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -160,7 +163,8 @@ import javax.crypto.spec.PBEKeySpec;
  * watch for and manage dynamically added storage, such as SD cards and USB mass
  * storage. Also decides how storage should be presented to users on the device.
  */
-class StorageManagerService extends IStorageManager.Stub implements Watchdog.Monitor {
+class StorageManagerService extends IStorageManager.Stub
+        implements Watchdog.Monitor, ScreenObserver {
 
     // Static direct instance pointer for the tightly-coupled idle service to use
     static StorageManagerService sSelf = null;
@@ -402,6 +406,7 @@ class StorageManagerService extends IStorageManager.Stub implements Watchdog.Mon
     private volatile boolean mSystemReady = false;
     private volatile boolean mBootCompleted = false;
     private volatile boolean mDaemonConnected = false;
+    private volatile boolean mSecureKeyguardShowing = true;
 
     private PackageManagerService mPms;
 
@@ -827,6 +832,7 @@ class StorageManagerService extends IStorageManager.Stub implements Watchdog.Mon
                     mVold.onUserStarted(userId);
                     mStoraged.onUserStarted(userId);
                 }
+                mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
             } catch (Exception e) {
                 Slog.wtf(TAG, e);
             }
@@ -878,6 +884,24 @@ class StorageManagerService extends IStorageManager.Stub implements Watchdog.Mon
         }
     }
 
+    @Override
+    public void onAwakeStateChanged(boolean isAwake) {
+        // Ignored
+    }
+
+    @Override
+    public void onKeyguardStateChanged(boolean isShowing) {
+        // Push down current secure keyguard status so that we ignore malicious
+        // USB devices while locked.
+        mSecureKeyguardShowing = isShowing
+                && mContext.getSystemService(KeyguardManager.class).isDeviceSecure();
+        try {
+            mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
+        } catch (Exception e) {
+            Slog.wtf(TAG, e);
+        }
+    }
+
     void runIdleMaintenance(Runnable callback) {
         mHandler.sendMessage(mHandler.obtainMessage(H_FSTRIM, callback));
     }
@@ -1414,6 +1438,9 @@ class StorageManagerService extends IStorageManager.Stub implements Watchdog.Mon
     }
 
     private void systemReady() {
+        LocalServices.getService(ActivityManagerInternal.class)
+                .registerScreenObserver(this);
+
         mSystemReady = true;
         mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
     }
index 9366f6e..975e58b 100644 (file)
@@ -210,6 +210,7 @@ import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackInfo;
 import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerInternal.ScreenObserver;
 import android.app.ActivityManagerInternal.SleepToken;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
@@ -1627,6 +1628,8 @@ public class ActivityManagerService extends IActivityManager.Stub
         }
     }
 
+    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
+
     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
 
@@ -1749,13 +1752,13 @@ public class ActivityManagerService extends IActivityManager.Stub
     static final int LOG_STACK_STATE = 60;
     static final int VR_MODE_CHANGE_MSG = 61;
     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
-    static final int NOTIFY_VR_SLEEPING_MSG = 65;
+    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
+    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
-    static final int NOTIFY_VR_KEYGUARD_MSG = 74;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -2391,11 +2394,17 @@ public class ActivityManagerService extends IActivityManager.Stub
                     }
                 }
             } break;
-            case NOTIFY_VR_SLEEPING_MSG: {
-                notifyVrManagerOfSleepState(msg.arg1 != 0);
+            case DISPATCH_SCREEN_AWAKE_MSG: {
+                final boolean isAwake = msg.arg1 != 0;
+                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
+                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
+                }
             } break;
-            case NOTIFY_VR_KEYGUARD_MSG: {
-                notifyVrManagerOfKeyguardState(msg.arg1 != 0);
+            case DISPATCH_SCREEN_KEYGUARD_MSG: {
+                final boolean isShowing = msg.arg1 != 0;
+                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
+                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
+                }
             } break;
             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
                 synchronized (ActivityManagerService.this) {
@@ -3292,32 +3301,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
     }
 
-    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
-        mHandler.sendMessage(
-                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
-    }
-
-    private void notifyVrManagerOfSleepState(boolean isSleeping) {
-        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
-        if (vrService == null) {
-            return;
-        }
-        vrService.onSleepStateChanged(isSleeping);
-    }
-
-    private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) {
-        mHandler.sendMessage(
-                mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0));
-    }
-
-    private void notifyVrManagerOfKeyguardState(boolean isShowing) {
-        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
-        if (vrService == null) {
-            return;
-        }
-        vrService.onKeyguardStateChanged(isShowing);
-    }
-
     final void showAskCompatModeDialogLocked(ActivityRecord r) {
         Message msg = Message.obtain();
         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
@@ -12432,7 +12415,8 @@ public class ActivityManagerService extends IActivityManager.Stub
             if (wasAwake != isAwake) {
                 // Also update state in a special way for running foreground services UI.
                 mServices.updateScreenStateLocked(isAwake);
-                sendNotifyVrManagerOfSleepState(!isAwake);
+                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
+                        .sendToTarget();
             }
         }
     }
@@ -12588,7 +12572,9 @@ public class ActivityManagerService extends IActivityManager.Stub
                 Binder.restoreCallingIdentity(ident);
             }
         }
-        sendNotifyVrManagerOfKeyguardState(showing);
+
+        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
+                .sendToTarget();
     }
 
     @Override
@@ -24525,6 +24511,11 @@ public class ActivityManagerService extends IActivityManager.Stub
             }
             return false;
         }
+
+        @Override
+        public void registerScreenObserver(ScreenObserver observer) {
+            mScreenObservers.add(observer);
+        }
     }
 
     /**
index 7b1e12e..35b6ad3 100644 (file)
@@ -59,13 +59,6 @@ public abstract class VrManagerInternal {
             int userId, int processId, @NonNull ComponentName calling);
 
     /**
-     * Set whether the system has acquired a sleep token.
-     *
-     * @param isAsleep is {@code true} if the device is asleep, or {@code false} otherwise.
-     */
-    public abstract void onSleepStateChanged(boolean isAsleep);
-
-    /**
      * Set whether the display used for VR output is on.
      *
      * @param isScreenOn is {@code true} if the display is on and can receive commands,
@@ -74,13 +67,6 @@ public abstract class VrManagerInternal {
     public abstract void onScreenStateChanged(boolean isScreenOn);
 
     /**
-     * Set whether the keyguard is currently active/showing.
-     *
-     * @param isShowing is {@code true} if the keyguard is active/showing.
-     */
-    public abstract void onKeyguardStateChanged(boolean isShowing);
-
-    /**
      * Return NO_ERROR if the given package is installed on the device and enabled as a
      * VrListenerService for the given current user, or a negative error code indicating a failure.
      *
index 7d55b68..21c6889 100644 (file)
@@ -19,6 +19,7 @@ import static android.view.Display.INVALID_DISPLAY;
 
 import android.Manifest;
 import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerInternal.ScreenObserver;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.INotificationManager;
@@ -105,7 +106,8 @@ import java.util.Objects;
  *
  * @hide
  */
-public class VrManagerService extends SystemService implements EnabledComponentChangeListener{
+public class VrManagerService extends SystemService
+        implements EnabledComponentChangeListener, ScreenObserver {
 
     public static final String TAG = "VrManagerService";
     static final boolean DBG = false;
@@ -237,15 +239,17 @@ public class VrManagerService extends SystemService implements EnabledComponentC
         }
     }
 
-    private void setSleepState(boolean isAsleep) {
-        setSystemState(FLAG_AWAKE, !isAsleep);
-    }
-
     private void setScreenOn(boolean isScreenOn) {
         setSystemState(FLAG_SCREEN_ON, isScreenOn);
     }
 
-    private void setKeyguardShowing(boolean isShowing) {
+    @Override
+    public void onAwakeStateChanged(boolean isAwake) {
+        setSystemState(FLAG_AWAKE, isAwake);
+    }
+
+    @Override
+    public void onKeyguardStateChanged(boolean isShowing) {
         setSystemState(FLAG_KEYGUARD_UNLOCKED, !isShowing);
     }
 
@@ -706,21 +710,11 @@ public class VrManagerService extends SystemService implements EnabledComponentC
         }
 
         @Override
-        public void onSleepStateChanged(boolean isAsleep) {
-            VrManagerService.this.setSleepState(isAsleep);
-        }
-
-        @Override
         public void onScreenStateChanged(boolean isScreenOn) {
             VrManagerService.this.setScreenOn(isScreenOn);
         }
 
         @Override
-        public void onKeyguardStateChanged(boolean isShowing) {
-            VrManagerService.this.setKeyguardShowing(isShowing);
-        }
-
-        @Override
         public boolean isCurrentVrListener(String packageName, int userId) {
             return VrManagerService.this.isCurrentVrListener(packageName, userId);
         }
@@ -773,6 +767,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC
     @Override
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
+            LocalServices.getService(ActivityManagerInternal.class)
+                    .registerScreenObserver(this);
+
             mNotificationManager = INotificationManager.Stub.asInterface(
                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
             synchronized (mLock) {