diff options
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/com/android/server/SystemConfig.java | 74 |
1 files changed, 68 insertions, 6 deletions
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index b0cf5dcbbfd5..ae9d71610aaa 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -56,6 +56,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -95,6 +96,9 @@ public class SystemConfig { // property for runtime configuration differentiation in vendor private static final String VENDOR_SKU_PROPERTY = "ro.boot.product.vendor.sku"; + private static final ArrayMap<String, ArraySet<String>> EMPTY_PERMISSIONS = + new ArrayMap<>(); + // Group-ids that are given to all packages as read from etc/permissions/*.xml. int[] mGlobalGids = EmptyArray.INT; @@ -224,6 +228,11 @@ public class SystemConfig { final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>(); + final ArrayMap<String, ArrayMap<String, ArraySet<String>>> mApexPrivAppPermissions = + new ArrayMap<>(); + final ArrayMap<String, ArrayMap<String, ArraySet<String>>> mApexPrivAppDenyPermissions = + new ArrayMap<>(); + final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>(); // Allowed associations between applications. If there are any entries @@ -360,6 +369,18 @@ public class SystemConfig { return mPrivAppDenyPermissions.get(packageName); } + /** Get privapp permission allowlist for an apk-in-apex. */ + public ArraySet<String> getApexPrivAppPermissions(String module, String packageName) { + return mApexPrivAppPermissions.getOrDefault(module, EMPTY_PERMISSIONS) + .get(packageName); + } + + /** Get privapp permissions denylist for an apk-in-apex. */ + public ArraySet<String> getApexPrivAppDenyPermissions(String module, String packageName) { + return mApexPrivAppDenyPermissions.getOrDefault(module, EMPTY_PERMISSIONS) + .get(packageName); + } + public ArraySet<String> getVendorPrivAppPermissions(String packageName) { return mVendorPrivAppPermissions.get(packageName); } @@ -573,8 +594,8 @@ public class SystemConfig { if (!isSystemProcess()) { return; } - // Read configuration of features and libs from apex module. - int apexPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES; + // Read configuration of features, libs and priv-app permissions from apex module. + int apexPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS; // TODO: Use a solid way to filter apex module folders? for (File f: FileUtils.listFilesOrEmpty(Environment.getApexDirectory())) { if (f.isFile() || f.getPath().contains("@")) { @@ -1040,10 +1061,10 @@ public class SystemConfig { } break; case "privapp-permissions": { if (allowPrivappPermissions) { - // privapp permissions from system, vendor, product and system_ext - // partitions are stored separately. This is to prevent xml files in - // the vendor partition from granting permissions to priv apps in the - // system partition and vice versa. + // privapp permissions from system, apex, vendor, product and + // system_ext partitions are stored separately. This is to + // prevent xml files in the vendor partition from granting + // permissions to priv apps in the system partition and vice versa. boolean vendor = permFile.toPath().startsWith( Environment.getVendorDirectory().toPath() + "/") || permFile.toPath().startsWith( @@ -1052,6 +1073,8 @@ public class SystemConfig { Environment.getProductDirectory().toPath() + "/"); boolean systemExt = permFile.toPath().startsWith( Environment.getSystemExtDirectory().toPath() + "/"); + boolean apex = permFile.toPath().startsWith( + Environment.getApexDirectory().toPath() + "/"); if (vendor) { readPrivAppPermissions(parser, mVendorPrivAppPermissions, mVendorPrivAppDenyPermissions); @@ -1061,6 +1084,8 @@ public class SystemConfig { } else if (systemExt) { readPrivAppPermissions(parser, mSystemExtPrivAppPermissions, mSystemExtPrivAppDenyPermissions); + } else if (apex) { + readApexPrivAppPermissions(parser, permFile); } else { readPrivAppPermissions(parser, mPrivAppPermissions, mPrivAppDenyPermissions); @@ -1616,6 +1641,43 @@ public class SystemConfig { } } + + /** + * Returns the module name for a file in the apex module's partition. + */ + private String getApexModuleNameFromFilePath(Path path) { + final Path apexDirectoryPath = Environment.getApexDirectory().toPath(); + if (!path.startsWith(apexDirectoryPath)) { + throw new IllegalArgumentException("File " + path + " is not part of an APEX."); + } + // File must be in <apex_directory>/<module_name>/[extra_paths/]<xml_file> + if (path.getNameCount() <= (apexDirectoryPath.getNameCount() + 1)) { + throw new IllegalArgumentException("File " + path + " is in the APEX partition," + + " but not inside a module."); + } + return path.getName(apexDirectoryPath.getNameCount()).toString(); + } + + private void readApexPrivAppPermissions(XmlPullParser parser, File permFile) + throws IOException, XmlPullParserException { + final String moduleName = getApexModuleNameFromFilePath(permFile.toPath()); + final ArrayMap<String, ArraySet<String>> privAppPermissions; + if (mApexPrivAppPermissions.containsKey(moduleName)) { + privAppPermissions = mApexPrivAppPermissions.get(moduleName); + } else { + privAppPermissions = new ArrayMap<>(); + mApexPrivAppPermissions.put(moduleName, privAppPermissions); + } + final ArrayMap<String, ArraySet<String>> privAppDenyPermissions; + if (mApexPrivAppDenyPermissions.containsKey(moduleName)) { + privAppDenyPermissions = mApexPrivAppDenyPermissions.get(moduleName); + } else { + privAppDenyPermissions = new ArrayMap<>(); + mApexPrivAppDenyPermissions.put(moduleName, privAppDenyPermissions); + } + readPrivAppPermissions(parser, privAppPermissions, privAppDenyPermissions); + } + private static boolean isSystemProcess() { return Process.myUid() == Process.SYSTEM_UID; } |
