概述
问题
今天尝试用一个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权限管理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复