我是靠谱客的博主 优秀雪碧,最近开发中收集的这篇文章主要介绍android权限管理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

问题
今天尝试用一个android application读写网卡的mac地址,java层通过jni用ioctl命令。在将apk放在/system/app中、设置platform签名凭证、以及设置shareUid后,发现设置MAC地址(ioctl(SIOCSIFHWADDR))总是有权限问题,而读取MAC地址(ioctl(SIOCGIFHWADDR))则正常。

kernel检查
跟踪到kernel中net/core/dev.c,在函数dev_ioctl中,会检查CAP_NET_ADMIN权限:

if (! capable ( CAP_NET_ADMIN ))
  return - EPERM ;


进入这个函数,发现检查的是进程是否在group AID_NET_ADMIN中:

if ( cap == CAP_NET_ADMIN && in_egroup_p ( AID_NET_ADMIN ))
  return 0 ;


这里AID_NET_ADMIN跟android在init中的权限定义有些类似。

android权限定义
在system/core/include/private/android_filesystem_config.h中,android定义了一组uid和gid,如AID_ROOT, AID_SYSTEM, AID_NET_ADMIN。每一个id对应有字符串,如root, system, net_admin。当用户程序需要访问受限资源是,需要保证自己加入到对应的group中。

我在frameworks中搜索net_admin,没有找到任何文件。搜索蓝牙权限net_bt_admin时,找到了文件/etc/permissions/platform.xml。这里存放有AndroidManifest.xml中权限与底层权限的对应关系:

<permission name = "android.permission.BLUETOOTH_ADMIN" >
    <group gid = "net_bt_admin" />
</permission>  


我想,当开发者在AndroidManifest.xml中申请权限时,framework会通过platform.xml将它对应到net_bt_admin,进而确定所属组AID_XXX。这样,每个apk就有不同的权限。

另外,在android_filesystem_config.h,还可以看到为某些特定目录和特定文件静态设置的group,如/system/bin/ping加入了AID_NET_RAW。

尝试
我在platform.xml的android.permission.INTERNET权限下加入了group net_admin,使它变成:

<permission name = "android.permission.INTERNET" >                    
    <group gid = "inet" />                                          
    <group gid = "net_admin" />                                            
</permission>  


然后,在AndroidManifest.xml中请求权限android.permission.INTERNET。重启系统后运行apk,发现可以修改mac了!


apk文件的group设置
PackageManagerService构造函数会解析platform.xml,建立android权限和gid的对应关系。然后,扫描apk时,会由请求的权限找到对应的gid,并保存在Package类中。

PackageManagerService ()
  readPermissions (); /* 解析/etc/permissions/platform.xml */
    readPermissionsFromXml ()
      readPermission () /* 建立permisstion名字与gid的关系,放在map mSettings.mPermissions中*/
  scanDirLI () /* 扫描/system/app, /data/app */
  updatePermissionsLP ()
    grantPermissionsLP ()

      

grantPermissionsLP ()
{
  final PackageSetting ps = ( PackageSetting ) pkg . mExtras ;

  /* gp 指向ps,即pkg的PackageSetting成员 */
  final GrantedPermissions gp = ps . sharedUser != null ? ps . sharedUser : ps ;

  /* 设置gid */
  gp . gids = mGlobalGids ;

  /* 如果package请求了permission, 则根据permission的protectionLevel决定是否要授予特定的gid,加入到gids中 */
}  


protectionLevel有4种:
normal - 安装时即授予权限,不需要确认
dangerous - 危险的权限,需要用户确认授予
signature - 安装的app需要与声明该权限的app有相同的signature
signatureOrSystem - 拥有相同的signature,或者放在system image中

比如拿android.permission.WRITE_SECURE_SETTINGS来讲,即使用户在app中声明的该权限,如果不把它放在system中,或者用platform key签名的话,android是不会授予该权限的。因为,在声明该权限的地方,即frameworks/base/core/res/AndroidManifest.xml中,该权限被声明为signatureOrSystem,而该app是用platform key签名的。

不管怎样,根据实际情况,android会给app授予一定的用户组。具体来说,apk的group信息是保存在pkg.mExtras中。在启动apk是,可以看到adb打印:

I/ActivityManager(  134): Start proc com.android.settings for activity com.android.settings/.Settings: pid=792 uid=1000 gids={3003, 3005, 3002, 3001}


后面的{3003, 3005, 3002, 3001}就是所在的组的id列表。

最后

以上就是优秀雪碧为你收集整理的android权限管理的全部内容,希望文章能够帮你解决android权限管理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部