Android中的权限管理(基于Permission ProtectionLevel)

2023-05-16

     1、什么是protectionlevel呢?

      我们经常在AndroidManifest中使用权限,如果我们想让应用程序可以发短信,那么应该这样写:

 <uses-permission android:name="android.permission.SEND_SMS" />

      那么这个权限的定义是在哪里定义的呢?如下:

      frameworks/base/core/res/AndroidManifest.xml

<permission android:name="android.permission.SEND_SMS"
        android:permissionGroup="android.permission-group.COST_MONEY"
        android:protectionLevel="dangerous"
        android:label="@string/permlab_sendSms"
        android:description="@string/permdesc_sendSms" />
     这个xml可以认为是系统apk使用的AndroidManifest.xml,该apk使用系统的私钥进行签名。

     name:权限的名字,uses-permisson使用的。

     permissionGroup:权限的分类,在提示用户安装时会把某些功能差不多的权限放到一类。

     protectionLevel:分为Normal、Dangerous、Signature、SignatureOrSystem,我们后面会着重讲这个。

     label:提示给用户的权限名。

     description:提示给用户的权限描述。


    2、protectionLevel

    (1)Normal

    权限被声明为Normal级别,任何应用都可以申请,在安装应用时,不会直接提示给用户,点击全部才会展示。

    (2)Dangerous

    权限被声明为Dangerous级别,任何应用都可以申请,在安装应用时,会直接提示给用户。

    (3)Signature

    权限被声明为Signature级别,只有和该apk(定义了这个权限的apk)用相同的私钥签名的应用才可以申请该权限。
    frameworks/base/core/res/AndroidManifest.xml声明的权限为Signature级别,那么只有Android官方使用相同私钥签名的应用才可以申请该权限。

    (4)SignatureOrSystem

    权限被声明为SignatureOrSystem级别,有两种应用可以申请该权限。

    1)和该apk(定义了这个权限的apk)用相同的私钥签名的应用

    2)在/system/app目录下的应用


    3、举个例子

    比如百度地图apk的AndroidManifest.xml里面声明了一个权限,

    (1)、权限定义为Dangerous,那么任何其他应用都可以使用。

    (2)、权限定义为Signature,那么只有使用同样私钥签名的apk,例如百度网盘,可以使用这个权限。

    (3)、权限定义为SignatureOrSystem,那么使用同样私钥签名的apk,例如百度网盘,可以使用这个权限。在/system/app下的应用也可以使用这个权限。


    4、我们自然想到一个问题,申请了某个权限与否,在代码中是怎么控制是否可以访问某个资源呢?

    (1)、Android系统独有的权限,在代码中是怎么控制是否可以访问某个资源呢?我们看一个实际的例子。

     Client端:

void startDockOrHome(){
	awakenDreams();
	......
}

private static void awakenDreams(){
	IDreamManager dreamManager = getDreamManager();
	if(dreamManager != null){
		try{
			dreamManager.awaken();//调用Server端的awaken
		} catch(RemoteException e){
			//fine, stay asleep then
		}
	}
      Server端:

@Override // Binder call
public void awaken() {
	checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);

    final long ident = Binder.clearCallingIdentity();
    try {
        requestAwakenInternal();
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}

private void checkPermission(String permission) {
    if (mContext.checkCallingOrSelfPermission(permission)
               != PackageManager.PERMISSION_GRANTED) {
           throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
                  + ", must have permission " + permission);
    }
}
      Client端和Server端通过Binder进程间通信机制来通信。在Server端通过checkPermission来检查Client端是否申明了此权限。

  

      (2)、对于非Android特有的Service(底层平台已经提供,如File访问,TCPIP数据收发等),多个入口访问:Android API,Java API,NDK C API,shell都可以访问。这样权限控制就聚口在底层,所以在底层统一控制。这个底层统一控制其实就是传统的Linux文件读写执行权限(rwx)。

      例如在应用中申请了写SD卡的权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      我们需要把Android空间的Permission Mapping到OS的GID。

      我们看一个重要的类,frameworks\base\data\etc\Platform.xml

    <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
        <group gid="sdcard_rw" />
    </permission>

   

     对于申请了WRITE_EXTERNAL_STORAGE特权的应用,该应用的进程的gids就包含了sdcard_r,就可以对sd卡中的文件进行操作了。

     再看Android_filesystem_config.h的源码:

#define AID_SDCARD_RW 1015 /* external storage write access */

    也就是说这个权限映射到1015的gid,我们再来看一张图:

    我们查看com.android.phone这个进程,该应用申请了写外部内存卡的权限。首先使用ps查看该进程的进程号是1038,然后采用如下命令:


    我们看到这个进程的Groups里面有gid为1015,1015就是对应sdcard_r。

    5、除了我们在AndroidManifest.xml里面申请权限外,我们还可以在frameworks\base\data\etc\Platform.xml,assign权限,如下:

<assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="shell" />
    <assign-permission name="android.permission.SEND_SMS" uid="shell" />
    <assign-permission name="android.permission.CALL_PHONE" uid="shell" />
    <assign-permission name="android.permission.READ_CONTACTS" uid="shell" />
    <assign-permission name="android.permission.WRITE_CONTACTS" uid="shell" />
    <assign-permission name="android.permission.READ_CALENDAR" uid="shell" />
    <assign-permission name="android.permission.WRITE_CALENDAR" uid="shell" />
    <assign-permission name="android.permission.READ_USER_DICTIONARY" uid="shell" />
    <assign-permission name="android.permission.WRITE_USER_DICTIONARY" uid="shell" />
    <assign-permission name="android.permission.ACCESS_FINE_LOCATION" uid="shell" />
    <assign-permission name="android.permission.ACCESS_COARSE_LOCATION" uid="shell" />
    <assign-permission name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" uid="shell" />
    <assign-permission name="android.permission.ACCESS_NETWORK_STATE" uid="shell" />
    <assign-permission name="android.permission.ACCESS_WIFI_STATE" uid="shell" />
    <assign-permission name="android.permission.BLUETOOTH" uid="shell" />
    <!-- System tool permissions granted to the shell. -->
    <assign-permission name="android.permission.GET_TASKS" uid="shell" />
    <assign-permission name="android.permission.CHANGE_CONFIGURATION" uid="shell" />
    <assign-permission name="android.permission.REORDER_TASKS" uid="shell" />
    <assign-permission name="android.permission.SET_ANIMATION_SCALE" uid="shell" />
    <assign-permission name="android.permission.SET_PREFERRED_APPLICATIONS" uid="shell" />
    <assign-permission name="android.permission.WRITE_SETTINGS" uid="shell" />
    <assign-permission name="android.permission.WRITE_SECURE_SETTINGS" uid="shell" />
    <assign-permission name="android.permission.BROADCAST_STICKY" uid="shell" />
    <!-- Development tool permissions granted to the shell. -->
    <assign-permission name="android.permission.SET_DEBUG_APP" uid="shell" />
    <assign-permission name="android.permission.SET_PROCESS_LIMIT" uid="shell" />
    <assign-permission name="android.permission.SET_ALWAYS_FINISH" uid="shell" />
    <assign-permission name="android.permission.DUMP" uid="shell" />
    <assign-permission name="android.permission.SIGNAL_PERSISTENT_PROCESSES" uid="shell" />
    <!-- Internal permissions granted to the shell. -->
    <assign-permission name="android.permission.FORCE_BACK" uid="shell" />
    <assign-permission name="android.permission.BATTERY_STATS" uid="shell" />
    <assign-permission name="android.permission.INTERNAL_SYSTEM_WINDOW" uid="shell" />
    <assign-permission name="android.permission.INJECT_EVENTS" uid="shell" />
    <assign-permission name="android.permission.SET_ACTIVITY_WATCHER" uid="shell" />
    <assign-permission name="android.permission.READ_INPUT_STATE" uid="shell" />
    <assign-permission name="android.permission.SET_ORIENTATION" uid="shell" />
    <assign-permission name="android.permission.INSTALL_PACKAGES" uid="shell" />
    <assign-permission name="android.permission.CLEAR_APP_USER_DATA" uid="shell" />
    <assign-permission name="android.permission.DELETE_CACHE_FILES" uid="shell" />
    <assign-permission name="android.permission.DELETE_PACKAGES" uid="shell" />
    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="shell" />
    <assign-permission name="android.permission.READ_FRAME_BUFFER" uid="shell" />
    <assign-permission name="android.permission.DEVICE_POWER" uid="shell" />
    <assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />
    <assign-permission name="android.permission.BACKUP" uid="shell" />

    <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
    <assign-permission name="android.permission.ACCESS_DRM" uid="media" />
    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />

    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
      shell进程的权限我们 在Android中的权限管理(基于uid gid gids setUid),已经看到过其申请的权限对应的gids。那时候没有讲shell进程是怎么样申请的这个权限,这里解决了我们的疑问。

      由于platform.xml只有root用户可以操作,避免了安全问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android中的权限管理(基于Permission ProtectionLevel) 的相关文章

