From 8a111b8b0039690f2ce661e0964799d05f5efa3e Mon Sep 17 00:00:00 2001 From: Victor Hsieh Date: Mon, 12 Dec 2022 10:47:55 -0800 Subject: [PATCH] Fix preinstalled path of APEX When package name of one APEX is a prefix of another, the binary transparency service may return the wrong preinstalled path and measurement. For example, preinstall path of com.android.media should not be /system/apex/com.android.media.swcodec.capex. Besides fixing the issue, the implementation is switched from iterating the /system/apex directory, to querying apexservice. This may give us vendor APEX for free, though I haven't been able to confirm yet. Bug: 262259909 Test: Diff `adb shell cmd transparency get apex_info -v` before and after. Saw the only change is the corrected pre-install path. Change-Id: Ib7cc87dee17091c379c679cd5bece49120077f54 --- .../server/BinaryTransparencyService.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java index 6cd7ce8a1c43a..6016df8d1056c 100644 --- a/services/core/java/com/android/server/BinaryTransparencyService.java +++ b/services/core/java/com/android/server/BinaryTransparencyService.java @@ -19,6 +19,8 @@ package com.android.server; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; +import android.apex.ApexInfo; +import android.apex.IApexService; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobScheduler; @@ -39,6 +41,7 @@ import android.content.pm.SigningInfo; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseResult; import android.content.pm.parsing.result.ParseTypeImpl; +import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; @@ -61,7 +64,6 @@ import com.android.internal.util.FrameworkStatsLog; import libcore.util.HexEncoding; -import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; import java.security.PublicKey; @@ -73,7 +75,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.Executors; import java.util.stream.Collectors; -import java.util.stream.Stream; /** * @hide @@ -105,7 +106,6 @@ public class BinaryTransparencyService extends SystemService { @VisibleForTesting static final String BUNDLE_CONTENT_DIGEST = "content-digest"; - static final String APEX_PRELOAD_LOCATION = "/system/apex/"; static final String APEX_PRELOAD_LOCATION_ERROR = "could-not-be-determined"; // used for indicating any type of error during MBA measurement @@ -320,9 +320,7 @@ public class BinaryTransparencyService extends SystemService { FrameworkStatsLog.write(FrameworkStatsLog.MOBILE_BUNDLED_APP_INFO_GATHERED, packageInfo.packageName, packageInfo.getLongVersionCode(), - (cDigest != null) ? HexEncoding.encodeToString( - packageMeasurement.getByteArray(BUNDLE_CONTENT_DIGEST), - false) : null, + (cDigest != null) ? HexEncoding.encodeToString(cDigest, false) : null, packageMeasurement.getInt(BUNDLE_CONTENT_DIGEST_ALGORITHM), signerDigestHexStrings, // signer_cert_digest mba_status, // mba_status @@ -381,9 +379,7 @@ public class BinaryTransparencyService extends SystemService { FrameworkStatsLog.write(FrameworkStatsLog.MOBILE_BUNDLED_APP_INFO_GATHERED, packageInfo.packageName, packageInfo.getLongVersionCode(), - (cDigest != null) ? HexEncoding.encodeToString( - packageMeasurement.getByteArray(BUNDLE_CONTENT_DIGEST), - false) : null, + (cDigest != null) ? HexEncoding.encodeToString(cDigest, false) : null, packageMeasurement.getInt(BUNDLE_CONTENT_DIGEST_ALGORITHM), signerDigestHexStrings, MBA_STATUS_NEW_INSTALL, // mba_status @@ -1096,19 +1092,18 @@ public class BinaryTransparencyService extends SystemService { @NonNull private String getOriginalApexPreinstalledLocation(String packageName, - String currentInstalledLocation) { - // get a listing of all apex files in /system/apex/ - Set originalApexs = Stream.of(new File(APEX_PRELOAD_LOCATION).listFiles()) - .filter(f -> !f.isDirectory()) - .map(File::getName) - .collect(Collectors.toSet()); - - for (String originalApex : originalApexs) { - if (originalApex.startsWith(packageName)) { - return APEX_PRELOAD_LOCATION + originalApex; + String currentInstalledLocation) { + try { + IApexService apexService = IApexService.Stub.asInterface( + Binder.allowBlocking(ServiceManager.waitForService("apexservice"))); + for (ApexInfo info : apexService.getAllPackages()) { + if (packageName.equals(info.moduleName)) { + return info.preinstalledModulePath; + } } + } catch (RemoteException e) { + Slog.e(TAG, "Unable to get package list from apexservice", e); } - return APEX_PRELOAD_LOCATION_ERROR; }