privAppPermissions = isVendorApp(pkg) ?
+ SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg)
+ : SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
+
+ getOutPrintWriter().println(privAppPermissions == null
+ ? "{}" : privAppPermissions.toString());
return 0;
}
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 3b414e9a0dc57..258dd4d4dcb39 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -140,6 +140,10 @@ public final class PackageSetting extends PackageSettingBase {
return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
}
+ public boolean isVendor() {
+ return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
+ }
+
public boolean isForwardLocked() {
return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0;
}
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index c97f5e5443a34..46ba0060d93e4 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -61,6 +61,7 @@ abstract class SettingBase {
this.pkgPrivateFlags = pkgPrivateFlags
& (ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
| ApplicationInfo.PRIVATE_FLAG_OEM
+ | ApplicationInfo.PRIVATE_FLAG_VENDOR
| ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK
| ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER);
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index ddad6774871d6..af1a4d148856f 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -847,6 +847,8 @@ public final class Settings {
pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
pkgSetting.pkgPrivateFlags |=
pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM;
+ pkgSetting.pkgPrivateFlags |=
+ pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR;
pkgSetting.primaryCpuAbiString = primaryCpuAbi;
pkgSetting.secondaryCpuAbiString = secondaryCpuAbi;
if (childPkgNames != null) {
@@ -4421,6 +4423,7 @@ public final class Settings {
ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
+ ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
};
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 8c86db64471db..75a61064c1c9e 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -225,6 +225,9 @@ public final class BasePermission {
public boolean isVerifier() {
return (protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0;
}
+ public boolean isVendorPrivileged() {
+ return (protectionLevel & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0;
+ }
public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) {
if (!origPackageName.equals(sourcePackageName)) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 7d8e20696affe..90ac4ab7dd426 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -959,8 +959,9 @@ Slog.e(TAG, "TODD: Packages: " + Arrays.toString(packages));
* This handles parent/child apps.
*/
private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
- ArraySet wlPermissions = SystemConfig.getInstance()
- .getPrivAppPermissions(pkg.packageName);
+ ArraySet wlPermissions = pkg.isVendor() ?
+ SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName)
+ : SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
// Let's check if this package is whitelisted...
boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
// If it's not, we'll also tail-recurse to the parent.
@@ -971,7 +972,8 @@ Slog.e(TAG, "TODD: Packages: " + Arrays.toString(packages));
private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
BasePermission bp, PermissionsState origPermissions) {
boolean oemPermission = bp.isOEM();
- boolean privilegedPermission = bp.isPrivileged();
+ boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
+ boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
boolean privappPermissionsDisable =
RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
@@ -982,8 +984,11 @@ Slog.e(TAG, "TODD: Packages: " + Arrays.toString(packages));
// Only report violations for apps on system image
if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
// it's only a reportable violation if the permission isn't explicitly denied
- final ArraySet deniedPermissions = SystemConfig.getInstance()
- .getPrivAppDenyPermissions(pkg.packageName);
+ final ArraySet deniedPermissions = pkg.isVendor() ?
+ SystemConfig.getInstance()
+ .getVendorPrivAppDenyPermissions(pkg.packageName)
+ : SystemConfig.getInstance()
+ .getPrivAppDenyPermissions(pkg.packageName);
final boolean permissionViolation =
deniedPermissions == null || !deniedPermissions.contains(perm);
if (permissionViolation) {
@@ -1086,6 +1091,15 @@ Slog.e(TAG, "TODD: Packages: " + Arrays.toString(packages));
|| (oemPermission && pkg.isOem()
&& canGrantOemPermission(ps, perm));
}
+ // In any case, don't grant a privileged permission to privileged vendor apps, if
+ // the permission's protectionLevel does not have the extra 'vendorPrivileged'
+ // flag.
+ if (allowed && privilegedPermission &&
+ !vendorPrivilegedPermission && pkg.isVendor()) {
+ Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
+ + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
+ allowed = false;
+ }
}
}
if (!allowed) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
deleted file mode 100644
index e6b4540f73c96..0000000000000
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2016 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.pm;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PermissionInfo;
-import android.platform.test.annotations.GlobalPresubmit;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.ArraySet;
-
-import com.android.internal.os.RoSystemProperties;
-import com.android.internal.util.ArrayUtils;
-import com.android.server.SystemConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-import static android.content.pm.PackageManager.GET_PERMISSIONS;
-import static junit.framework.Assert.assertTrue;
-
-
-/**
- * Presubmit tests for {@link PackageManager}.
- */
-@RunWith(AndroidJUnit4.class)
-public class PackageManagerPresubmitTest {
-
- private Context mContext;
-
- private PackageManager mPackageManager;
-
- @Before
- public void setUp() {
- mContext = InstrumentationRegistry.getContext();
- mPackageManager = mContext.getPackageManager();
- }
-
- /**
- * This test ensures that all signature|privileged permissions are granted to priv-apps.
- * If CONTROL_PRIVAPP_PERMISSIONS_ENFORCE is set, the test also verifies that
- * granted permissions are whitelisted in {@link SystemConfig}
- */
- @Test
- @SmallTest
- @GlobalPresubmit
- public void testPrivAppPermissions() throws PackageManager.NameNotFoundException {
- List installedPackages = mPackageManager
- .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES | GET_PERMISSIONS);
- for (PackageInfo packageInfo : installedPackages) {
- if (!packageInfo.applicationInfo.isPrivilegedApp()
- || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(packageInfo.packageName)) {
- continue;
- }
- testPackagePrivAppPermission(packageInfo);
- }
-
- }
-
- private void testPackagePrivAppPermission(PackageInfo packageInfo)
- throws PackageManager.NameNotFoundException {
- String packageName = packageInfo.packageName;
- ArraySet privAppPermissions = SystemConfig.getInstance()
- .getPrivAppPermissions(packageName);
- if (ArrayUtils.isEmpty(packageInfo.requestedPermissions)) {
- return;
- }
- for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
- String pName = packageInfo.requestedPermissions[i];
- int protectionLevel;
- boolean platformPermission;
- try {
- PermissionInfo permissionInfo = mPackageManager.getPermissionInfo(pName, 0);
- platformPermission = PackageManagerService.PLATFORM_PACKAGE_NAME.equals(
- permissionInfo.packageName);
- protectionLevel = permissionInfo.protectionLevel;
- } catch (PackageManager.NameNotFoundException e) {
- continue;
- }
- if ((protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
- boolean granted = (packageInfo.requestedPermissionsFlags[i]
- & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
- // if privapp permissions are enforced, platform permissions must be whitelisted
- // in SystemConfig
- if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
- assertTrue("Permission " + pName + " should be declared in "
- + "privapp-permissions-.xml file for package "
- + packageName,
- privAppPermissions != null && privAppPermissions.contains(pName));
- }
- assertTrue("Permission " + pName + " should be granted to " + packageName, granted);
- }
- }
- }
-}
diff --git a/tests/privapp-permissions/Android.mk b/tests/privapp-permissions/Android.mk
new file mode 100644
index 0000000000000..b001c8c466a9e
--- /dev/null
+++ b/tests/privapp-permissions/Android.mk
@@ -0,0 +1,31 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := PrivAppPermissionTest
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_MANIFEST_FILE := system/AndroidManifest.xml
+LOCAL_REQUIRED_MODULES := privapp-permissions-test.xml
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := privapp-permissions-test.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+LOCAL_SRC_FILES:= system/privapp-permissions-test.xml
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := VendorPrivAppPermissionTest
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_MANIFEST_FILE := vendor/AndroidManifest.xml
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := vendorprivapp-permissions-test.xml
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := vendorprivapp-permissions-test.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/permissions
+LOCAL_SRC_FILES:= vendor/privapp-permissions-test.xml
+include $(BUILD_PREBUILT)
+
diff --git a/tests/privapp-permissions/system/AndroidManifest.xml b/tests/privapp-permissions/system/AndroidManifest.xml
new file mode 100644
index 0000000000000..2099e31bd2c17
--- /dev/null
+++ b/tests/privapp-permissions/system/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/tests/privapp-permissions/system/privapp-permissions-test.xml b/tests/privapp-permissions/system/privapp-permissions-test.xml
new file mode 100644
index 0000000000000..a0cb6bc74195b
--- /dev/null
+++ b/tests/privapp-permissions/system/privapp-permissions-test.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/tests/privapp-permissions/vendor/AndroidManifest.xml b/tests/privapp-permissions/vendor/AndroidManifest.xml
new file mode 100644
index 0000000000000..78dedc5f199b3
--- /dev/null
+++ b/tests/privapp-permissions/vendor/AndroidManifest.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/privapp-permissions/vendor/privapp-permissions-test.xml b/tests/privapp-permissions/vendor/privapp-permissions-test.xml
new file mode 100644
index 0000000000000..51c588f0dea7d
--- /dev/null
+++ b/tests/privapp-permissions/vendor/privapp-permissions-test.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+