Permission management in Android (based on Permission ProtectionLevel) and androidpermission
1. What is protectionlevel?
We often use permissions in AndroidManifest. If we want applications to send text messages, we should write as follows:
<uses-permission android:name="android.permission.SEND_SMS" />
So where is the definition of this permission defined? As follows:
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" />
This xml can be considered as AndroidManifest. xml used by the system apk. This apk uses the private key of the system for signature.
Name: Permission name, which is used by uses-permisson.
PermissionGroup: Permission type. When you are prompted to install permissionGroup, you will be given the same permissions as some functions.
ProtectionLevel: divided into Normal, Dangerous, Signature, SignatureOrSystem. We will focus on this later.
Description: The description of the permission that is displayed to the user.
2. protectionLevel
(1) Normal
The permission is declared as Normal and can be applied for by any application. When the application is installed, no prompt is sent to the user. Click All to display the permission.
(2) Dangerous
The permission is declared as Dangerous and can be applied for by any application. When an application is installed, a prompt is displayed to the user.
(3) Signature
The permission is declared as Signature level. Only applications with the same private key Signature as the apk that defines this permission can apply for this permission.
The permissions declared in frameworks/base/core/res/AndroidManifest. xml are at the Signature level. Only apps officially using the same private key Signature on Android can apply for this permission.
(4) SignatureOrSystem
The permission is declared at the SignatureOrSystem level and can be applied for by two applications.
1) the application that uses the same private key signature as the apk that defines this permission.
2) applications under the/system/app directory
3. Example
For example, the AndroidManifest. xml file of Baidu map apk declares a permission,
(1) Permission is defined as Dangerous, so any other application can use it.
(2) If the permission is defined as Signature, only the apk with the same private key Signature, such as Baidu online storage, can use this permission.
(3) If the permission is defined as SignatureOrSystem, you can use the apk signed with the same private key, such as Baidu online storage. You can also use this permission for applications under/system/app.
4. We naturally think of a question: how can we control whether a resource can be accessed in the Code if a permission is applied for or not?
(1) How do I control the unique permissions of the Android System in the code to access a resource? Let's look at a real example.
Client:
Void startDockOrHome () {awakenDreams (); ......} private static void awakenDreams () {IDreamManager dreamManager = getDreamManager (); if (dreamManager! = Null) {try {dreamManager. awaken (); // call the awaken} catch (RemoteException e) {// fine, stay asleep then }}
Server:
@Override // Binder callpublic 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); }}
The Client and Server communicate through the Binder process communication mechanism. On the Server side, check whether the Client declares this permission through checkPermission.
(2) For non-Android-specific services (provided by the underlying platform, such as File access and TCPIP data sending and receiving), multiple access entries: Android API, Java API, both ndk c api and shell can be accessed. In this way, permission control is implemented at the underlying layer, so it is centrally controlled at the underlying layer. This underlying unified control is actually the traditional Linux File Read/Write execution permission (rwx ).
For example, you have applied for the SD card write permission in the application:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
We need to map the Permission ing of the Android space to the GID of the OS.
Let's look at an important class: frameworks \ base \ data \ etc \ Platform. xml
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" > <group gid="sdcard_rw" /> </permission>
For applications that have applied for the WRITE_EXTERNAL_STORAGE privilege, the gids of the application process includes sdcard_r, and the files in the SD card can be operated.
Let's look at the source code of Android_filesystem_config.h:
#define AID_SDCARD_RW 1015 /* external storage write access */
That is to say, this permission is mapped to the gid of 1015. Let's take a look at the figure:
Let's check the com. android. phone process. The app has applied for the permission to write an external memory card. Run the following command to check that the process number is 1038 in ps:
We can see that the Groups of this process has a gid of 1015,1015, Which is corresponding to sdcard_r.
5. In addition to applying for permissions in AndroidManifest. xml, we can also apply for permissions in frameworks \ base \ data \ etc \ Platform. xml and assign as follows:
<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" />
Permission management for shell processes in Android (based on uid gid gids setUid), we have seen the gids corresponding to the permissions applied. At that time, we didn't talk about how the shell process applied for this permission. Here we solve our questions.
Since platform. xml can only be operated by the root user, security issues are avoided.
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.