Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Corresponding group ID not added to the process of the application

Adb command adb shell dumpsys package com.hackerli.girl can help me get application info.

Before I request android.permission.WRITE_EXTERNAL_STORAGE permission, my app has a gids=[3003].

requested permissions:
  android.permission.INTERNET
  android.permission.WRITE_EXTERNAL_STORAGE
  android.permission.READ_EXTERNAL_STORAGE
  android.permission.ACCESS_NETWORK_STATE
install permissions:
  android.permission.INTERNET: granted=true
  android.permission.ACCESS_NETWORK_STATE: granted=true
User 0: ceDataInode=1531967 installed=true hidden=false suspended=false stopped=true notLaunched=false enabled=0
  gids=[3003]
  runtime permissions:
User 999: ceDataInode=0 installed=false hidden=false suspended=false stopped=true notLaunched=true enabled=0
  gids=[3003]
  runtime permissions:

After runtime permission android.permission.WRITE_EXTERNAL_STORAGE is granted, I get below info.

requested permissions:
  android.permission.INTERNET
  android.permission.WRITE_EXTERNAL_STORAGE
  android.permission.READ_EXTERNAL_STORAGE
  android.permission.ACCESS_NETWORK_STATE
install permissions:
  android.permission.INTERNET: granted=true
  android.permission.ACCESS_NETWORK_STATE: granted=true
User 0: ceDataInode=1531967 installed=true hidden=false suspended=false stopped=false notLaunched=false enabled=0
  gids=[3003]
  runtime permissions:
    android.permission.READ_EXTERNAL_STORAGE: granted=true
    android.permission.WRITE_EXTERNAL_STORAGE: granted=true
User 999: ceDataInode=0 installed=false hidden=false suspended=false stopped=true notLaunched=true enabled=0
  gids=[3003]
  runtime permissions:

As you see, READ_EXTERNAL_STORAGE permission is also granted since it belongs to as same group as WRITE_EXTERNAL_STORAGE. However the gids is not changed. I think it should be updated so is there anything I mistake?

like image 313
CoXier Avatar asked Nov 07 '22 09:11

CoXier


1 Answers

Summary

The android.permission.WRITE_EXTERNAL_STORAGE is now (> API 23) implemented as a built-in android permission and is now managed by the runtime. Earlier (< API 23) the permission was part the low-level kernel enforced group of permission implemented as Linux Supplementary Group, i.e, by assigning the groups to the App on install time.

Behaviour prior to Marshmallow (< API 23)

Before Marshmallow (specifically before introduction of Runtime Permission), the android.permission.WRITE_EXTERNAL_STORAGE was implemented at kernel level. Whenever any process try to access the external storage, the call goes through the kernel (the open() syscall) where the kernel checked the permissions of the calling process (usual Linux stuff...). For the geeks this is how the call-stack looks like:

  1. To read a File you open a stream to it using the FileOutputStream. When we construct a FileOutputStream, this calls IOBridge.open(String, int). IOBridge is an internal class and delegates the opening to native JNI-call.

  2. Inside the IOBridge.open() call, the method delegates to Libcore.os.open(). Again Libcore is an internal class.

  3. The Libcore.os.open() is a native method, implemented here. And here, the method calls the open() syscall and the kernel kicks-in!

Behaviour starting Marshmallow (>= API 23)

Starting with Marshmallow (with introduction of Runtime Permission) developers are required to ask for the android.permission.WRITE_EXTERNAL_STORAGE from the user. This changes the way the permission is assigned to the app. Android still assigns normal permissions at install time but for dangerous app Android requires the app to display a popup asking for the permission. When the user grants the permission, the PackageManager records it and adds it to the app's database record (in /data/system/packages.xml). If the permission is a low-level permission, i.e., implemented by kernel using groups then the PackageManager adds the app's user id to the corresponding group too. Earlier the android.permission.WRITE_EXTERNAL_STORAGE was implemented as a low-level permission (hence managed by kernel) but now the app is implemented as a built-in permission managed by runtime. The call-stack now looks like:

  1. To read a File you open a stream to it using the FileOutputStream. When we construct a FileOutputStream, which calls the private FileOutputStream.open() native function implemented here.

  2. The native FileOutputStream.open() calls the helper fileOpen() which delegates call to JVM_Open() implemented by runtime and thus the runtime now manages the permission.

Because the app is not added to the group, so it is not displayed in dumpsys.

For more details about permissions and security on Android, I would recommend you read Android Security Internals by Nikolay Elenkov

like image 146
riyaz-ali Avatar answered Nov 14 '22 21:11

riyaz-ali