2

The Developer documentation writes on the protection level "signature":

A permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user's explicit approval.

This was as I always knew it. But it seems to somehow contradict what the same documentation writes about WRITE_SETTINGS, which is marked as "Protection level: signature":

If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen.

Does that mean the behavior towards this has changed with Marshmallow – and a non-system app using a different signature can still access functionality covered by it, provided the user agrees? Also, with the new "mentality" of automatically granting permissions of a group where the user already has another permission granted: is this permission also granted automatically then (like with all permissions of the protection level "dangerous") – or is the difference here that it always requires the user's agreement, no matter what?


Note 1: there were a lot of changes towards how permissions are dealt with in Android 6+. To not make a "too broad" question, I've tried to split it up; so for the other parts, please also see: Permission system changes with Android 6.0: What are the implications for us users? and Android 6+ and account permissions: where have they gone to?

Note 2: This definitely is of relevance to the end user, as it's about his/her data – and cross-checking permissions for possible implications should be part of the installation or rather app selection process. I'm not asking from the perspective of a developer on how to deal with that when writing an app (though that might be interesting at well ;)

  • Above API level 23 requires accepting permissions when they're requested... Old versions excepted permissions on install ! – Gadget Guru Sep 19 '16 at 1:41
  • @ProbablyThis Thanks, but that's not the point I'm asking about (I'm aware of this difference ;). My point is: 3rd party apps (installed by the user) were only granted permissions with protection level "normal" (granted without the need of approval) and "dangerous" (that are those the user has explicitely to agree to – be it on install before MM, or on request with MM and up). Protection level "signature" permissions were only granted if the signature matched that of the app granting it. Has that changed? I'm not asking about "on install" versus "on runtime". – Izzy Sep 19 '16 at 6:30
2
+50

No, the meaning of protection level of "signature" is not changed in Android 6.

We can 'git blame' the file PackageManagerService.java and check function grantSignaturePermission. The basic logic didn't change since Android Lollipop. The following logic was added in Android 6:

    if (!allowed && (bp.protectionLevel
            & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
            && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
        // If this was a previously normal/dangerous permission that got moved
        // to a system permission as part of the runtime permission redesign, then
        // we still want to blindly grant it to old apps.
        allowed = true;
    }
    if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
            && pkg.packageName.equals(mRequiredInstallerPackage)) {
        // If this permission is to be granted to the system installer and
        // this app is an installer, then it gets the permission.
        allowed = true;
    }
    if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
            && pkg.packageName.equals(mRequiredVerifierPackage)) {
        // If this permission is to be granted to the system verifier and
        // this app is a verifier, then it gets the permission.
        allowed = true;
    }
    if (!allowed && (bp.protectionLevel
            & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
            && isSystemApp(pkg)) {
        // Any pre-installed system app is allowed to get this permission.
        allowed = true;
    }

From the above code, we can see,

  • if the permission is specified with "signature|pre23" and the app target sdk version is less then 23, it will get this permission, because this permission was moved to system permission in Android 6.
  • if the permission is specified with "signature|preinstalled" and the app is pre-installed system app, it will get the permission
  • if the permission is specified with "signature|installer" or "signature|verifier" and the app is installer and verifier, it will get the permission.

Conclusion: the signature protection level didn't change its meaning in Android 6. If a permission has signature protection level with other flag, such as pre23, preinstalled, intaller or verifier, it has new meanings.


The following explains the confusion about WRITE_SETTING permission in the question:

The documentation on WRITE_SETTING is incorrect about protection level. If you look at the Android source code at frameworks/base/core/res/AndroidManifest.xml:

 <permission android:name="android.permission.WRITE_SETTINGS"
        android:label="@string/permlab_writeSettings"
        android:description="@string/permdesc_writeSettings"
        android:protectionLevel="signature|preinstalled|appop|pre23" />

you can see the protection level is signature|preinstalled|appop|pre23.

A non-system app using a different signature can access functionality because of the protection level of appop, which means the user can choose if this permission is on or off.

  • Good find, thanks! Wouldn't be the first time the docs are flaky. If you could name some authoritative ("credible and/or official") source to back that in general (i.e. not only for WRITE_SETTINGS, but for protectionLevel:signature), I'd award you the bounty immediately! – Izzy Oct 8 '16 at 22:46
  • 1
    The most credible and official source about protectionLevel:signature should be the Android Source Code. We can 'git blame' the file PackageManagerService.java and check function grantSignaturePermission. The basic logic didn't change since Android Lollipop. – Albert Ma Oct 9 '16 at 3:38
  • Good points again, Albert. Not being a dev myself: Am I assuming correctly you've already checked the function and did a "blame"? The link given currently times out on me. – Izzy Oct 10 '16 at 9:51
  • 1
    Yes, lzzy. I did a "git blame" on the function and added more detailed conclusion in my answer. – Albert Ma Oct 11 '16 at 2:33
  • Thanks a lot for your efforts, Albert! Bounty awarded :) Special thanks for outlining how the process was extended with new protection levels. I've never seen preinstalled before (neither appop nor pre23, but these two are quite self-explaining in the context, as AppOp was officially introduced with 23/MM). As so often, documentation hasn't been updated to include the new plevels. If you got any link on those, it will be appreciated! +15rep (accept) then #D – Izzy Oct 13 '16 at 10:15
0

SHORT ANSWER
YES


LONG ANSWER from permission documentations

Permission groups

All dangerous Android system permissions belong to permission groups. If the device is running Android 6.0 (API level 23) and the app's targetSdkVersion is 23 or higher, the following system behavior applies when your app requests a dangerous permission:

If an app requests a dangerous permission listed in its manifest, and the app does not currently have any permissions in the permission group, the system shows a dialog box to the user describing the permission group that the app wants access to. The dialog box does not describe the specific permission within that group. For example, if an app requests the READ_CONTACTS permission, the system dialog box just says the app needs access to the device's contacts. If the user grants approval, the system gives the app just the permission it requested.If an app requests a dangerous permission listed in its manifest, and the app already has another dangerous permission in the same permission group, the system immediately grants the permission without any interaction with the user. For example, if an app had previously requested and been granted the READ_CONTACTS permission, and it then requests WRITE_CONTACTS, the system immediately grants that permission.


Please Watch This About 23+ Practices
BEST PRACTICES AND CHANGES FOR API 23 +

  • Sorry, but again: I didn't ask for "protection level: dangerous", but for "protection level: signature". As I wrote, I'm aware of the change to "runtime permission requests" with Android 6+, so that's not what I'm asking about. As the title says, I'm asking specifically for "protection level: signature". Your answer only covers "protection level: dangerous". See: developer documentation on permissions: protection level. – Izzy Sep 19 '16 at 6:52
  • The video goes for 30min and it's supposed to explain the changes for permissions after 23+........ It's all i can find..... Other than "signature" was introduced in API level 1...... The Play Store Say's that individual signatures are required for separate apps.... so i gather that, you are trying to use two apps to access one signature permission, this isn't possible due to the individual permission for apps and the current permission system seems to have overlooked this... – Gadget Guru Sep 19 '16 at 6:53
  • Thanks for your efforts. I've also tried all my Google-Fu (and found several pages detailling on the API changes for MM, none of them covering this detail – which is why I am asking here). Also see my other question on that: Permission system changes with Android 6.0: What are the implications for us users?, where I mention some of my findings. Still, this doesn't answer my question. – Izzy Sep 19 '16 at 6:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.