Did the meaning of „Protection Level: signature“ change with Android 6? 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 ;)
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 &amp;&amp; (bp.protectionLevel
            &amp; PermissionInfo.PROTECTION_FLAG_PRE23) != 0
            &amp;&amp; pkg.applicationInfo.targetSdkVersion &lt; 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 &amp;&amp; (bp.protectionLevel &amp; PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
            &amp;&amp; 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 &amp;&amp; (bp.protectionLevel &amp; PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
            &amp;&amp; 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 &amp;&amp; (bp.protectionLevel
            &amp; PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
            &amp;&amp; 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:

 &lt;permission android:name="android.permission.WRITE_SETTINGS"
        android:label="@string/permlab_writeSettings"
        android:description="@string/permdesc_writeSettings"
        android:protectionLevel="signature|preinstalled|appop|pre23" /&gt;


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.