不一样的SYSTEM APP(SYSTEM flag和system_prop区别)

2024-06-17 00:28
文章标签 app 区别 flag system prop

本文主要是介绍不一样的SYSTEM APP(SYSTEM flag和system_prop区别),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.问题引入

在Android开发中,
1)Framework中PackageManager扫包后,会把app归类为SYSTEM, SYSTEM_EXT, PRIVILEGED 类别.

2)同样的, SeAndroid也会把APP归类程platform_app, system_app, untrusted_app(甚至还有其他,mediaprovider,gmscore_app).

flag SYSTEM和system_app我们都称之为系统app.
但是他们不是同一个概念的"系统app".

2.PackageSettings flag SYSTEM

dumpsys package com.android.systemui为例, 输出如下:

Packages:Package [com.android.systemui] (d6f33bf):appId=10187sharedUser=SharedUserSetting{4058ad4 android.uid.systemui/10187}pkg=Package{aa0e47d com.android.systemui}codePath=/system_ext/priv-app/SystemUIresourcePath=/system_ext/priv-app/SystemUIlegacyNativeLibraryDir=/system_ext/priv-app/SystemUI/libextractNativeLibs=trueprimaryCpuAbi=arm64-v8asecondaryCpuAbi=nullcpuAbiOverride=nullversionCode=1410014 minSdk=33 targetSdk=34minExtensionVersions=[]versionName=14.00.14usesNonSdkApi=falsesplits=[base]apkSigningVersion=3flags=[ SYSTEM HAS_CODE PERSISTENT ]privateFlags=[ PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION ALLOW_AUDIO_PLAYBACK_CAPTURE DEFAULT_TO_DEVICE_PROTECTED_STORAGE DIRECT_BOOT_AWARE PARTIALLY_DIRECT_BOOT_AWARE PRIVILEGED SYSTEM_EXT PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING ]forceQueryable=false

根据输出可以看到两个重要的flag,分别为flags和privateFlags.其中flags其中标签为SYSTEM和PERSISTENT, 而privateFlags其中两个输出为PRIVILEGED/SYSTEM_EXT.

对应的输出代码如下:

    @NeverCompile // Avoid size overhead of debugging code.void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,ArraySet<String> permissionNames, PackageSetting ps,LegacyPermissionState permissionsState, SimpleDateFormat sdf, Date date,List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents) {AndroidPackage pkg = ps.getPkg();// 省略好多if (pkg != null) {pw.print(prefix); pw.print("  versionName="); pw.println(pkg.getVersionName());pw.print(prefix); pw.print("  usesNonSdkApi="); pw.println(pkg.isUsesNonSdkApi());pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, pkg); pw.println();final int apkSigningVersion = pkg.getSigningDetails().getSignatureSchemeVersion();pw.print(prefix); pw.print("  apkSigningVersion="); pw.println(apkSigningVersion);pw.print(prefix); pw.print("  flags=");printFlags(pw, PackageInfoUtils.appInfoFlags(pkg, ps), FLAG_DUMP_SPEC); pw.println();int privateFlags = PackageInfoUtils.appInfoPrivateFlags(pkg, ps);if (privateFlags != 0) {pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();}if (pkg.hasPreserveLegacyExternalStorage()) {pw.print(prefix); pw.print("  hasPreserveLegacyExternalStorage=true");pw.println();}pw.print(prefix); pw.print("  forceQueryable=");pw.print(ps.getPkg().isForceQueryable());if (ps.isForceQueryableOverride()) {pw.print(" (override=true)");}
static void printFlags(PrintWriter pw, int val, Object[] spec) {pw.print("[ ");for (int i=0; i<spec.length; i+=2) {int mask = (Integer)spec[i];if ((val & mask) != 0) {pw.print(spec[i+1]);pw.print(" ");}}pw.print("]");
}

