Android Permission【转】
http://blog.csdn.net/stevenliyong/article/details/5343085
1. 文件(夹)读写权限
init.rc 中建立test1 test2 test3 文件夹
mkdir /data/misc/test1 0770 root root
mkdir /data/misc/test2 0770 wifi wifi
mkdir /data/misc/test3 0770 system misc
其中
test1 目录的owner是root, group 也是root
test2 目录的owner是wifi , group 也是wifi
test3 目录的owner是system , group 是misc (任何用户都属于group misc)
service xxxx /system/bin/xxxx
user root
disabled
oneshot
service yyyy /system/bin/yyyy
user system
disabled
oneshot
service zzzz /system/bin/zzzz
user wifi
disabled
oneshot
结果:
xxxx 服务可以访问 test1, test2, test3
yyyy 服务可以访问 test3
zzzz 服务可以访问 test2, test3
Android 中mkdir 的定义
[cpp] view plaincopy
- int do_mkdir(int nargs, char **args)
- {
- mode_t mode = 0755;
- /* mkdir <path> [mode] [owner] [group] */
- if (nargs >= 3) {
- mode = strtoul(args[2], 0, 8);
- }
- if (mkdir(args[1], mode)) {
- return -errno;
- }
- if (nargs >= 4) {
- uid_t uid = decode_uid(args[3]);
- gid_t gid = -1;
- if (nargs == 5) {
- gid = decode_uid(args[4]);
- }
- if (chown(args[1], uid, gid)) {
- return -errno;
- }
- }
- return 0;
- }
2. Property 权限
Android Property 也是有权限的。
2.1 以前缀 ctl. 开头的控制属性, 设置前,Android 代码会调用函数check_control_perms()检查调用者的 user id 和 group id
[cpp] view plaincopy
- struct {
- const char *service;
- unsigned int uid;
- unsigned int gid;
- } control_perms[] = {
- { "dumpstate",AID_SHELL, AID_LOG },
- {NULL, 0, 0 }
- };
- static int check_control_perms(const char *name, int uid, int gid) {
- int i;
- if (uid == AID_SYSTEM || uid == AID_ROOT)
- return 1;
- /* Search the ACL */
- for (i = 0; control_perms[i].service; i++) {
- if (strcmp(control_perms[i].service, name) == 0) {
- if ((uid && control_perms[i].uid == uid) ||
- (gid && control_perms[i].gid == gid)) {
- return 1;
- }
- }
- }
- return 0;
- }
2.2 其它属性, 设置前,Android 代码会调用函数check_perms()检查调用者的 user id 和 group id
check_perms(msg.name, cr.uid, cr.gid)
[cpp] view plaincopy
- struct {
- const char *prefix;
- unsigned int uid;
- unsigned int gid;
- } property_perms[] = {
- { "net.rmnet0.", AID_RADIO, 0 },
- { "net.gprs.", AID_RADIO, 0 },
- { "net.ppp", AID_RADIO, 0 },
- { "ril.", AID_RADIO, 0 },
- { "gsm.", AID_RADIO, 0 },
- { "persist.radio", AID_RADIO, 0 },
- { "net.dns", AID_RADIO, 0 },
- { "net.", AID_SYSTEM, 0 },
- { "dev.", AID_SYSTEM, 0 },
- { "runtime.", AID_SYSTEM, 0 },
- { "hw.", AID_SYSTEM, 0 },
- { "sys.", AID_SYSTEM, 0 },
- { "service.", AID_SYSTEM, 0 },
- { "wlan.", AID_SYSTEM, 0 },
- { "dhcp.", AID_SYSTEM, 0 },
- { "dhcp.", AID_DHCP, 0 },
- { "vpn.", AID_SYSTEM, 0 },
- { "vpn.", AID_VPN, 0 },
- { "debug.", AID_SHELL, 0 },
- { "log.", AID_SHELL, 0 },
- { "service.adb.root", AID_SHELL, 0 },
- { "persist.sys.", AID_SYSTEM, 0 },
- { "persist.service.", AID_SYSTEM, 0 },
- { NULL, 0, 0 }
- };
- static int check_perms(const char *name, unsigned int uid, int gid)
- {
- int i;
- if (uid == 0)
- return 1;
- if(!strncmp(name, "ro.", 3))
- name +=3;
- for (i = 0; property_perms[i].prefix; i++) {
- int tmp;
- if (strncmp(property_perms[i].prefix, name,
- strlen(property_perms[i].prefix)) == 0) {
- if ((uid && property_perms[i].uid == uid) ||
- (gid && property_perms[i].gid == gid)) {
- return 1;
- }
- }
- }
- return 0;
- }
从代码中可以看到, 任何不以property_perms[] 中定义的前缀开头的property 是
无法被除root以外的用户访问的,包括system用户。
3. 最后补充Android 的uid gid 定义
[cpp] view plaincopy
- #define AID_ROOT 0 /* traditional unix root user */
- #define AID_SYSTEM 1000 /* system server */
- #define AID_RADIO 1001 /* telephony subsystem, RIL */
- #define AID_BLUETOOTH 1002 /* bluetooth subsystem */
- #define AID_GRAPHICS 1003 /* graphics devices */
- #define AID_INPUT 1004 /* input devices */
- #define AID_AUDIO 1005 /* audio devices */
- #define AID_CAMERA 1006 /* camera devices */
- #define AID_LOG 1007 /* log devices */
- #define AID_COMPASS 1008 /* compass device */
- #define AID_MOUNT 1009 /* mountd socket */
- #define AID_WIFI 1010 /* wifi subsystem */
- #define AID_ADB 1011 /* android debug bridge (adbd) */
- #define AID_INSTALL 1012 /* group for installing packages */
- #define AID_MEDIA 1013 /* mediaserver process */
- #define AID_DHCP 1014 /* dhcp client */
- #define AID_SDCARD_RW 1015 /* external storage write access */
- #define AID_VPN 1016 /* vpn system */
- #define AID_KEYSTORE 1017 /* keystore subsystem */
- #define AID_SHELL 2000 /* adb and debug shell user */
- #define AID_CACHE 2001 /* cache access */
- #define AID_DIAG 2002 /* access to diagnostic resources */
- /* The 3000 series are intended for use as supplemental group id's only.
- * They indicate special Android capabilities that the kernel is aware of. */
- #define AID_NET_BT_ADMIN 3001 /* bluetooth: create any socket */
- #define AID_NET_BT 3002 /* bluetooth: create sco, rfcomm or l2cap sockets */
- #define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */
- #define AID_NET_RAW 3004 /* can create raw INET sockets */
- #define AID_NET_ADMIN 3005 /* can configure interfaces and routing tables. */
- #define AID_MISC 9998 /* access to misc storage */
- #define AID_NOBODY 9999
- #define AID_APP 10000 /* first app user */
可见root (AID_ROOT = 0) 的权限最高, app (AID_APP = 10000) 权限最低, misc (AID_MISC = 9998) 权限倒数第三低。
所以#1 中描述的目录test3的group 属性设置成了 misc, 则除了 app/nobody 这两个用户,
android系统中其它所有用户都有该目录的group权限!
http://developer.android.com/guide/topics/security/permissions.html
Application Signing
All Android applications (.apk files) must be signed with a certificate whose private key is held by their developer. This certificate identifies the author of the application. The certificate does not need to be signed by a certificate authority(证书不需要由认证机构签发): it is perfectly allowable, and typical, for Android applications to use self-signed certificates. The purpose of certificates in Android is to distinguish application authors. This allows the system to grant or deny applications access to signature-level permissions and to grant or deny an application'srequest to be given the same Linux identity as another application.
User IDs and File Access
At install time, Android gives each package a distinct Linux user ID. The identity remains constant for the duration of the package's life on that device. On a different device, the same package may have a different UID; what matters is that each package has a distinct UID on a given device.
Because security enforcement happens at the process level, the code of any two packages can not normally run in the same process, since they need to run as different Linux users. You can use the sharedUserId
attribute in the AndroidManifest.xml
's manifest
tag of each package to have them assigned the same user ID. By doing this, for purposes of security the two packages are then treated as being the same application, with the same user ID and file permissions. Note that in order to retain security, only two applications signed with the same signature (and requesting the same sharedUserId) will be given the same user ID.
Any data stored by an application will be assigned that application's user ID, and not normally accessible to other packages. When creating a new file with getSharedPreferences(String, int)
, openFileOutput(String, int)
, or openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory)
, you can use theMODE_WORLD_READABLE
and/or MODE_WORLD_WRITEABLE
flags to allow any other package to read/write the file. When setting these flags, the file is still owned by your application, but its global read and/or write permissions have been set appropriately so any other application can see it.
Using Permissions
A basic Android application has no permissions associated with it by default, meaning it can not do anything that would adversely impact the user experience or any data on the device. To make use of protected features of the device, you must include in your AndroidManifest.xml
one or more
tags declaring the permissions that your application needs.<uses-permission>
For example, an application that needs to monitor incoming SMS messages would specify:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.app.myapp" >
<uses-permission android:name="android.permission.RECEIVE_SMS" />
...
</manifest>
At application install time, permissions requested by the application are granted to it by the package installer, based on checks against the signatures of the applications declaring those permissions and/or interaction with the user(通过检查应用签名或与用户交互来提示是否允许授权某些权限). No checks with the user are done while an application is running: it either was granted a particular permission when installed, and can use that feature as desired, or the permission was not granted and any attempt to use the feature will fail without prompting the user.