1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.pm.dex; 18 19 import android.content.pm.ApplicationInfo; 20 import android.content.pm.IPackageManager; 21 import android.os.RemoteException; 22 23 import android.util.ArraySet; 24 import android.util.ByteStringUtils; 25 import android.util.EventLog; 26 import android.util.PackageUtils; 27 import android.util.Slog; 28 29 import com.android.internal.annotations.GuardedBy; 30 import com.android.internal.annotations.VisibleForTesting; 31 import com.android.server.pm.Installer; 32 import com.android.server.pm.Installer.InstallerException; 33 34 import java.io.File; 35 import java.util.Set; 36 37 import static com.android.server.pm.dex.PackageDexUsage.DexUseInfo; 38 39 /** 40 * This class is responsible for logging data about secondary dex files. 41 * The data logged includes hashes of the name and content of each file. 42 */ 43 public class DexLogger implements DexManager.Listener { 44 private static final String TAG = "DexLogger"; 45 46 // Event log tag & subtag used for SafetyNet logging of dynamic 47 // code loading (DCL) - see b/63927552. 48 private static final int SNET_TAG = 0x534e4554; 49 private static final String DCL_SUBTAG = "dcl"; 50 51 private final IPackageManager mPackageManager; 52 private final Object mInstallLock; 53 @GuardedBy("mInstallLock") 54 private final Installer mInstaller; 55 56 public static DexManager.Listener getListener(IPackageManager pms, 57 Installer installer, Object installLock) { 58 return new DexLogger(pms, installer, installLock); 59 } 60 61 @VisibleForTesting 62 /*package*/ DexLogger(IPackageManager pms, Installer installer, Object installLock) { 63 mPackageManager = pms; 64 mInstaller = installer; 65 mInstallLock = installLock; 66 } 67 68 /** 69 * Compute and log hashes of the name and content of a secondary dex file. 70 */ 71 @Override 72 public void onReconcileSecondaryDexFile(ApplicationInfo appInfo, DexUseInfo dexUseInfo, 73 String dexPath, int storageFlags) { 74 int ownerUid = appInfo.uid; 75 76 byte[] hash = null; 77 synchronized(mInstallLock) { 78 try { 79 hash = mInstaller.hashSecondaryDexFile(dexPath, appInfo.packageName, 80 ownerUid, appInfo.volumeUuid, storageFlags); 81 } catch (InstallerException e) { 82 Slog.e(TAG, "Got InstallerException when hashing dex " + dexPath + 83 " : " + e.getMessage()); 84 } 85 } 86 if (hash == null) { 87 return; 88 } 89 90 String dexFileName = new File(dexPath).getName(); 91 String message = PackageUtils.computeSha256Digest(dexFileName.getBytes()); 92 // Valid SHA256 will be 256 bits, 32 bytes. 93 if (hash.length == 32) { 94 message = message + ' ' + ByteStringUtils.toHexString(hash); 95 } 96 97 writeDclEvent(ownerUid, message); 98 99 if (dexUseInfo.isUsedByOtherApps()) { 100 Set<String> otherPackages = dexUseInfo.getLoadingPackages(); 101 Set<Integer> otherUids = new ArraySet<>(otherPackages.size()); 102 for (String otherPackageName : otherPackages) { 103 try { 104 int otherUid = mPackageManager.getPackageUid( 105 otherPackageName, /*flags*/0, dexUseInfo.getOwnerUserId()); 106 if (otherUid != -1 && otherUid != ownerUid) { 107 otherUids.add(otherUid); 108 } 109 } catch (RemoteException ignore) { 110 // Can't happen, we're local. 111 } 112 } 113 for (int otherUid : otherUids) { 114 writeDclEvent(otherUid, message); 115 } 116 } 117 } 118 119 @VisibleForTesting 120 /*package*/ void writeDclEvent(int uid, String message) { 121 EventLog.writeEvent(SNET_TAG, DCL_SUBTAG, uid, message); 122 } 123 } 124