从上可知是PackageManagerService扫包解析后缓存在PackageSettings中的相关状态值记录,用于区分各类APP.

  1. FLAG_DUMP_SPEC
    在这里插入图片描述
  2. PRIVATE_FLAG_DUMP_SPEC
    在这里插入图片描述

从上可知,输出来源于和这些flag与运算后转换成对应的字串输出.
再看ApplicationInfo中的定义:
[1] FLAG_SYSTEM
在这里插入图片描述
注意表述,只要是预装在System镜像里边的即表示该APP为SYSTEM APP.

再对照着下边几个FLAG来看,
在这里插入图片描述

发现如果APP预制在OEM/ VENDOR/PRODUCT/SYSTEM_EXT分区,都会分别别打上对应的PRIVATE_FLAG_DUMP_SPEC标签.
以我自用的Android14真机举例:
/product/app/Ether
在这里插入图片描述

/product/priv-app/OppoGallery2
在这里插入图片描述

/system_ext/app/OTA/OTA.apk
在这里插入图片描述

/vendor/overlay/WifiResTarget_mainline.apk
在这里插入图片描述
/data/app/OppoCompass2
在这里插入图片描述

从以上可知,在product/system_ext/system/vendor/oem分区的都带FLAG_SYSTEM. 而可卸载的/data分区的不带(即便是OPPO预装的).

oem的例子:
/oem/priv-app/SearchSelector
在这里插入图片描述
因此需要注意ApplicationInfo中的注释,一个是is installed in the device’s system image, 一个是is pre-installed on the xxx partition of the system image.

因此, 暂且可以简单理解为非data分区的都可以是SYSTEM app.
如果是自安装APP(安装在/data分区), 即使是平台签名,也不是FLAG_SYSTEM.
在这里插入图片描述

3.seAndroid system_app

Android 默认是回来其enforcing模式的. 规则中会把各类app分门别类,从而达到其对各分区资源的操作访问做权限管理.
http://aospxref.com/android-13.0.0_r3/xref/system/sepolicy/private/mac_permissions.xml

<?xml version="1.0" encoding="utf-8"?>
<policy><!--* A signature is a hex encoded X.509 certificate or a tag defined inkeys.conf and is required for each signer tag. The signature caneither appear as a set of attached cert child tags or as an attribute.* A signer tag must contain a seinfo tag XOR multiple package stanzas.* Each signer/package tag is allowed to contain one seinfo tag. This tagrepresents additional info that each app can use in setting a SELinux securitycontext on the eventual process as well as the apps data directory.* seinfo assignments are made according to the following rules:- Stanzas with package name refinements will be checked first.- Stanzas w/o package name refinements will be checked second.- The "default" seinfo label is automatically applied.* valid stanzas can take one of the following forms:// single cert protecting seinfo<signer signature="@PLATFORM" ><seinfo value="platform" /></signer>// multiple certs protecting seinfo (all contained certs must match)<signer><cert signature="@PLATFORM1"/><cert signature="@PLATFORM2"/><seinfo value="platform" /></signer>// single cert protecting explicitly named app<signer signature="@PLATFORM" ><package name="com.android.foo"><seinfo value="bar" /></package></signer>// multiple certs protecting explicitly named app (all certs must match)<signer><cert signature="@PLATFORM1"/><cert signature="@PLATFORM2"/><package name="com.android.foo"><seinfo value="bar" /></package></signer>
--><!-- Platform dev key in AOSP --><signer signature="@PLATFORM" ><seinfo value="platform" /></signer><!-- Sdk Sandbox key --><signer signature="@SDK_SANDBOX" ><seinfo value="sdk_sandbox" /></signer><!-- Bluetooth key in AOSP --><signer signature="@BLUETOOTH" ><seinfo value="bluetooth" /></signer><!-- Media key in AOSP --><signer signature="@MEDIA" ><seinfo value="media" /></signer><signer signature="@NETWORK_STACK" ><seinfo value="network_stack" /></signer>
</policy>

