Revamp BinaryTransparencyService.

BinaryTransparencyService:
- change default binary measurement method from SHA256 digest to
  APK content digest. This allows for more performant measurements.

- got rid of in-memory caches of digest results because:
  a) larger scope: more binaries will be covered (in the magnitude
     of hundreds);
  b) the digest length using APK content digest might be longer than
     256 bits: e.g. CHUNKED_SHA512 which is 512 bits;
  c) the computation of these new digests are not as computationally
     intensive that it causes noticible lags even when commands are
     invoked repeatedly in adb shell.

- changed scheduled job to be scheduled periodically (once in a 24
  hour period) instead of a one-off job.

- make use of method calls to BackgroundInstallControlService (BICS)
  to obtain list of newly installed mobile bundled apps (MBAs).

BinaryTransparencyServiceTest:
- modified the return type for `getApexInfo` to receive a List instead
 of Map.

Bug: 245944666

Test: atest BinaryTransparencyServiceTest.
      Also, adb shell cmd jobscheduler run android <job-id>.
      <job-id> can be found in debug printouts with TransparencyService
      tag.
Change-Id: Ie305e71c514f4fb65b9e640301093ec83f01f718
This commit is contained in:
Billy Lau
2022-11-15 11:14:43 -06:00
parent 9ae00a02ad
commit 0f55c59324
4 changed files with 646 additions and 274 deletions

View File

@@ -24,7 +24,7 @@ import android.util.Slog;
import com.android.internal.os.IBinaryTransparencyService;
import java.util.Map;
import java.util.List;
/**
* BinaryTransparencyManager defines a number of system interfaces that other system apps or
@@ -66,12 +66,15 @@ public class BinaryTransparencyManager {
}
/**
* Returns a map of all installed APEXs consisting of package name to SHA256 hash of the
* package.
* @return A Map with the following entries: {apex package name : sha256 digest of package}
* Gets binary measurements of all installed APEXs, each packed in a Bundle.
* @return A List of {@link android.os.Bundle}s with the following keys:
* {@link com.android.server.BinaryTransparencyService#BUNDLE_PACKAGE_INFO}
* {@link com.android.server.BinaryTransparencyService#BUNDLE_CONTENT_DIGEST_ALGORITHM}
* {@link com.android.server.BinaryTransparencyService#BUNDLE_CONTENT_DIGEST}
*/
// TODO(b/259422958): Fix static constants referenced here - should be defined here
@NonNull
public Map getApexInfo() {
public List getApexInfo() {
try {
Slog.d(TAG, "Calling backend's getApexInfo()");
return mService.getApexInfo();

View File

@@ -26,5 +26,7 @@ package com.android.internal.os;
interface IBinaryTransparencyService {
String getSignedImageInfo();
Map getApexInfo();
List getApexInfo();
List getMeasurementsForAllPackages();
}

View File

@@ -23,6 +23,7 @@ import android.app.job.JobScheduler;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemProperties;
@@ -36,8 +37,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.FileDescriptor;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class BinaryTransparencyServiceTest {
@@ -96,7 +96,7 @@ public class BinaryTransparencyServiceTest {
@Test
public void getApexInfo_postInitialize_returnsValidEntries() throws RemoteException {
prepApexInfo();
Map result = mTestInterface.getApexInfo();
List result = mTestInterface.getApexInfo();
Assert.assertNotNull("Apex info map should not be null", result);
Assert.assertFalse("Apex info map should not be empty", result.isEmpty());
}
@@ -105,13 +105,18 @@ public class BinaryTransparencyServiceTest {
public void getApexInfo_postInitialize_returnsActualApexs()
throws RemoteException, PackageManager.NameNotFoundException {
prepApexInfo();
Map result = mTestInterface.getApexInfo();
List resultList = mTestInterface.getApexInfo();
PackageManager pm = mContext.getPackageManager();
Assert.assertNotNull(pm);
HashMap<PackageInfo, String> castedResult = (HashMap<PackageInfo, String>) result;
for (PackageInfo packageInfo : castedResult.keySet()) {
Assert.assertTrue(packageInfo.packageName + "is not an APEX!", packageInfo.isApex);
List<Bundle> castedResult = (List<Bundle>) resultList;
for (Bundle resultBundle : castedResult) {
PackageInfo resultPackageInfo = resultBundle.getParcelable(
BinaryTransparencyService.BUNDLE_PACKAGE_INFO, PackageInfo.class);
Assert.assertNotNull("PackageInfo for APEX should not be null",
resultPackageInfo);
Assert.assertTrue(resultPackageInfo.packageName + "is not an APEX!",
resultPackageInfo.isApex);
}
}