From 9765e446d3ffa60a1a82ae8fbb81585fb424d2ce Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 14 Dec 2017 22:15:14 -0700 Subject: [PATCH] Delay touching disks when secure keyguard showing. 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 --- .../android/app/ActivityManagerInternal.java | 7 +++ .../android/server/StorageManagerService.java | 29 ++++++++- .../server/am/ActivityManagerService.java | 59 ++++++++----------- .../android/server/vr/VrManagerInternal.java | 14 ----- .../android/server/vr/VrManagerService.java | 29 ++++----- 5 files changed, 73 insertions(+), 65 deletions(-) diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 6666fcc77e000..998d77fa6d46a 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -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); } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 7f0b50817d564..7ecb9ce7033ec 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -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(); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9366f6e348a33..975e58b2f0d0c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -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 mScreenObservers = new ArrayList<>(); + final RemoteCallbackList 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); + } } /** diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java index 7b1e12e240723..35b6ad3079a55 100644 --- a/services/core/java/com/android/server/vr/VrManagerInternal.java +++ b/services/core/java/com/android/server/vr/VrManagerInternal.java @@ -58,13 +58,6 @@ public abstract class VrManagerInternal { public abstract void setVrMode(boolean enabled, @NonNull ComponentName packageName, 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. * @@ -73,13 +66,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. diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index 7d55b68f2c960..21c688907dc1b 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -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); } @@ -705,21 +709,11 @@ public class VrManagerService extends SystemService implements EnabledComponentC VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage); } - @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) {