以上定义了signer和seinfo之间的对应关系.
http://aospxref.com/android-13.0.0_r3/xref/system/sepolicy/private/seapp_contexts

关键部分:

user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all
user=system seinfo=platform domain=system_app type=system_app_data_file
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user
user=_app isPrivApp=true name=com.google.android.providers.media.module domain=mediaprovider_app type=privapp_data_file levelFrom=all

全部内容如下:

# The entries in this file define how security contexts for apps are determined.
# Each entry lists input selectors, used to match the app, and outputs which are
# used to determine the security contexts for matching apps.
#
# Input selectors:
#       isSystemServer (boolean)
#       isEphemeralApp (boolean)
#       user (string)
#       seinfo (string)
#       name (string)
#       isPrivApp (boolean)
#       minTargetSdkVersion (unsigned integer)
#       fromRunAs (boolean)
#
# All specified input selectors in an entry must match (i.e. logical AND).
# An unspecified string or boolean selector with no default will match any
# value.
# A user, or name string selector that ends in * will perform a prefix
# match.
# String matching is case-insensitive.
# See external/selinux/libselinux/src/android/android_platform.c,
# seapp_context_lookup().
#
# isSystemServer=true only matches the system server.
# An unspecified isSystemServer defaults to false.
# isEphemeralApp=true will match apps marked by PackageManager as Ephemeral
# user=_app will match any regular app process.
# user=_isolated will match any isolated service process.
# user=_sdksandbox will match sdk sandbox process for an app.
# Other values of user are matched against the name associated with the process
# UID.
# seinfo= matches aginst the seinfo tag for the app, determined from
# mac_permissions.xml files.
# The ':' character is reserved and may not be used in seinfo.
# name= matches against the package name of the app.
# isPrivApp=true will only match for applications preinstalled in
#       /system/priv-app.
# minTargetSdkVersion will match applications with a targetSdkVersion
#       greater than or equal to the specified value. If unspecified,
#       it has a default value of 0.
# fromRunAs=true means the process being labeled is started by run-as. Default
# is false.
#
# Precedence: entries are compared using the following rules, in the order shown
# (see external/selinux/libselinux/src/android/android_platform.c,
# seapp_context_cmp()).
#       (1) isSystemServer=true before isSystemServer=false.
#       (2) Specified isEphemeralApp= before unspecified isEphemeralApp=
#             boolean.
#       (3) Specified user= string before unspecified user= string;
#             more specific user= string before less specific user= string.
#       (4) Specified seinfo= string before unspecified seinfo= string.
#       (5) Specified name= string before unspecified name= string;
#             more specific name= string before less specific name= string.
#       (6) Specified isPrivApp= before unspecified isPrivApp= boolean.
#       (7) Higher value of minTargetSdkVersion= before lower value of
#              minTargetSdkVersion= integer. Note that minTargetSdkVersion=
#              defaults to 0 if unspecified.
#       (8) fromRunAs=true before fromRunAs=false.
# (A fixed selector is more specific than a prefix, i.e. ending in *, and a
# longer prefix is more specific than a shorter prefix.)
# Apps are checked against entries in precedence order until the first match,
# regardless of their order in this file.
#
# Duplicate entries, i.e. with identical input selectors, are not allowed.
#
# Outputs:
#       domain (string)
#       type (string)
#       levelFrom (string; one of none, all, app, or user)
#       level (string)
#
# domain= determines the label to be used for the app process; entries
# without domain= are ignored for this purpose.
# type= specifies the label to be used for the app data directory; entries
# without type= are ignored for this purpose. The label specified must
# have the app_data_file_type attribute.
# levelFrom and level are used to determine the level (sensitivity + categories)
# for MLS/MCS.
# levelFrom=none omits the level.
# levelFrom=app determines the level from the process UID.
# levelFrom=user determines the level from the user ID.
# levelFrom=all determines the level from both UID and user ID.
#
# levelFrom=user is only supported for _app or _isolated UIDs.
# levelFrom=app or levelFrom=all is only supported for _app UIDs.
# level may be used to specify a fixed level for any UID.
#
# For backwards compatibility levelFromUid=true is equivalent to levelFrom=app
# and levelFromUid=false is equivalent to levelFrom=none.
#
#
# Neverallow Assertions
# Additional compile time assertion checks for the rules in this file can be
# added as well. The assertion
# rules are lines beginning with the keyword neverallow. Full support for PCRE
# regular expressions exists on all input and output selectors. Neverallow
# rules are never output to the built seapp_contexts file. Like all keywords,
# neverallows are case-insensitive. A neverallow is asserted when all key value
# inputs are matched on a key value rule line.
## only the system server can be assigned the system_server domains
neverallow isSystemServer=false domain=system_server
neverallow isSystemServer=false domain=system_server_startup
neverallow isSystemServer="" domain=system_server
neverallow isSystemServer="" domain=system_server_startup# system domains should never be assigned outside of system uid
neverallow user=((?!system).)* domain=system_app
neverallow user=((?!system).)* type=system_app_data_file# any non priv-app with a non-known uid with a specified name should have a specified
# seinfo
neverallow user=_app isPrivApp=false name=.* seinfo=""
neverallow user=_app isPrivApp=false name=.* seinfo=default# neverallow shared relro to any other domain
# and neverallow any other uid into shared_relro
neverallow user=shared_relro domain=((?!shared_relro).)*
neverallow user=((?!shared_relro).)* domain=shared_relro# neverallow non-isolated uids into isolated_app domain
# and vice versa
neverallow user=_isolated domain=((?!isolated_app).)*
neverallow user=((?!_isolated).)* domain=isolated_app# uid shell should always be in shell domain, however non-shell
# uid's can be in shell domain
neverallow user=shell domain=((?!shell).)*# only the package named com.android.shell can run in the shell domain
neverallow domain=shell name=((?!com\.android\.shell).)*
neverallow user=shell name=((?!com\.android\.shell).)*# Ephemeral Apps must run in the ephemeral_app domain
neverallow isEphemeralApp=true domain=((?!ephemeral_app).)*isSystemServer=true domain=system_server_startup# sdksandbox must run in the sdksandbox domain
neverallow name=com.android.sdksandbox domain=((?!sdk_sandbox).)*user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all
user=_app isPrivApp=true name=com.android.remoteprovisioner domain=remote_prov_app type=app_data_file levelFrom=all
user=system seinfo=platform domain=system_app type=system_app_data_file
user=bluetooth seinfo=bluetooth domain=bluetooth type=bluetooth_data_file
user=network_stack seinfo=network_stack domain=network_stack type=radio_data_file
user=nfc seinfo=platform domain=nfc type=nfc_data_file
user=secure_element seinfo=platform domain=secure_element levelFrom=all
user=radio seinfo=platform domain=radio type=radio_data_file
user=shared_relro domain=shared_relro levelFrom=all
user=shell seinfo=platform domain=shell name=com.android.shell type=shell_data_file
user=webview_zygote seinfo=webview_zygote domain=webview_zygote
user=_isolated domain=isolated_app levelFrom=user
user=_sdksandbox domain=sdk_sandbox type=sdk_sandbox_data_file levelFrom=all
user=_app seinfo=app_zygote domain=app_zygote levelFrom=user
user=_app seinfo=media domain=mediaprovider type=app_data_file levelFrom=user
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
user=_app isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=all
user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user
user=_app isPrivApp=true name=com.google.android.permissioncontroller domain=permissioncontroller_app type=privapp_data_file levelFrom=all
user=_app seinfo=media isPrivApp=true name=com.android.providers.media.module domain=mediaprovider_app type=privapp_data_file levelFrom=all
user=_app isPrivApp=true name=com.google.android.providers.media.module domain=mediaprovider_app type=privapp_data_file levelFrom=all
user=_app seinfo=platform isPrivApp=true name=com.android.permissioncontroller domain=permissioncontroller_app type=privapp_data_file levelFrom=all
user=_app isPrivApp=true name=com.android.vzwomatrigger domain=vzwomatrigger_app type=privapp_data_file levelFrom=all
user=_app isPrivApp=true name=com.google.android.gms domain=gmscore_app type=privapp_data_file levelFrom=user
user=_app isPrivApp=true name=com.google.android.gms.* domain=gmscore_app type=privapp_data_file levelFrom=user
user=_app isPrivApp=true name=com.google.android.gms:* domain=gmscore_app type=privapp_data_file levelFrom=user
user=_app isPrivApp=true name=com.google.android.gsf domain=gmscore_app type=privapp_data_file levelFrom=user
user=_app minTargetSdkVersion=32 domain=untrusted_app type=app_data_file levelFrom=all
user=_app minTargetSdkVersion=30 domain=untrusted_app_30 type=app_data_file levelFrom=all
user=_app minTargetSdkVersion=29 domain=untrusted_app_29 type=app_data_file levelFrom=all
user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all
user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file levelFrom=user
user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user
user=_app minTargetSdkVersion=28 fromRunAs=true domain=runas_app levelFrom=all
user=_app fromRunAs=true domain=runas_app levelFrom=user

