Merge changes I0877f915,If6889737 into rvc-dev

* changes:
  RebootEscrow: create event log
  RebootEscrow: add bugreport dump
This commit is contained in:
TreeHugger Robot
2020-03-28 05:17:44 +00:00
committed by Android (Google) Code Review
2 changed files with 150 additions and 0 deletions

View File

@@ -3193,6 +3193,12 @@ public class LockSettingsService extends ILockSettings.Stub {
mStrongAuth.dump(pw);
pw.println();
pw.decreaseIndent();
pw.println("RebootEscrow:");
pw.increaseIndent();
mRebootEscrowManager.dump(pw);
pw.println();
pw.decreaseIndent();
}
/**

View File

@@ -18,6 +18,7 @@ package com.android.server.locksettings;
import static android.os.UserHandle.USER_SYSTEM;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
@@ -25,6 +26,7 @@ import android.content.pm.UserInfo;
import android.hardware.rebootescrow.IRebootEscrow;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Slog;
@@ -32,11 +34,15 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.widget.RebootEscrowListener;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
class RebootEscrowManager {
@@ -62,6 +68,11 @@ class RebootEscrowManager {
*/
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
* 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) {
FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, success);
}
public RebootEscrowEventLog getEventLog() {
return new RebootEscrowEventLog();
}
}
RebootEscrowManager(Context context, Callbacks callbacks, LockSettingsStorage storage) {
@@ -148,6 +163,7 @@ class RebootEscrowManager {
mCallbacks = callbacks;
mStorage = storage;
mUserManager = injector.getUserManager();
mEventLog = injector.getEventLog();
}
void loadRebootEscrowDataIfAvailable() {
@@ -173,6 +189,8 @@ class RebootEscrowManager {
return;
}
mEventLog.addEntry(RebootEscrowEvent.FOUND_ESCROW_DATA);
boolean allUsersUnlocked = true;
for (UserInfo user : rebootEscrowUsers) {
allUsersUnlocked &= restoreRebootEscrowForUser(user.id, escrowKey);
@@ -221,6 +239,7 @@ class RebootEscrowManager {
// Overwrite the existing key with the null key
rebootEscrow.storeKey(new byte[32]);
mEventLog.addEntry(RebootEscrowEvent.RETRIEVED_STORED_KEK);
return RebootEscrowKey.fromKeyBytes(escrowKeyBytes);
} catch (RemoteException e) {
Slog.w(TAG, "Could not retrieve escrow data");
@@ -242,6 +261,7 @@ class RebootEscrowManager {
mCallbacks.onRebootEscrowRestored(escrowData.getSpVersion(),
escrowData.getSyntheticPassword(), userId);
Slog.i(TAG, "Restored reboot escrow data for user " + userId);
mEventLog.addEntry(RebootEscrowEvent.RETRIEVED_LSKF_FOR_USER, userId);
return true;
} catch (IOException 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());
mEventLog.addEntry(RebootEscrowEvent.STORED_LSKF_FOR_USER, userId);
setRebootEscrowReady(true);
}
@@ -322,6 +343,8 @@ class RebootEscrowManager {
for (UserInfo user : users) {
mStorage.removeRebootEscrow(user.id);
}
mEventLog.addEntry(RebootEscrowEvent.CLEARED_LSKF_REQUEST);
}
boolean armRebootEscrowIfNeeded() {
@@ -356,6 +379,7 @@ class RebootEscrowManager {
if (armedRebootEscrow) {
mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS);
}
return armedRebootEscrow;
@@ -375,6 +399,7 @@ class RebootEscrowManager {
clearRebootEscrowIfNeeded();
mRebootEscrowWanted = true;
mEventLog.addEntry(RebootEscrowEvent.REQUESTED_LSKF);
return true;
}
@@ -390,4 +415,123 @@ class RebootEscrowManager {
void setRebootEscrowListener(RebootEscrowListener 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();
}
}