随机推荐

  • Docker镜像容器的迁移问题

    本文是本人项目踩坑经验 xff0c 如有错漏请见谅 xff01 背景需求 xff1a 一个已经配置好的容器 xff08 无build文件 xff09 需要部署到生产环境中 xff0c 容器内有程序绑定了宿主环境的硬件信息 需求部署后能让第三
  • 视觉里程计1 高翔

    小白 xff08 我 xff09 本着学习 xff0c 提高自我 xff0c 增加知识的想法 xff0c 决定认真分析高翔博士slam 在此立下一个flag xff1a 每周进行知识总结 xff08 CSDN xff09 xff1b 每周要
  • InvokeHelper函数的用法

    ActiveX控件的方法和属性操作与生成的C 43 43 类成员函数相关联都是通过InvokeHelper函数的调用来完成的 xff0c InvokeHelper函数的第一个参数是由Component Gallery xff08 控件提供者
  • 前向声明! struct netif; —— 只声明,无具体内部细节

    今天在看到 Linux阅码场 的 宋宝华 xff1a Linux内核编程广泛使用的前向声明 Forward Declaration xff0c 非常感谢 xff01 前向声明 编程定律 先强调一点 xff1a 在一切可能的场景 xff0c
  • MCU初始化流程——从上电到main()之间

    说明 xff1a 以下介绍示例的MCU地址空间如下 xff1a ROM空间为 xff1a 0x0000 0000 0x0000 8000 RAM空间为 xff1a 0x2000 0000 0x2000 2000 堆栈 SP 生长方向为 递减
  • FreeRTOS 启动第一个任务 prvStartFirstTask vPortSVCHandler

    asm void prvStartFirstTask void asm void prvStartFirstTask void PRESERVE8 Use the NVIC offset register to locate the sta
  • 组播知识 - IGMP

    https zhuanlan zhihu com p 258619129 组播初识 一 为什么要启用组播 xff1f 1 节省不必要的数据发送 2 需要发送相同的数据去往多个不同的接收者 3 减少带宽的占用 4 优化网络设备的处理进程 5
  • copy_from_user函数详细分析

    copy from user函数的目的是从用户空间拷贝数据到内核空间 xff0c 失败返回没有被拷贝的字节数 xff0c 成功返回0 这么简单的一个函数却含盖了许多关于内核方面的知识 比如内核关于异常出错的处理 从用户空间拷贝数据到内核中时
  • linux驱动中的宏 _IOC_NR, _IOC_TYPE, _IOC_SIZE, _IOC_DIR

    转载自 xff1a http blog csdn net u010245383 article details 29391805 虽然排版都点点乱 xff0c 但是内容还是较全面的 在驱动程序里 xff0c ioctl 函数上传送的变量 c
  • 【转载】更进一步的了解Keil Flash的下载算法

    转载自 xff1a https jingyan baidu com article 414eccf64f03be6b431f0af8 html 前面提到了通用算法的选择 xff0c 那么问题来了 xff0c 这个算法文件如何来的呢 xff1
  • 自己动手写操作系统-经典书籍

    汇编语言 xff0c 王爽编写 王爽老师这本书 xff0c 绝对是经典中的经典 xff0c 比其他介绍汇编语言的书强很多 这本书以例子贯穿整本书 不像其他书罗列一堆指令 这本书只介绍了常用指令 xff0c 而且每个指令都有例子 xff0c
  • golang 闭包 函数作为参数和返回值

    一 函数闭包 package main import 34 fmt 34 func adder func int int 函数作为返回值 sum 61 0 自由变量 xff0c 每次调用都保留上次的结果 return func v int
  • go routine channel select

    一 go routine channel package main import 34 fmt 34 34 time 34 func worker id int c chan int for n 61 range c 读取channel f
  • 我的vimrc配置文件

    34 vundle begin set nocompatible 34 与vi不一致 filetype off filetype plugin on 34 检测插件 set rtp 43 61 vim bundle vundle 34 载入
  • extern C 透彻理解

    一 背景 一直以来对extern C的理解都停留在表面 xff0c 只知道为了C C 43 43 混合编程 今天来透彻理解下这个概念 二 整体的项目结构 jni Android mk LOCAL PATH 61 call my dir in
  • 从ndk编译,说到so文件结构以及ida导入、导出函数

    一 背景 一直以来对ndk的编译链接所依赖的文件没有完成弄明白 xff0c 还有ida的导入 导出函数与dynsym section之间的关系是什么 xff1f 二 ndk编译所依赖的文件 1 我们一般在Application mk中指定所
  • C++ 布尔值用法

    一 整体代码 01 cpp include lt iostream gt include lt stdio h gt using namespace std int main void bool b 61 100 bool c 61 fal
  • UML 类图关系(继承,实现,依赖,关联,聚合,组合)

    1 继承 xff08 is a xff09 指的是一个类 xff08 称为子类 子接口 xff09 继承另外的一个类 xff08 称为父类 父接口 xff09 的功能 xff0c 并可以增加它自己的新功能的能力 xff0c 继承是类与类或者
  • Linux内核源代码情景分析-内存管理之slab-分配与释放

    首先说缓存区的数据结构 xff1a struct kmem cache s 1 each alloc amp free full partial first then free struct list head slabs 指向所有的sla
  • Android中的权限管理(基于Permission ProtectionLevel)

    1 什么是protectionlevel呢 xff1f 我们经常在AndroidManifest中使用权限 xff0c 如果我们想让应用程序可以发短信 xff0c 那么应该这样写 xff1a lt uses permission andro