summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/android/content/pm/PackageManagerInternal.java15
-rw-r--r--services/core/java/com/android/server/integrity/AppIntegrityManagerService.java43
-rw-r--r--services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java80
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java13
-rw-r--r--services/java/com/android/server/SystemServer.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java72
6 files changed, 228 insertions, 0 deletions
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 21f5f899e75c..53f306bae8e5 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -822,4 +822,19 @@ public abstract class PackageManagerInternal {
/** Sets the enforcement of reading external storage */
public abstract void setReadExternalStorageEnforced(boolean enforced);
+
+ /**
+ * Allows the integrity component to respond to the
+ * {@link Intent#ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION package verification
+ * broadcast} to respond to the package manager. The response must include
+ * the {@code verificationCode} which is one of
+ * {@link PackageManager#VERIFICATION_ALLOW} or
+ * {@link PackageManager#VERIFICATION_REJECT}.
+ *
+ * @param verificationId pending package identifier as passed via the
+ * {@link PackageManager#EXTRA_VERIFICATION_ID} Intent extra.
+ * @param verificationResult either {@link PackageManager#VERIFICATION_ALLOW}
+ * or {@link PackageManager#VERIFICATION_REJECT}.
+ */
+ public abstract void setIntegrityVerificationResult(int verificationId, int verificationResult);
}
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerService.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerService.java
new file mode 100644
index 000000000000..005fb696b089
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerService.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.server.integrity;
+
+import android.content.Context;
+
+import com.android.server.SystemService;
+
+/**
+ * Service that manages app integrity rules and verifications.
+ *
+ * @hide
+ */
+public class AppIntegrityManagerService extends SystemService {
+
+ private Context mContext;
+ private AppIntegrityManagerServiceImpl mService;
+
+ public AppIntegrityManagerService(Context context) {
+ super(context);
+ mContext = context;
+ }
+
+ @Override
+ public void onStart() {
+ mService = new AppIntegrityManagerServiceImpl(mContext);
+ // TODO: define and publish a binder service.
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
new file mode 100644
index 000000000000..39c1b8535565
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.server.integrity;
+
+import static android.content.Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION;
+import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+
+/** Implementation of {@link AppIntegrityManagerService}. */
+class AppIntegrityManagerServiceImpl {
+ private static final String TAG = "AppIntegrityManagerServiceImpl";
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final PackageManagerInternal mPackageManagerInternal;
+
+ AppIntegrityManagerServiceImpl(Context context) {
+ mContext = context;
+
+ HandlerThread handlerThread = new HandlerThread("AppIntegrityManagerServiceHandler");
+ handlerThread.start();
+ mHandler = handlerThread.getThreadHandler();
+
+ mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
+
+ IntentFilter integrityVerificationFilter = new IntentFilter();
+ integrityVerificationFilter.addAction(ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
+
+ mContext.registerReceiver(
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION.equals(
+ intent.getAction())) {
+ return;
+ }
+ mHandler.post(() -> handleIntegrityVerification(intent));
+ }
+ },
+ integrityVerificationFilter,
+ /* broadcastPermission= */ null,
+ mHandler);
+ }
+
+ // protected broadcasts cannot be sent in the test.
+ @VisibleForTesting
+ void handleIntegrityVerification(Intent intent) {
+ int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1);
+ // TODO: implement this method.
+ Slog.i(TAG, "Received integrity verification intent " + intent.toString());
+ mPackageManagerInternal.setIntegrityVerificationResult(
+ verificationId, PackageManager.VERIFICATION_ALLOW);
+ }
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 73ab82dc01b2..aa6c6c7a2f45 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1439,6 +1439,7 @@ public class PackageManagerService extends IPackageManager.Stub
static final int ENABLE_ROLLBACK_TIMEOUT = 22;
static final int DEFERRED_NO_KILL_POST_DELETE = 23;
static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
+ static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
@@ -1763,6 +1764,10 @@ public class PackageManagerService extends IPackageManager.Stub
break;
}
+ case INTEGRITY_VERIFICATION_COMPLETE: {
+ // TODO: implement this case.
+ break;
+ }
case START_INTENT_FILTER_VERIFICATIONS: {
IFVerificationParams params = (IFVerificationParams) msg.obj;
verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, params.replacing,
@@ -23199,6 +23204,14 @@ public class PackageManagerService extends IPackageManager.Stub
mSettings.writeLPr();
}
}
+
+ @Override
+ public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
+ final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
+ msg.arg1 = verificationId;
+ msg.obj = verificationResult;
+ mHandler.sendMessage(msg);
+ }
}
@GuardedBy("mLock")
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 21cacd45dcb5..b6e501a785ef 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -109,6 +109,7 @@ import com.android.server.input.InputManagerService;
import com.android.server.inputmethod.InputMethodManagerService;
import com.android.server.inputmethod.InputMethodSystemProperty;
import com.android.server.inputmethod.MultiClientInputMethodManagerService;
+import com.android.server.integrity.AppIntegrityManagerService;
import com.android.server.lights.LightsService;
import com.android.server.media.MediaResourceMonitorService;
import com.android.server.media.MediaRouterService;
@@ -1129,6 +1130,10 @@ public final class SystemServer {
SignedConfigService.registerUpdateReceiver(mSystemContext);
t.traceEnd();
+ t.traceBegin("AppIntegrityService");
+ mSystemServiceManager.startService(AppIntegrityManagerService.class);
+ t.traceEnd();
+
} catch (Throwable e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service");
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
new file mode 100644
index 000000000000..37ff06a18492
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.server.integrity;
+
+import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
+
+import static org.mockito.Mockito.verify;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.LocalServices;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+/** Unit test for {@link com.android.server.integrity.AppIntegrityManagerServiceImpl} */
+@RunWith(AndroidJUnit4.class)
+public class AppIntegrityManagerServiceImplTest {
+
+ @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Mock PackageManagerInternal mPackageManagerInternal;
+
+ // under test
+ private AppIntegrityManagerServiceImpl mService;
+
+ @Before
+ public void setup() {
+ LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
+
+ mService = new AppIntegrityManagerServiceImpl(InstrumentationRegistry.getContext());
+ }
+
+ @Test
+ public void integrityVerification_allow() {
+ int verificationId = 2;
+ Intent integrityVerificationIntent = new Intent();
+ integrityVerificationIntent.setAction(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
+ integrityVerificationIntent.putExtra(EXTRA_VERIFICATION_ID, verificationId);
+
+ // We cannot send the broadcast using the context since it is a protected broadcast and
+ // we will get a security exception.
+ mService.handleIntegrityVerification(integrityVerificationIntent);
+
+ verify(mPackageManagerInternal)
+ .setIntegrityVerificationResult(verificationId, PackageManager.VERIFICATION_ALLOW);
+ }
+}