Merge "Fix for security logging of missing packages."

This commit is contained in:
Alex Buynytskyy
2020-11-16 01:32:45 +00:00
committed by Android (Google) Code Review
3 changed files with 71 additions and 43 deletions

View File

@@ -1126,4 +1126,16 @@ public abstract class PackageManagerInternal {
* Notifies that a package has crashed or ANR'd.
*/
public abstract void notifyPackageCrashOrAnr(String packageName);
/**
* Requesting the checksums for APKs within a package.
* See {@link PackageManager#requestChecksums} for details.
*
* @param executor to use for digest calculations.
* @param handler to use for postponed calculations.
*/
public abstract void requestChecksums(@NonNull String packageName, boolean includeSplits,
@Checksum.Type int optional, @Checksum.Type int required,
@Nullable List trustedInstallers, @NonNull IntentSender statusReceiver, int userId,
@NonNull Executor executor, @NonNull Handler handler);
}

View File

@@ -2535,8 +2535,20 @@ public class PackageManagerService extends IPackageManager.Stub
@Checksum.Type int optional,
@Checksum.Type int required, @Nullable List trustedInstallers,
@NonNull IntentSender statusReceiver, int userId) {
requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers,
statusReceiver, userId, mInjector.getBackgroundExecutor(),
mInjector.getBackgroundHandler());
}
private void requestChecksumsInternal(@NonNull String packageName, boolean includeSplits,
@Checksum.Type int optional,
@Checksum.Type int required, @Nullable List trustedInstallers,
@NonNull IntentSender statusReceiver, int userId, @NonNull Executor executor,
@NonNull Handler handler) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(statusReceiver);
Objects.requireNonNull(executor);
Objects.requireNonNull(handler);
final ApplicationInfo applicationInfo = getApplicationInfoInternal(packageName, 0,
Binder.getCallingUid(), userId);
@@ -2560,10 +2572,10 @@ public class PackageManagerService extends IPackageManager.Stub
final Certificate[] trustedCerts = (trustedInstallers != null) ? decodeCertificates(
trustedInstallers) : null;
mInjector.getBackgroundExecutor().execute(() -> {
executor.execute(() -> {
ApkChecksums.Injector injector = new ApkChecksums.Injector(
() -> mContext,
() -> mInjector.getBackgroundHandler(),
() -> handler,
() -> mInjector.getIncrementalManager());
ApkChecksums.getChecksums(filesToChecksum, optional, required, trustedCerts,
statusReceiver, injector);
@@ -25911,6 +25923,14 @@ public class PackageManagerService extends IPackageManager.Stub
}
ps.setStatesOnCrashOrAnr();
}
public void requestChecksums(@NonNull String packageName, boolean includeSplits,
@Checksum.Type int optional, @Checksum.Type int required,
@Nullable List trustedInstallers, @NonNull IntentSender statusReceiver, int userId,
@NonNull Executor executor, @NonNull Handler handler) {
requestChecksumsInternal(packageName, includeSplits, optional, required,
trustedInstallers, statusReceiver, userId, executor, handler);
}
}
@@ -26060,8 +26080,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (!SecurityLog.isLoggingEnabled()) {
return;
}
mProcessLoggingHandler.logAppProcessStart(mContext, this, apkFile, packageName, processName,
uid, seinfo, pid);
mProcessLoggingHandler.logAppProcessStart(mContext, mPmInternal, apkFile, packageName,
processName, uid, seinfo, pid);
}
public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {

View File

@@ -26,13 +26,12 @@ import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApkChecksum;
import android.content.pm.Checksum;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.Message;
import android.os.Parcelable;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Slog;
@@ -42,12 +41,11 @@ import com.android.internal.os.BackgroundThread;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
public final class ProcessLoggingHandler extends Handler {
private static final String TAG = "ProcessLoggingHandler";
private static final int LOG_APP_PROCESS_START_MSG = 1;
private static final int CHECKSUM_TYPE = Checksum.TYPE_WHOLE_SHA256;
static class LoggingInfo {
@@ -55,6 +53,9 @@ public final class ProcessLoggingHandler extends Handler {
public List<Bundle> pendingLogEntries = new ArrayList<>();
}
// Executor to handle checksum calculations.
private final Executor mExecutor = new HandlerExecutor(this);
// Apk path to logging info map.
private final ArrayMap<String, LoggingInfo> mLoggingInfo = new ArrayMap<>();
@@ -62,25 +63,7 @@ public final class ProcessLoggingHandler extends Handler {
super(BackgroundThread.getHandler().getLooper());
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case LOG_APP_PROCESS_START_MSG: {
Bundle bundle = msg.getData();
long startTimestamp = bundle.getLong("startTimestamp");
String processName = bundle.getString("processName");
int uid = bundle.getInt("uid");
String seinfo = bundle.getString("seinfo");
int pid = bundle.getInt("pid");
String apkHash = bundle.getString("apkHash");
SecurityLog.writeEvent(SecurityLog.TAG_APP_PROCESS_START, processName,
startTimestamp, uid, pid, seinfo, apkHash);
break;
}
}
}
void logAppProcessStart(Context context, IPackageManager pms, String apkFile,
void logAppProcessStart(Context context, PackageManagerInternal pmi, String apkFile,
String packageName, String processName, int uid, String seinfo, int pid) {
Bundle data = new Bundle();
data.putLong("startTimestamp", System.currentTimeMillis());
@@ -125,7 +108,7 @@ public final class ProcessLoggingHandler extends Handler {
// Request base checksums when first added entry.
// Capturing local loggingInfo to still log even if hash was invalidated.
try {
pms.requestChecksums(packageName, false, 0, CHECKSUM_TYPE, null,
pmi.requestChecksums(packageName, false, 0, CHECKSUM_TYPE, null,
new IntentSender((IIntentSender) new IIntentSender.Stub() {
@Override
public void send(int code, Intent intent, String resolvedType,
@@ -133,10 +116,10 @@ public final class ProcessLoggingHandler extends Handler {
String requiredPermission, Bundle options) {
processChecksums(loggingInfo, intent);
}
}), context.getUserId());
} catch (RemoteException e) {
Slog.e(TAG, "requestChecksums() failed", e);
processChecksums(loggingInfo, null);
}), context.getUserId(), mExecutor, this);
} catch (Throwable t) {
Slog.e(TAG, "requestChecksums() failed", t);
enqueueProcessChecksum(loggingInfo, null);
}
}
@@ -148,9 +131,16 @@ public final class ProcessLoggingHandler extends Handler {
for (ApkChecksum checksum : checksums) {
if (checksum.getType() == CHECKSUM_TYPE) {
processChecksum(loggingInfo, checksum.getValue());
break;
return;
}
}
Slog.e(TAG, "requestChecksums() failed to return SHA256, see logs for details.");
processChecksum(loggingInfo, null);
}
void enqueueProcessChecksum(final LoggingInfo loggingInfo, final byte[] hash) {
this.post(() -> processChecksum(loggingInfo, null));
}
void processChecksum(final LoggingInfo loggingInfo, final byte[] hash) {
@@ -178,22 +168,28 @@ public final class ProcessLoggingHandler extends Handler {
if (pendingLogEntries != null) {
for (Bundle data : pendingLogEntries) {
enqueueSecurityLogEvent(data, apkHash);
logSecurityLogEvent(data, apkHash);
}
}
}
void enqueueSecurityLogEvent(Bundle data, String apkHash) {
data.putString("apkHash", apkHash);
Message msg = this.obtainMessage(LOG_APP_PROCESS_START_MSG);
msg.setData(data);
this.sendMessage(msg);
}
void invalidateBaseApkHash(String apkFile) {
synchronized (mLoggingInfo) {
mLoggingInfo.remove(apkFile);
}
}
void enqueueSecurityLogEvent(Bundle data, String apkHash) {
this.post(() -> logSecurityLogEvent(data, apkHash));
}
void logSecurityLogEvent(Bundle bundle, String apkHash) {
long startTimestamp = bundle.getLong("startTimestamp");
String processName = bundle.getString("processName");
int uid = bundle.getInt("uid");
String seinfo = bundle.getString("seinfo");
int pid = bundle.getInt("pid");
SecurityLog.writeEvent(SecurityLog.TAG_APP_PROCESS_START, processName,
startTimestamp, uid, pid, seinfo, apkHash);
}
}