新博客地址
blog.marssecure.com
platform.xml
Android中沿用Linux用户和组的来限制系统资源的访问,查看从Android真机pull出/etc/permissions/platform.xml
权限初始化
PackageManagerService构造函数会解析platform.xml,建立android权限和gid的对应关系。然后,扫描apk时,会由请求的权限找到对应的gid,并保存在Package类中。
由于Android很多都是使用permission来进行保护,需要在AndroidManifest中显示声明对应权限,有些在platfrom.xml中定义的权限须由特定用户组使用
下面来解析一下在该构造方法中对于plafrom.xml解析
源码分析
初始化处理permission文件
- 创建的时候,在构造方法中初始化systemConfig
public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore) {
...
SystemConfig systemConfig = SystemConfig.getInstance()
...
}
- getInstance()是创建一个SystemConfig对象
public static SystemConfig getInstance() {
synchronized (SystemConfig.class) {
if (sInstance == null) {
sInstance = new SystemConfig();
}
return sInstance;
}
}
- SystemConfig构造方法中,使用readPermissions处理了系统和OEM厂商的配置和系统权限
SystemConfig() {
/system/etc/sysconfig
readPermissions(Environment.buildPath(
Environment.getRootDirectory(), "etc", "sysconfig"), false);
/system/etc/permissions
readPermissions(Environment.buildPath(
Environment.getRootDirectory(), "etc", "permissions"), false);
/oem/etc/sysconfig
readPermissions(Environment.buildPath(
Environment.getOemDirectory(), "etc", "sysconfig"), true);
/oem/etc/permissions
readPermissions(Environment.buildPath(
Environment.getOemDirectory(), "etc", "permissions"), true);
}
- 对于上面四个目录都使用了readPermissions函数读取
void readPermissions(File libraryDir, boolean onlyFeatures) {
// 从给定的文件夹中读取权限
....
// 迭代方式读取xml文件
File platformFile = null;
for (File f : libraryDir.listFiles()) {
// 最后单独处理platform.xml
if (f.getPath().endsWith("etc/permissions/platform.xml")) {
platformFile = f;
continue;
}
...
// 取到的xml结尾的文件,使用readPermissionsFromXml读取
readPermissionsFromXml(f, onlyFeatures);
}
// 最后读取平台权限以致其能最优先
if (platformFile != null) {
readPermissionsFromXml(platformFile, onlyFeatures);
}
}
- 不管是platform.xml还是其他的xml文件,都是调用readPermissionsFromXml函数处理,assign-permission解析后存放到mSystemPermissions中,uid和permission对应
ArraySet<String> perms = mSystemPermissions.get(uid);
if (perms == null) {
perms = new ArraySet<String>();
mSystemPermissions.put(uid, perms);
}
perms.add(perm);
permission将permission和gid存放到mPermissions中
PermissionEntry perm = mPermissions.get(name);
if (perm == null) {
perm = new PermissionEntry(name);
mPermissions.put(name, perm);
}
- 整体方法源代码
private void readPermissionsFromXml(File permFile, boolean onlyFeatures) {
FileReader permReader = null;
permReader =