Loading services/core/java/com/android/server/pm/DynamicCodeLoggingService.java +14 −13 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import android.util.ByteStringUtils; import android.util.EventLog; import android.util.Log; import com.android.server.pm.dex.DexLogger; import com.android.server.pm.dex.DynamicCodeLogger; import java.util.ArrayList; import java.util.List; Loading @@ -38,9 +38,10 @@ import java.util.regex.Pattern; /** * Scheduled jobs related to logging of app dynamic code loading. The idle logging job runs daily * while idle and charging and calls {@link DexLogger} to write dynamic code information to the * event log. The audit watching job scans the event log periodically while idle to find AVC audit * messages indicating use of dynamic native code and adds the information to {@link DexLogger}. * while idle and charging and calls {@link DynamicCodeLogger} to write dynamic code information * to the event log. The audit watching job scans the event log periodically while idle to find AVC * audit messages indicating use of dynamic native code and adds the information to * {@link DynamicCodeLogger}. * {@hide} */ public class DynamicCodeLoggingService extends JobService { Loading Loading @@ -130,9 +131,9 @@ public class DynamicCodeLoggingService extends JobService { } } private static DexLogger getDexLogger() { private static DynamicCodeLogger getDynamicCodeLogger() { PackageManagerService pm = (PackageManagerService) ServiceManager.getService("package"); return pm.getDexManager().getDexLogger(); return pm.getDexManager().getDynamicCodeLogger(); } private class IdleLoggingThread extends Thread { Loading @@ -149,14 +150,14 @@ public class DynamicCodeLoggingService extends JobService { Log.d(TAG, "Starting IdleLoggingJob run"); } DexLogger dexLogger = getDexLogger(); for (String packageName : dexLogger.getAllPackagesWithDynamicCodeLoading()) { DynamicCodeLogger dynamicCodeLogger = getDynamicCodeLogger(); for (String packageName : dynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) { if (mIdleLoggingStopRequested) { Log.w(TAG, "Stopping IdleLoggingJob run at scheduler request"); return; } dexLogger.logDynamicCodeLoading(packageName); dynamicCodeLogger.logDynamicCodeLoading(packageName); } jobFinished(mParams, /* reschedule */ false); Loading Loading @@ -191,7 +192,7 @@ public class DynamicCodeLoggingService extends JobService { private boolean processAuditEvents() { // Scan the event log for SELinux (avc) audit messages indicating when an // (untrusted) app has executed native code from an app data // file. Matches are recorded in DexLogger. // file. Matches are recorded in DynamicCodeLogger. // // These messages come from the kernel audit system via logd. (Note that // some devices may not generate these messages at all, or the format may Loading @@ -213,7 +214,7 @@ public class DynamicCodeLoggingService extends JobService { // On each run we process all the matching events in the log. This may // mean re-processing events we have already seen, and in any case there // may be duplicate events for the same app+file. These are de-duplicated // by DexLogger. // by DynamicCodeLogger. // // Note that any app can write a message to the event log, including one // that looks exactly like an AVC audit message, so the information may Loading @@ -228,7 +229,7 @@ public class DynamicCodeLoggingService extends JobService { return true; } DexLogger dexLogger = getDexLogger(); DynamicCodeLogger dynamicCodeLogger = getDynamicCodeLogger(); List<EventLog.Event> events = new ArrayList<>(); EventLog.readEvents(tags, events); Loading Loading @@ -267,7 +268,7 @@ public class DynamicCodeLoggingService extends JobService { // hex-encodes the bytes; we need to undo that. path = unhex(matcher.group(2)); } dexLogger.recordNative(uid, path); dynamicCodeLogger.recordNative(uid, path); } return true; Loading services/core/java/com/android/server/pm/dex/DexManager.java +14 −14 Original line number Diff line number Diff line Loading @@ -86,11 +86,11 @@ public class DexManager { // encode and save the dex usage data. private final PackageDexUsage mPackageDexUsage; // DexLogger handles recording of dynamic code loading - which is similar to PackageDexUsage // but records a different aspect of the data. // DynamicCodeLogger handles recording of dynamic code loading - which is similar to // PackageDexUsage but records a different aspect of the data. // (It additionally includes DEX files loaded with unsupported class loaders, and doesn't // record class loaders or ISAs.) private final DexLogger mDexLogger; private final DynamicCodeLogger mDynamicCodeLogger; private final IPackageManager mPackageManager; private final PackageDexOptimizer mPackageDexOptimizer; Loading Loading @@ -126,11 +126,11 @@ public class DexManager { mPackageDexOptimizer = pdo; mInstaller = installer; mInstallLock = installLock; mDexLogger = new DexLogger(pms, installer); mDynamicCodeLogger = new DynamicCodeLogger(pms, installer); } public DexLogger getDexLogger() { return mDexLogger; public DynamicCodeLogger getDynamicCodeLogger() { return mDynamicCodeLogger; } /** Loading Loading @@ -230,8 +230,8 @@ public class DexManager { if (!primaryOrSplit) { // Record loading of a DEX file from an app data directory. mDexLogger.recordDex(loaderUserId, dexPath, searchResult.mOwningPackageName, loadingAppInfo.packageName); mDynamicCodeLogger.recordDex(loaderUserId, dexPath, searchResult.mOwningPackageName, loadingAppInfo.packageName); } if (classLoaderContexts != null) { Loading Loading @@ -269,7 +269,7 @@ public class DexManager { loadInternal(existingPackages); } catch (Exception e) { mPackageDexUsage.clear(); mDexLogger.clear(); mDynamicCodeLogger.clear(); Slog.w(TAG, "Exception while loading. Starting with a fresh state.", e); } } Loading Loading @@ -320,12 +320,12 @@ public class DexManager { if (mPackageDexUsage.removePackage(packageName)) { mPackageDexUsage.maybeWriteAsync(); } mDexLogger.removePackage(packageName); mDynamicCodeLogger.removePackage(packageName); } else { if (mPackageDexUsage.removeUserPackage(packageName, userId)) { mPackageDexUsage.maybeWriteAsync(); } mDexLogger.removeUserPackage(packageName, userId); mDynamicCodeLogger.removeUserPackage(packageName, userId); } } Loading Loading @@ -404,9 +404,9 @@ public class DexManager { } try { mDexLogger.readAndSync(packageToUsersMap); mDynamicCodeLogger.readAndSync(packageToUsersMap); } catch (Exception e) { mDexLogger.clear(); mDynamicCodeLogger.clear(); Slog.w(TAG, "Exception while loading package dynamic code usage. " + "Starting with a fresh state.", e); } Loading Loading @@ -692,7 +692,7 @@ public class DexManager { */ public void writePackageDexUsageNow() { mPackageDexUsage.writeNow(); mDexLogger.writeNow(); mDynamicCodeLogger.writeNow(); } /** Loading services/core/java/com/android/server/pm/dex/DexLogger.java→services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java +9 −9 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License * limitations under the License. */ package com.android.server.pm.dex; Loading Loading @@ -44,12 +44,12 @@ import java.util.Map; import java.util.Set; /** * This class is responsible for logging data about secondary dex files and, despite the name, * native code executed from an app's private directory. The data logged includes hashes of the * name and content of each file. * This class is responsible for logging data about secondary dex files and native code executed * from an app's private directory. The data logged includes hashes of the name and content of each * file. */ public class DexLogger { private static final String TAG = "DexLogger"; public class DynamicCodeLogger { private static final String TAG = "DynamicCodeLogger"; // Event log tag & subtags used for SafetyNet logging of dynamic code loading (DCL) - // see b/63927552. Loading @@ -61,12 +61,12 @@ public class DexLogger { private final PackageDynamicCodeLoading mPackageDynamicCodeLoading; private final Installer mInstaller; public DexLogger(IPackageManager pms, Installer installer) { DynamicCodeLogger(IPackageManager pms, Installer installer) { this(pms, installer, new PackageDynamicCodeLoading()); } @VisibleForTesting DexLogger(IPackageManager pms, Installer installer, DynamicCodeLogger(IPackageManager pms, Installer installer, PackageDynamicCodeLoading packageDynamicCodeLoading) { mPackageManager = pms; mPackageDynamicCodeLoading = packageDynamicCodeLoading; Loading Loading @@ -217,7 +217,7 @@ public class DexLogger { /** * Record that an app running in the specified uid has executed native code from the file at * {@link path}. * {@param path}. */ public void recordNative(int loadingUid, String path) { String[] packages; Loading services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -568,7 +568,8 @@ public class DexManagerTests { } private PackageDynamicCode getPackageDynamicCodeInfo(TestData testData) { return mDexManager.getDexLogger().getPackageDynamicCodeInfo(testData.getPackageName()); return mDexManager.getDynamicCodeLogger() .getPackageDynamicCodeInfo(testData.getPackageName()); } private void assertNoUseInfo(TestData testData) { Loading services/tests/servicestests/src/com/android/server/pm/dex/DexLoggerTests.java→services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java +25 −24 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ import org.mockito.stubbing.Stubber; @RunWith(AndroidJUnit4.class) @SmallTest public class DexLoggerTests { public class DynamicCodeLoggerTests { private static final String OWNING_PACKAGE_NAME = "package.name"; private static final String VOLUME_UUID = "volUuid"; private static final String FILE_PATH = "/bar/foo.jar"; Loading Loading @@ -85,7 +85,7 @@ public class DexLoggerTests { @Mock IPackageManager mPM; @Mock Installer mInstaller; private DexLogger mDexLogger; private DynamicCodeLogger mDynamicCodeLogger; private final ListMultimap<Integer, String> mMessagesForUid = ArrayListMultimap.create(); private boolean mWriteTriggered = false; Loading @@ -106,7 +106,7 @@ public class DexLoggerTests { }; // For test purposes capture log messages as well as sending to the event log. mDexLogger = new DexLogger(mPM, mInstaller, packageDynamicCodeLoading) { mDynamicCodeLogger = new DynamicCodeLogger(mPM, mInstaller, packageDynamicCodeLoading) { @Override void writeDclEvent(String subtag, int uid, String message) { super.writeDclEvent(subtag, uid, message); Loading @@ -131,13 +131,13 @@ public class DexLoggerTests { whenFileIsHashed(FILE_PATH, doReturn(CONTENT_HASH_BYTES)); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(OWNER_UID); assertThat(mMessagesForUid).containsEntry(OWNER_UID, EXPECTED_MESSAGE_WITH_CONTENT_HASH); assertThat(mWriteTriggered).isFalse(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()) assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) .containsExactly(OWNING_PACKAGE_NAME); } Loading @@ -146,14 +146,14 @@ public class DexLoggerTests { whenFileIsHashed(FILE_PATH, doReturn(EMPTY_BYTES)); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(OWNER_UID); assertThat(mMessagesForUid).containsEntry(OWNER_UID, EXPECTED_MESSAGE_WITHOUT_CONTENT_HASH); // File should be removed from the DCL list, since we can't hash it. assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); } @Test Loading @@ -162,24 +162,24 @@ public class DexLoggerTests { doThrow(new InstallerException("Intentional failure for test"))); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(OWNER_UID); assertThat(mMessagesForUid).containsEntry(OWNER_UID, EXPECTED_MESSAGE_WITHOUT_CONTENT_HASH); // File should be removed from the DCL list, since we can't hash it. assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); } @Test public void testOneLoader_ownFile_unknownPath() { recordLoad(OWNING_PACKAGE_NAME, "other/path"); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid).isEmpty(); assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); } @Test Loading @@ -189,7 +189,7 @@ public class DexLoggerTests { setPackageUid(OWNING_PACKAGE_NAME, -1); recordLoad(OWNING_PACKAGE_NAME, filePath); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid).isEmpty(); } Loading @@ -200,7 +200,7 @@ public class DexLoggerTests { setPackageUid("other.package.name", 1001); recordLoad("other.package.name", FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(1001); assertThat(mMessagesForUid).containsEntry(1001, EXPECTED_MESSAGE_WITH_CONTENT_HASH); Loading @@ -213,7 +213,7 @@ public class DexLoggerTests { setPackageUid("other.package.name", -1); recordLoad("other.package.name", FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid).isEmpty(); assertThat(mWriteTriggered).isFalse(); Loading @@ -224,14 +224,14 @@ public class DexLoggerTests { whenFileIsHashed(FILE_PATH, doReturn(CONTENT_HASH_BYTES)); recordLoadNative(FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(OWNER_UID); assertThat(mMessagesForUid) .containsEntry(OWNER_UID, EXPECTED_MESSAGE_NATIVE_WITH_CONTENT_HASH); assertThat(mWriteTriggered).isFalse(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()) assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) .containsExactly(OWNING_PACKAGE_NAME); } Loading @@ -247,7 +247,7 @@ public class DexLoggerTests { recordLoad("other.package.name1", otherDexPath); recordLoad("other.package.name2", FILE_PATH); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(1001, 1001, 1002, OWNER_UID); assertThat(mMessagesForUid).containsEntry(1001, EXPECTED_MESSAGE_WITH_CONTENT_HASH); Loading @@ -256,10 +256,10 @@ public class DexLoggerTests { assertThat(mMessagesForUid).containsEntry(OWNER_UID, EXPECTED_MESSAGE_WITH_CONTENT_HASH); assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()) assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) .containsExactly(OWNING_PACKAGE_NAME); // Check the DexLogger caching is working // Check the DynamicCodeLogger caching is working verify(mPM, atMost(1)).getPackageInfo(OWNING_PACKAGE_NAME, /*flags*/ 0, OWNER_USER_ID); } Loading @@ -267,7 +267,7 @@ public class DexLoggerTests { public void testUnknownOwner() { reset(mPM); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading("other.package.name"); mDynamicCodeLogger.logDynamicCodeLoading("other.package.name"); assertThat(mMessagesForUid).isEmpty(); assertThat(mWriteTriggered).isFalse(); Loading @@ -278,11 +278,11 @@ public class DexLoggerTests { public void testUninstalledPackage() { reset(mPM); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid).isEmpty(); assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); } private void setPackageUid(String packageName, int uid) throws Exception { Loading @@ -295,7 +295,8 @@ public class DexLoggerTests { } private void recordLoad(String loadingPackageName, String dexPath) { mDexLogger.recordDex(OWNER_USER_ID, dexPath, OWNING_PACKAGE_NAME, loadingPackageName); mDynamicCodeLogger.recordDex( OWNER_USER_ID, dexPath, OWNING_PACKAGE_NAME, loadingPackageName); mWriteTriggered = false; } Loading @@ -304,7 +305,7 @@ public class DexLoggerTests { String[] packageNames = { OWNING_PACKAGE_NAME }; when(mPM.getPackagesForUid(loadingUid)).thenReturn(packageNames); mDexLogger.recordNative(loadingUid, nativePath); mDynamicCodeLogger.recordNative(loadingUid, nativePath); mWriteTriggered = false; } } Loading
services/core/java/com/android/server/pm/DynamicCodeLoggingService.java +14 −13 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import android.util.ByteStringUtils; import android.util.EventLog; import android.util.Log; import com.android.server.pm.dex.DexLogger; import com.android.server.pm.dex.DynamicCodeLogger; import java.util.ArrayList; import java.util.List; Loading @@ -38,9 +38,10 @@ import java.util.regex.Pattern; /** * Scheduled jobs related to logging of app dynamic code loading. The idle logging job runs daily * while idle and charging and calls {@link DexLogger} to write dynamic code information to the * event log. The audit watching job scans the event log periodically while idle to find AVC audit * messages indicating use of dynamic native code and adds the information to {@link DexLogger}. * while idle and charging and calls {@link DynamicCodeLogger} to write dynamic code information * to the event log. The audit watching job scans the event log periodically while idle to find AVC * audit messages indicating use of dynamic native code and adds the information to * {@link DynamicCodeLogger}. * {@hide} */ public class DynamicCodeLoggingService extends JobService { Loading Loading @@ -130,9 +131,9 @@ public class DynamicCodeLoggingService extends JobService { } } private static DexLogger getDexLogger() { private static DynamicCodeLogger getDynamicCodeLogger() { PackageManagerService pm = (PackageManagerService) ServiceManager.getService("package"); return pm.getDexManager().getDexLogger(); return pm.getDexManager().getDynamicCodeLogger(); } private class IdleLoggingThread extends Thread { Loading @@ -149,14 +150,14 @@ public class DynamicCodeLoggingService extends JobService { Log.d(TAG, "Starting IdleLoggingJob run"); } DexLogger dexLogger = getDexLogger(); for (String packageName : dexLogger.getAllPackagesWithDynamicCodeLoading()) { DynamicCodeLogger dynamicCodeLogger = getDynamicCodeLogger(); for (String packageName : dynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) { if (mIdleLoggingStopRequested) { Log.w(TAG, "Stopping IdleLoggingJob run at scheduler request"); return; } dexLogger.logDynamicCodeLoading(packageName); dynamicCodeLogger.logDynamicCodeLoading(packageName); } jobFinished(mParams, /* reschedule */ false); Loading Loading @@ -191,7 +192,7 @@ public class DynamicCodeLoggingService extends JobService { private boolean processAuditEvents() { // Scan the event log for SELinux (avc) audit messages indicating when an // (untrusted) app has executed native code from an app data // file. Matches are recorded in DexLogger. // file. Matches are recorded in DynamicCodeLogger. // // These messages come from the kernel audit system via logd. (Note that // some devices may not generate these messages at all, or the format may Loading @@ -213,7 +214,7 @@ public class DynamicCodeLoggingService extends JobService { // On each run we process all the matching events in the log. This may // mean re-processing events we have already seen, and in any case there // may be duplicate events for the same app+file. These are de-duplicated // by DexLogger. // by DynamicCodeLogger. // // Note that any app can write a message to the event log, including one // that looks exactly like an AVC audit message, so the information may Loading @@ -228,7 +229,7 @@ public class DynamicCodeLoggingService extends JobService { return true; } DexLogger dexLogger = getDexLogger(); DynamicCodeLogger dynamicCodeLogger = getDynamicCodeLogger(); List<EventLog.Event> events = new ArrayList<>(); EventLog.readEvents(tags, events); Loading Loading @@ -267,7 +268,7 @@ public class DynamicCodeLoggingService extends JobService { // hex-encodes the bytes; we need to undo that. path = unhex(matcher.group(2)); } dexLogger.recordNative(uid, path); dynamicCodeLogger.recordNative(uid, path); } return true; Loading
services/core/java/com/android/server/pm/dex/DexManager.java +14 −14 Original line number Diff line number Diff line Loading @@ -86,11 +86,11 @@ public class DexManager { // encode and save the dex usage data. private final PackageDexUsage mPackageDexUsage; // DexLogger handles recording of dynamic code loading - which is similar to PackageDexUsage // but records a different aspect of the data. // DynamicCodeLogger handles recording of dynamic code loading - which is similar to // PackageDexUsage but records a different aspect of the data. // (It additionally includes DEX files loaded with unsupported class loaders, and doesn't // record class loaders or ISAs.) private final DexLogger mDexLogger; private final DynamicCodeLogger mDynamicCodeLogger; private final IPackageManager mPackageManager; private final PackageDexOptimizer mPackageDexOptimizer; Loading Loading @@ -126,11 +126,11 @@ public class DexManager { mPackageDexOptimizer = pdo; mInstaller = installer; mInstallLock = installLock; mDexLogger = new DexLogger(pms, installer); mDynamicCodeLogger = new DynamicCodeLogger(pms, installer); } public DexLogger getDexLogger() { return mDexLogger; public DynamicCodeLogger getDynamicCodeLogger() { return mDynamicCodeLogger; } /** Loading Loading @@ -230,8 +230,8 @@ public class DexManager { if (!primaryOrSplit) { // Record loading of a DEX file from an app data directory. mDexLogger.recordDex(loaderUserId, dexPath, searchResult.mOwningPackageName, loadingAppInfo.packageName); mDynamicCodeLogger.recordDex(loaderUserId, dexPath, searchResult.mOwningPackageName, loadingAppInfo.packageName); } if (classLoaderContexts != null) { Loading Loading @@ -269,7 +269,7 @@ public class DexManager { loadInternal(existingPackages); } catch (Exception e) { mPackageDexUsage.clear(); mDexLogger.clear(); mDynamicCodeLogger.clear(); Slog.w(TAG, "Exception while loading. Starting with a fresh state.", e); } } Loading Loading @@ -320,12 +320,12 @@ public class DexManager { if (mPackageDexUsage.removePackage(packageName)) { mPackageDexUsage.maybeWriteAsync(); } mDexLogger.removePackage(packageName); mDynamicCodeLogger.removePackage(packageName); } else { if (mPackageDexUsage.removeUserPackage(packageName, userId)) { mPackageDexUsage.maybeWriteAsync(); } mDexLogger.removeUserPackage(packageName, userId); mDynamicCodeLogger.removeUserPackage(packageName, userId); } } Loading Loading @@ -404,9 +404,9 @@ public class DexManager { } try { mDexLogger.readAndSync(packageToUsersMap); mDynamicCodeLogger.readAndSync(packageToUsersMap); } catch (Exception e) { mDexLogger.clear(); mDynamicCodeLogger.clear(); Slog.w(TAG, "Exception while loading package dynamic code usage. " + "Starting with a fresh state.", e); } Loading Loading @@ -692,7 +692,7 @@ public class DexManager { */ public void writePackageDexUsageNow() { mPackageDexUsage.writeNow(); mDexLogger.writeNow(); mDynamicCodeLogger.writeNow(); } /** Loading
services/core/java/com/android/server/pm/dex/DexLogger.java→services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java +9 −9 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License * limitations under the License. */ package com.android.server.pm.dex; Loading Loading @@ -44,12 +44,12 @@ import java.util.Map; import java.util.Set; /** * This class is responsible for logging data about secondary dex files and, despite the name, * native code executed from an app's private directory. The data logged includes hashes of the * name and content of each file. * This class is responsible for logging data about secondary dex files and native code executed * from an app's private directory. The data logged includes hashes of the name and content of each * file. */ public class DexLogger { private static final String TAG = "DexLogger"; public class DynamicCodeLogger { private static final String TAG = "DynamicCodeLogger"; // Event log tag & subtags used for SafetyNet logging of dynamic code loading (DCL) - // see b/63927552. Loading @@ -61,12 +61,12 @@ public class DexLogger { private final PackageDynamicCodeLoading mPackageDynamicCodeLoading; private final Installer mInstaller; public DexLogger(IPackageManager pms, Installer installer) { DynamicCodeLogger(IPackageManager pms, Installer installer) { this(pms, installer, new PackageDynamicCodeLoading()); } @VisibleForTesting DexLogger(IPackageManager pms, Installer installer, DynamicCodeLogger(IPackageManager pms, Installer installer, PackageDynamicCodeLoading packageDynamicCodeLoading) { mPackageManager = pms; mPackageDynamicCodeLoading = packageDynamicCodeLoading; Loading Loading @@ -217,7 +217,7 @@ public class DexLogger { /** * Record that an app running in the specified uid has executed native code from the file at * {@link path}. * {@param path}. */ public void recordNative(int loadingUid, String path) { String[] packages; Loading
services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -568,7 +568,8 @@ public class DexManagerTests { } private PackageDynamicCode getPackageDynamicCodeInfo(TestData testData) { return mDexManager.getDexLogger().getPackageDynamicCodeInfo(testData.getPackageName()); return mDexManager.getDynamicCodeLogger() .getPackageDynamicCodeInfo(testData.getPackageName()); } private void assertNoUseInfo(TestData testData) { Loading
services/tests/servicestests/src/com/android/server/pm/dex/DexLoggerTests.java→services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java +25 −24 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ import org.mockito.stubbing.Stubber; @RunWith(AndroidJUnit4.class) @SmallTest public class DexLoggerTests { public class DynamicCodeLoggerTests { private static final String OWNING_PACKAGE_NAME = "package.name"; private static final String VOLUME_UUID = "volUuid"; private static final String FILE_PATH = "/bar/foo.jar"; Loading Loading @@ -85,7 +85,7 @@ public class DexLoggerTests { @Mock IPackageManager mPM; @Mock Installer mInstaller; private DexLogger mDexLogger; private DynamicCodeLogger mDynamicCodeLogger; private final ListMultimap<Integer, String> mMessagesForUid = ArrayListMultimap.create(); private boolean mWriteTriggered = false; Loading @@ -106,7 +106,7 @@ public class DexLoggerTests { }; // For test purposes capture log messages as well as sending to the event log. mDexLogger = new DexLogger(mPM, mInstaller, packageDynamicCodeLoading) { mDynamicCodeLogger = new DynamicCodeLogger(mPM, mInstaller, packageDynamicCodeLoading) { @Override void writeDclEvent(String subtag, int uid, String message) { super.writeDclEvent(subtag, uid, message); Loading @@ -131,13 +131,13 @@ public class DexLoggerTests { whenFileIsHashed(FILE_PATH, doReturn(CONTENT_HASH_BYTES)); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(OWNER_UID); assertThat(mMessagesForUid).containsEntry(OWNER_UID, EXPECTED_MESSAGE_WITH_CONTENT_HASH); assertThat(mWriteTriggered).isFalse(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()) assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) .containsExactly(OWNING_PACKAGE_NAME); } Loading @@ -146,14 +146,14 @@ public class DexLoggerTests { whenFileIsHashed(FILE_PATH, doReturn(EMPTY_BYTES)); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(OWNER_UID); assertThat(mMessagesForUid).containsEntry(OWNER_UID, EXPECTED_MESSAGE_WITHOUT_CONTENT_HASH); // File should be removed from the DCL list, since we can't hash it. assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); } @Test Loading @@ -162,24 +162,24 @@ public class DexLoggerTests { doThrow(new InstallerException("Intentional failure for test"))); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(OWNER_UID); assertThat(mMessagesForUid).containsEntry(OWNER_UID, EXPECTED_MESSAGE_WITHOUT_CONTENT_HASH); // File should be removed from the DCL list, since we can't hash it. assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); } @Test public void testOneLoader_ownFile_unknownPath() { recordLoad(OWNING_PACKAGE_NAME, "other/path"); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid).isEmpty(); assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); } @Test Loading @@ -189,7 +189,7 @@ public class DexLoggerTests { setPackageUid(OWNING_PACKAGE_NAME, -1); recordLoad(OWNING_PACKAGE_NAME, filePath); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid).isEmpty(); } Loading @@ -200,7 +200,7 @@ public class DexLoggerTests { setPackageUid("other.package.name", 1001); recordLoad("other.package.name", FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(1001); assertThat(mMessagesForUid).containsEntry(1001, EXPECTED_MESSAGE_WITH_CONTENT_HASH); Loading @@ -213,7 +213,7 @@ public class DexLoggerTests { setPackageUid("other.package.name", -1); recordLoad("other.package.name", FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid).isEmpty(); assertThat(mWriteTriggered).isFalse(); Loading @@ -224,14 +224,14 @@ public class DexLoggerTests { whenFileIsHashed(FILE_PATH, doReturn(CONTENT_HASH_BYTES)); recordLoadNative(FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(OWNER_UID); assertThat(mMessagesForUid) .containsEntry(OWNER_UID, EXPECTED_MESSAGE_NATIVE_WITH_CONTENT_HASH); assertThat(mWriteTriggered).isFalse(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()) assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) .containsExactly(OWNING_PACKAGE_NAME); } Loading @@ -247,7 +247,7 @@ public class DexLoggerTests { recordLoad("other.package.name1", otherDexPath); recordLoad("other.package.name2", FILE_PATH); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid.keys()).containsExactly(1001, 1001, 1002, OWNER_UID); assertThat(mMessagesForUid).containsEntry(1001, EXPECTED_MESSAGE_WITH_CONTENT_HASH); Loading @@ -256,10 +256,10 @@ public class DexLoggerTests { assertThat(mMessagesForUid).containsEntry(OWNER_UID, EXPECTED_MESSAGE_WITH_CONTENT_HASH); assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()) assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) .containsExactly(OWNING_PACKAGE_NAME); // Check the DexLogger caching is working // Check the DynamicCodeLogger caching is working verify(mPM, atMost(1)).getPackageInfo(OWNING_PACKAGE_NAME, /*flags*/ 0, OWNER_USER_ID); } Loading @@ -267,7 +267,7 @@ public class DexLoggerTests { public void testUnknownOwner() { reset(mPM); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading("other.package.name"); mDynamicCodeLogger.logDynamicCodeLoading("other.package.name"); assertThat(mMessagesForUid).isEmpty(); assertThat(mWriteTriggered).isFalse(); Loading @@ -278,11 +278,11 @@ public class DexLoggerTests { public void testUninstalledPackage() { reset(mPM); recordLoad(OWNING_PACKAGE_NAME, FILE_PATH); mDexLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); mDynamicCodeLogger.logDynamicCodeLoading(OWNING_PACKAGE_NAME); assertThat(mMessagesForUid).isEmpty(); assertThat(mWriteTriggered).isTrue(); assertThat(mDexLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); assertThat(mDynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()).isEmpty(); } private void setPackageUid(String packageName, int uid) throws Exception { Loading @@ -295,7 +295,8 @@ public class DexLoggerTests { } private void recordLoad(String loadingPackageName, String dexPath) { mDexLogger.recordDex(OWNER_USER_ID, dexPath, OWNING_PACKAGE_NAME, loadingPackageName); mDynamicCodeLogger.recordDex( OWNER_USER_ID, dexPath, OWNING_PACKAGE_NAME, loadingPackageName); mWriteTriggered = false; } Loading @@ -304,7 +305,7 @@ public class DexLoggerTests { String[] packageNames = { OWNING_PACKAGE_NAME }; when(mPM.getPackagesForUid(loadingUid)).thenReturn(packageNames); mDexLogger.recordNative(loadingUid, nativePath); mDynamicCodeLogger.recordNative(loadingUid, nativePath); mWriteTriggered = false; } }