从以上定义可知,当签名是platform, 且user是system时,默认匹配到的就是system_app;同样可以在指定包名的情况下为特定APP指定特殊的domain.
例如:com.android.traceur,对应的domain已经是:traceur_app.

[小结]
1.platform签名 + system user 才是system_app;
2.platform签名 + 非system user ,是platform_app;
3.自己安装的三方APP是untrusted_app.

注意这里的system user是指示UID 1000, 如果是个APP, 那么他的AndroidManifest.xml必须声明android:sharedUserId=“android.uid.system”.

注意文件seapp_contexts中对user的定义说明.
user=_app will match any regular app process.
user=_isolated will match any isolated service process.
user=_sdksandbox will match sdk sandbox process for an app.
Other values of user are matched against the name associated with the process UID.

4.结论

  1. framework中的system app, 指的是预装在system image里边的APP.
  2. seAndroid中的system_app,是指拥有平台签名且user为system的APP.

参考资料

SEAndroid安全机制框架分析

<android Selinux 之 platform_app,system_app,priv_app,untrusted_app>

这篇关于不一样的SYSTEM APP(SYSTEM flag和system_prop区别)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067979

相关文章

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

python中json.dumps和json.dump区别

《python中json.dumps和json.dump区别》json.dumps将Python对象序列化为JSON字符串,json.dump直接将Python对象序列化写入文件,本文就来介绍一下两个... 目录1、json.dumps和json.dump的区别2、使用 json.dumps() 然后写入文

native和static native区别

本文基于Hello JNI  如有疑惑,请看之前几篇文章。 native 与 static native java中 public native String helloJni();public native static String helloJniStatic();1212 JNI中 JNIEXPORT jstring JNICALL Java_com_test_g

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

javascript中break与continue的区别

在javascript中,break是结束整个循环,break下面的语句不再执行了 for(let i=1;i<=5;i++){if(i===3){break}document.write(i) } 上面的代码中,当i=1时,执行打印输出语句,当i=2时,执行打印输出语句,当i=3时,遇到break了,整个循环就结束了。 执行结果是12 continue语句是停止当前循环,返回从头开始。

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

ActiveMQ—Queue与Topic区别

Queue与Topic区别 转自:http://blog.csdn.net/qq_21033663/article/details/52458305 队列(Queue)和主题(Topic)是JMS支持的两种消息传递模型:         1、点对点(point-to-point,简称PTP)Queue消息传递模型:         通过该消息传递模型,一个应用程序(即消息生产者)可以