zoukankan
html css js c++ java
Privileged Permission开机授权时序图 SourceCode android-10.0.0_r36
Privileged Permission开机授权时序图 | SourceCode:android-10.0.0_r36 | Author:秋城 | v1.1
SystemServer
SystemServer
SystemServerInitThreadPool
SystemServerInitThreadPool
SystemConfig
SystemConfig
PackageManagerService
PackageManagerService
PermissionManagerService
PermissionManagerService
PermissionSettings
PermissionSettings
ParallelPackageParser
ParallelPackageParser
PackageParser
PackageParser
PackageParser.Package
PackageParser.Package
PermissionManagerService.PermissionManagerServiceInternalImpl
PermissionManagerService.PermissionManagerServiceInternalImpl
1
main()
2
run()
3
startBootstrapServices()
↓Step 读取配置好的特权白名单
4
get.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG)
5
getInstance()
6
new SystemConfig()
读取配置好的特权白名单到内存。涉及7个路径下/xxx/etc/permissions/*xml文件
过滤标签“privapp-permissions”中
“许可”:"permission"与“拒绝”:"deny-permission"
路径定义在Environment.java
ENV_ANDROID_ROOT, "
/system
"
ENV_OEM_ROOT, "
/oem
"
ENV_ODM_ROOT, "
/odm
"
Environment.getOdmDirectory(), "etc", "permissions",
skuDir
ENV_VENDOR_ROOT, "
/vendor
"
ENV_PRODUCT_ROOT, "
/product
"
ENV_PRODUCT_SERVICES_ROOT,"
/product_services
"
7
readPermissions()
8
readPermissionsFromXml()
9
readPermission()
10
readPrivAppPermissions(parser,
mPrivAppPermissions,mPrivAppDenyPermissions
)
private void readPrivAppPermissions(XmlPullParser parser,
ArrayMap<String, ArraySet<String>>
grantMap
,
ArrayMap<String, ArraySet<String>>
denyMap
)
while (XmlUtils.nextElementWithin(parser, depth)) {
String name = parser.getName();
if ("permission".equals(name)) {
String permName = parser.getAttributeValue(null, "name");
permissions
.add(permName);
} else if ("deny-permission".equals(name)) {
String permName = parser.getAttributeValue(null, "name");
denyPermissions
.add(permName);}}
grantMap
.put(packageName,
permissions
);
denyMap
.put(packageName,
denyPermissions
);
↓Step 读取"privileged"权限定义
11
main(mSystemContext, installer,<factoryTest>, mOnlyCore)
12
new PackageManagerService(context, installer,factoryTest, onlyCore)
13
create(context,mPackages /*externalLock*/)
14
new PermissionManagerService()
15
new PermissionSettings()
16
mSettings
All of the permissions known to the system.
系统中所有通过<permission>标签声明的权限
(FrameWork及App定义的权限都在这个map中存储)
public class PermissionSettings {
final ArrayMap<String, BasePermission>
mPermissions
=
new ArrayMap<String, BasePermission>();
}
17
scanDirTracedLI(frameworkDir,...)
扫描/system/framework/目录的apk,其中我们的privileged权限定义在system/framework/framework-res.apk中
代码是frameworks/base/core/res/AndroidManifest.xml文件的<permission>标签
其中
protectionLevel="signature|privileged"
是特权标志,共216个
$ ag android:protectionLevel=signature|privileged frameworks/base/core/res/AndroidManifest.xml |wc -l
216
例如重启权限:
3714 <!-- Required to be able to reboot the device.
3715 <p>Not for use by third-party applications. -->
3716 <permission android:name="android.permission.REBOOT"
3717 android:protectionLevel="signature|privileged" />
18
scanDirLI()
19
submit()
20
parsePackage()
21
parsePackage(scanFile, parseFlags, true /* useCaches */)
此处关注解析单个apk,parseMonolithicPackage()方法
其实parseClusterPackage内部也是遍历来调parseMonolithicPackage
public Package parsePackage(File packageFile, int flags, boolean useCaches){
Package parsed = useCaches ? getCachedResult(packageFile, flags) : null;
if (packageFile.isDirectory()) {
parsed = parseClusterPackage(packageFile, flags);
} else {
parsed = parseMonolithicPackage(packageFile, flags);
}
return parsed;
}
22
parseMonolithicPackage()
23
parseBaseApk(,,)
24
parseBaseApk(,,,)
25
new Package(pkgName)
26
pkg
27
parseBaseApkCommon(pkg,,,,,)
读取整个AndroidManifest.xml,此处关注<permission>:权限定义标签
} else if (tagName.equals(TAG_PERMISSION)) {
if (!parsePermission(pkg, res, parser, outError)) {
return null;
}
} else if ...
28
parsePermission(pkg,,,)
private boolean parsePermission(Package owner, Resources res,
XmlResourceParser parser, String[] outError)
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestPermission);
Permission perm = new
Permission
(owner, backgroundPermission);
perm.info.protectionLevel
= sa.getInt(
com.android.internal.R.styleable.AndroidManifestPermission_protectionLevel,
PermissionInfo.PROTECTION_NORMAL);
owner.
permissions
.add(perm);
frameworks/base/core/java/android/content/pm/PackageParser.java
public final static class
Permission
extends Component<IntentInfo>
implements Parcelable {
public final
PermissionInfo
info;
}
frameworks/base/core/java/android/content/pm/PermissionInfo.java
public class
PermissionInfo
extends PackageItemInfo
implements Parcelable {
public int
protectionLevel
;
}
frameworks/base/core/java/android/content/pm/PackageParser.java
PackageParser$Package代表内存中安装后apk
每个apk声明的权限都存放在其permissions这个ArrayList中
public final static class Package implements Parcelable {
public final ArrayList<Permission>
permissions
= new ArrayList<Permission>(0);
}
多线程并发扫描安装apk。
并发解析工具类:ParallelPackageParser.java
入队出队方法:submit/take
// Submit files for parsing in parallel
int fileCount = 0;
for (File file : files) {
...
parallelPackageParser.
submit
(file, parseFlags);
fileCount++;
}
// Process results one by one
for (; fileCount > 0; fileCount--) {
ParallelPackageParser.ParseResult parseResult = parallelPackageParser.
take
();
...
}
29
scanPackageChildLI(,,,,)
30
addForInitLI(,,,,)
31
commitReconciledScanResultLocked()
32
commitPackageSettings(,,,,,)
33
addAllPermissions(,)
34
addAllPermissions(,)
private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
final int N = pkg.
permissions
.size();
for (int i=0; i<N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
...
final BasePermission bp = BasePermission.createOrUpdate(
mSettings.getPermissionLocked(p.info.name),
p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
mSettings.putPermissionLocked(p.info.name, bp);
...
35
putPermissionLocked(,)
@GuardedBy("mLock")
void putPermissionLocked(@NonNull String permName, @NonNull BasePermission permission) {
mPermissions
.put(permName, permission);
}
↓Step 读取应用所申请权限(apk安装)
36
scanDirTracedLI(xxxDir)
扫描如下11个路径下的系统apk。
Environment.getRootDirectory():"priv-app"&&"app"
Environment.getVendorDirectory(): "priv-app"&&"app"
Environment.getOdmDirectory():"priv-app"&&"app"
Environment.getOemDirectory():"app"
Environment.getProductDirectory():"priv-app"&&"app"
Environment.getProductServicesDirectory():"priv-app"&&"app"
通过存放路径来分配FLAG是方式之一
priv-app/授予
"SYSTEM|PRIVILEGED"
,app/授予
"SYSTEM"
即我们俗称的系统应用和特权应用
37
scanDirLI()
38
submit()
39
parsePackage()
40
parsePackage(scanFile, parseFlags, true /* useCaches */)
41
parseMonolithicPackage()
42
parseBaseApk(,,)
43
parseBaseApk(,,,)
44
new Package(pkgName)
45
pkg
PackageParser$Package代表内存中安装后apk
每个apk所申请的权限都将存储在其PackageParser$Package
requestedPermissions数据结构中
public final ArrayList<String>
requestedPermissions
= new ArrayList<String>();
46
parseBaseApkCommon(pkg,,,,,)
读取整个AndroidManifest.xml,此处关注<uses-permission>权限申请标签
} else if (tagName.equals(TAG_USES_PERMISSION)) {
if (!parseUsesPermission(pkg, res, parser)) {
return null;
}
} else if...
47
parseUsesPermission()
private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser){
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestUsesPermission);
String name = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestUsesPermission_name);
...
pkg.requestedPermissions
.add(name.intern());
}
↓Step 给应用授权
48
startOtherServices()
49
systemReady()
50
updateAllPermissions(,,Collection<
PackageParser.Package
> allPackages,)
51
updateAllPermissions()
52
updatePermissions(,,,,,)
53
restorePermissionState(,,,)
private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
@Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
final int N = pkg.
requestedPermissions
.size();
for (int i = 0; i < N; i++) {
final String permName = pkg.
requestedPermissions
.get(i);
final BasePermission bp = mSettings.getPermissionLocked(permName);
else if (bp.isSignature()) {
allowedSig = grantSignaturePermission(...)
if (allowedSig) {
grant = GRANT_INSTALL;
}
54
grantSignaturePermission(...)
55
hasPrivappWhitelistEntry()
56
getPrivAppPermissions(packageName)
57
mPrivAppPermissions
.get(packageName)
private boolean grantSignaturePermission(String perm,
PackageParser.Package
> pkg,
BasePermission bp, PermissionsState origPermissions) {
boolean privappPermissionsDisable =
RoSystemProperties.
CONTROL_PRIVAPP_PERMISSIONS_DISABLE
;
if (
!privappPermissionsDisable
&&
privilegedPermission
&&
pkg.isPrivileged()
&&
!platformPackage
&&
platformPermission
) {
if (
!hasPrivappWhitelistEntry(perm, pkg)
) {
// 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 boolean permissionViolation =
deniedPermissions == null || !deniedPermissions.contains(perm);
if (
permissionViolation
) {
Slog.w(TAG, "Privileged permission " + perm + " for package "
+ pkg.packageName + " - not in privapp-permissions whitelist");
if (
RoSystemProperties.
CONTROL_PRIVAPP_PERMISSIONS_ENFORCE
) {
mPrivappPermissionsViolations
.add(pkg.packageName + ": " + perm);
//满足以上十条才会将强制crash开关打开。此外return true/false:授权/不授权
↓Step SystemServer Crash
58
systemReady()
59
systemReady()
private void systemReady() {
mSystemReady = true;
if (
mPrivappPermissionsViolations
!= null) {
throw new IllegalStateException
("Signature|privileged permissions not in "
+ "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
}
}
查看全文
相关阅读:
Shiro配置文件ini详解
Shiro配置文件ini详解
[转]shiro基础教程
[转]shiro基础教程
arguments.callee的作用
[转] C# WPF Unable to add event handler
[转] C# WPF Unable to add event handler
springmvcajax json对象 用Map接受
springmvcajax json对象 用Map接受
json 对象字符串相互转化, js中
原文地址:https://www.cnblogs.com/houser0323/p/13832091.html
最新文章
[转]C#WinForm应用程序——添加菜单栏MenuStrip
[转]C#WinForm应用程序——添加菜单栏MenuStrip
SQL中object_id函数的用法
SQL中object_id函数的用法
[转]sql server 的ANSI_NULLS设置
[转]sql server 的ANSI_NULLS设置
[转]SqlServer中Sql查看存储过程
[转]SqlServer中Sql查看存储过程
easyui MenuButton
easyui MenuButton
热门文章
easyui Menu
easyui Menu
[转]备份与还原mysql 数据库的常用命令。
[转]备份与还原mysql 数据库的常用命令。
[转]mysqldump 导出数据库各参数详细说明
[转]mysqldump 导出数据库各参数详细说明
sql还原(.mdf文件还原)
sql还原(.mdf文件还原)
Spring AOP 和代理
Spring AOP 和代理
Copyright © 2011-2022 走看看