Merge changes I0877f915,If6889737 into rvc-dev
* changes: RebootEscrow: create event log RebootEscrow: add bugreport dump
This commit is contained in:
committed by
Android (Google) Code Review
commit
e1741183b9
@@ -3193,6 +3193,12 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
mStrongAuth.dump(pw);
|
mStrongAuth.dump(pw);
|
||||||
pw.println();
|
pw.println();
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
|
|
||||||
|
pw.println("RebootEscrow:");
|
||||||
|
pw.increaseIndent();
|
||||||
|
mRebootEscrowManager.dump(pw);
|
||||||
|
pw.println();
|
||||||
|
pw.decreaseIndent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.server.locksettings;
|
|||||||
|
|
||||||
import static android.os.UserHandle.USER_SYSTEM;
|
import static android.os.UserHandle.USER_SYSTEM;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -25,6 +26,7 @@ import android.content.pm.UserInfo;
|
|||||||
import android.hardware.rebootescrow.IRebootEscrow;
|
import android.hardware.rebootescrow.IRebootEscrow;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -32,11 +34,15 @@ import android.util.Slog;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.FrameworkStatsLog;
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
import com.android.internal.widget.RebootEscrowListener;
|
import com.android.internal.widget.RebootEscrowListener;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
class RebootEscrowManager {
|
class RebootEscrowManager {
|
||||||
@@ -62,6 +68,11 @@ class RebootEscrowManager {
|
|||||||
*/
|
*/
|
||||||
private static final int BOOT_COUNT_TOLERANCE = 5;
|
private static final int BOOT_COUNT_TOLERANCE = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs events for later debugging in bugreports.
|
||||||
|
*/
|
||||||
|
private final RebootEscrowEventLog mEventLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track when the reboot escrow is wanted. Should stay true once escrow is requested
|
* Used to track when the reboot escrow is wanted. Should stay true once escrow is requested
|
||||||
* unless clearRebootEscrow is called. This will allow all the active users to be unlocked
|
* unless clearRebootEscrow is called. This will allow all the active users to be unlocked
|
||||||
@@ -135,6 +146,10 @@ class RebootEscrowManager {
|
|||||||
public void reportMetric(boolean success) {
|
public void reportMetric(boolean success) {
|
||||||
FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, success);
|
FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RebootEscrowEventLog getEventLog() {
|
||||||
|
return new RebootEscrowEventLog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RebootEscrowManager(Context context, Callbacks callbacks, LockSettingsStorage storage) {
|
RebootEscrowManager(Context context, Callbacks callbacks, LockSettingsStorage storage) {
|
||||||
@@ -148,6 +163,7 @@ class RebootEscrowManager {
|
|||||||
mCallbacks = callbacks;
|
mCallbacks = callbacks;
|
||||||
mStorage = storage;
|
mStorage = storage;
|
||||||
mUserManager = injector.getUserManager();
|
mUserManager = injector.getUserManager();
|
||||||
|
mEventLog = injector.getEventLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadRebootEscrowDataIfAvailable() {
|
void loadRebootEscrowDataIfAvailable() {
|
||||||
@@ -173,6 +189,8 @@ class RebootEscrowManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mEventLog.addEntry(RebootEscrowEvent.FOUND_ESCROW_DATA);
|
||||||
|
|
||||||
boolean allUsersUnlocked = true;
|
boolean allUsersUnlocked = true;
|
||||||
for (UserInfo user : rebootEscrowUsers) {
|
for (UserInfo user : rebootEscrowUsers) {
|
||||||
allUsersUnlocked &= restoreRebootEscrowForUser(user.id, escrowKey);
|
allUsersUnlocked &= restoreRebootEscrowForUser(user.id, escrowKey);
|
||||||
@@ -221,6 +239,7 @@ class RebootEscrowManager {
|
|||||||
// Overwrite the existing key with the null key
|
// Overwrite the existing key with the null key
|
||||||
rebootEscrow.storeKey(new byte[32]);
|
rebootEscrow.storeKey(new byte[32]);
|
||||||
|
|
||||||
|
mEventLog.addEntry(RebootEscrowEvent.RETRIEVED_STORED_KEK);
|
||||||
return RebootEscrowKey.fromKeyBytes(escrowKeyBytes);
|
return RebootEscrowKey.fromKeyBytes(escrowKeyBytes);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.w(TAG, "Could not retrieve escrow data");
|
Slog.w(TAG, "Could not retrieve escrow data");
|
||||||
@@ -242,6 +261,7 @@ class RebootEscrowManager {
|
|||||||
mCallbacks.onRebootEscrowRestored(escrowData.getSpVersion(),
|
mCallbacks.onRebootEscrowRestored(escrowData.getSpVersion(),
|
||||||
escrowData.getSyntheticPassword(), userId);
|
escrowData.getSyntheticPassword(), userId);
|
||||||
Slog.i(TAG, "Restored reboot escrow data for user " + userId);
|
Slog.i(TAG, "Restored reboot escrow data for user " + userId);
|
||||||
|
mEventLog.addEntry(RebootEscrowEvent.RETRIEVED_LSKF_FOR_USER, userId);
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.w(TAG, "Could not load reboot escrow data for user " + userId, e);
|
Slog.w(TAG, "Could not load reboot escrow data for user " + userId, e);
|
||||||
@@ -278,6 +298,7 @@ class RebootEscrowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mStorage.writeRebootEscrow(userId, escrowData.getBlob());
|
mStorage.writeRebootEscrow(userId, escrowData.getBlob());
|
||||||
|
mEventLog.addEntry(RebootEscrowEvent.STORED_LSKF_FOR_USER, userId);
|
||||||
|
|
||||||
setRebootEscrowReady(true);
|
setRebootEscrowReady(true);
|
||||||
}
|
}
|
||||||
@@ -322,6 +343,8 @@ class RebootEscrowManager {
|
|||||||
for (UserInfo user : users) {
|
for (UserInfo user : users) {
|
||||||
mStorage.removeRebootEscrow(user.id);
|
mStorage.removeRebootEscrow(user.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mEventLog.addEntry(RebootEscrowEvent.CLEARED_LSKF_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean armRebootEscrowIfNeeded() {
|
boolean armRebootEscrowIfNeeded() {
|
||||||
@@ -356,6 +379,7 @@ class RebootEscrowManager {
|
|||||||
|
|
||||||
if (armedRebootEscrow) {
|
if (armedRebootEscrow) {
|
||||||
mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
|
mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
|
||||||
|
mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return armedRebootEscrow;
|
return armedRebootEscrow;
|
||||||
@@ -375,6 +399,7 @@ class RebootEscrowManager {
|
|||||||
|
|
||||||
clearRebootEscrowIfNeeded();
|
clearRebootEscrowIfNeeded();
|
||||||
mRebootEscrowWanted = true;
|
mRebootEscrowWanted = true;
|
||||||
|
mEventLog.addEntry(RebootEscrowEvent.REQUESTED_LSKF);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,4 +415,123 @@ class RebootEscrowManager {
|
|||||||
void setRebootEscrowListener(RebootEscrowListener listener) {
|
void setRebootEscrowListener(RebootEscrowListener listener) {
|
||||||
mRebootEscrowListener = listener;
|
mRebootEscrowListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public static class RebootEscrowEvent {
|
||||||
|
static final int FOUND_ESCROW_DATA = 1;
|
||||||
|
static final int SET_ARMED_STATUS = 2;
|
||||||
|
static final int CLEARED_LSKF_REQUEST = 3;
|
||||||
|
static final int RETRIEVED_STORED_KEK = 4;
|
||||||
|
static final int REQUESTED_LSKF = 5;
|
||||||
|
static final int STORED_LSKF_FOR_USER = 6;
|
||||||
|
static final int RETRIEVED_LSKF_FOR_USER = 7;
|
||||||
|
|
||||||
|
final int mEventId;
|
||||||
|
final Integer mUserId;
|
||||||
|
final long mWallTime;
|
||||||
|
final long mTimestamp;
|
||||||
|
|
||||||
|
RebootEscrowEvent(int eventId) {
|
||||||
|
this(eventId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
RebootEscrowEvent(int eventId, Integer userId) {
|
||||||
|
mEventId = eventId;
|
||||||
|
mUserId = userId;
|
||||||
|
mTimestamp = SystemClock.uptimeMillis();
|
||||||
|
mWallTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getEventDescription() {
|
||||||
|
switch (mEventId) {
|
||||||
|
case FOUND_ESCROW_DATA:
|
||||||
|
return "Found escrow data";
|
||||||
|
case SET_ARMED_STATUS:
|
||||||
|
return "Set armed status";
|
||||||
|
case CLEARED_LSKF_REQUEST:
|
||||||
|
return "Cleared request for LSKF";
|
||||||
|
case RETRIEVED_STORED_KEK:
|
||||||
|
return "Retrieved stored KEK";
|
||||||
|
case REQUESTED_LSKF:
|
||||||
|
return "Requested LSKF";
|
||||||
|
case STORED_LSKF_FOR_USER:
|
||||||
|
return "Stored LSKF for user";
|
||||||
|
case RETRIEVED_LSKF_FOR_USER:
|
||||||
|
return "Retrieved LSKF for user";
|
||||||
|
default:
|
||||||
|
return "Unknown event ID " + mEventId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public static class RebootEscrowEventLog {
|
||||||
|
private RebootEscrowEvent[] mEntries = new RebootEscrowEvent[16];
|
||||||
|
private int mNextIndex = 0;
|
||||||
|
|
||||||
|
void addEntry(int eventId) {
|
||||||
|
addEntryInternal(new RebootEscrowEvent(eventId));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addEntry(int eventId, int userId) {
|
||||||
|
addEntryInternal(new RebootEscrowEvent(eventId, userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEntryInternal(RebootEscrowEvent event) {
|
||||||
|
final int index = mNextIndex;
|
||||||
|
mEntries[index] = event;
|
||||||
|
mNextIndex = (mNextIndex + 1) % mEntries.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump(@NonNull IndentingPrintWriter pw) {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US);
|
||||||
|
|
||||||
|
for (int i = 0; i < mEntries.length; ++i) {
|
||||||
|
RebootEscrowEvent event = mEntries[(i + mNextIndex) % mEntries.length];
|
||||||
|
if (event == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.print("Event #");
|
||||||
|
pw.println(i);
|
||||||
|
|
||||||
|
pw.println(" time=" + sdf.format(new Date(event.mWallTime))
|
||||||
|
+ " (timestamp=" + event.mTimestamp + ")");
|
||||||
|
|
||||||
|
pw.print(" event=");
|
||||||
|
pw.println(event.getEventDescription());
|
||||||
|
|
||||||
|
if (event.mUserId != null) {
|
||||||
|
pw.print(" user=");
|
||||||
|
pw.println(event.mUserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump(@NonNull IndentingPrintWriter pw) {
|
||||||
|
pw.print("mRebootEscrowWanted=");
|
||||||
|
pw.println(mRebootEscrowWanted);
|
||||||
|
|
||||||
|
pw.print("mRebootEscrowReady=");
|
||||||
|
pw.println(mRebootEscrowReady);
|
||||||
|
|
||||||
|
pw.print("mRebootEscrowListener=");
|
||||||
|
pw.println(mRebootEscrowListener);
|
||||||
|
|
||||||
|
boolean keySet;
|
||||||
|
synchronized (mKeyGenerationLock) {
|
||||||
|
keySet = mPendingRebootEscrowKey != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.print("mPendingRebootEscrowKey is ");
|
||||||
|
pw.println(keySet ? "set" : "not set");
|
||||||
|
|
||||||
|
pw.println();
|
||||||
|
pw.println("Event log:");
|
||||||
|
pw.increaseIndent();
|
||||||
|
mEventLog.dump(pw);
|
||||||
|
pw.println();
|
||||||
|
pw.decreaseIndent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user