On 06/28/2013 08:29 AM, Richard Haines wrote:
I've been experimenting with the Content Provider MAC using a resolver app
installed as "untrusted_app" and a Content Provider installed as "release_app".
The device content_permissions.xml file entries are shown below that were
added as a BOARD_SEPOLICY_UNION in the device BoardConfig.mk file.
The problem is that when setTypes() is called by the PM the
"demo_resolver_package" type entry was never selected. This is because the
code in ContentSecurityManager.java selected the first match on the signature.
The attached patch will now check if the package the PM is processing has a
matching "package value=" entry in the package types and if found process
these first.
I'm not sure if this is the best way but does at least work (note if the
content_permissions.xml file entries shown below are added at the beginning
of the external/sepolicy/content_permissions.xml, then they would be found
without the patch, simply because the sigs match first).
content_permissions.xml file entries:
<policy>
<!-- Resolver Package Type -->
<type name="demo_resolver_package" component="package">
<package value="com.example.resolvecontentdemo" />
<permission value="com.example.contentprovider1.READ" />
<permission value="com.example.contentprovider1.WRITE" />
</type>
<!-- Provider Content Type -->
<type name="demo_provider">
<package value="com.example.contentprovider1" />
<signature value="@RELEASE"/>
<provider value="com.example.contentprovider1.contentproviderdemo"/>
<export-read value="normal" />
<export-write value="dangerous" />
</type>
<allow-content>
<allow source="demo_resolver_package" destination="demo_provider"
permission="use;rw"/>
<allow source="demo_resolver_package" destination="settings_provider"
permission="use;r"/>
</allow-content>
</policy>
Richard
Try the patch below instead (I'm presently building and testing
right now it but it should work....). When the content_permissions.xml
file is read, the stanzas are then sorted based on a set of precedence
rules found in ContentSecurityManager.java (look for the
'packageComparator' object). The sorting ensures we only ever assign one
type per package by the PMS. This is also the same type of logic used
for assigning types to the content providers just using a different sort
function.
The original sorter for packages only considered if the signature
tag was present in the package stanza policy. This helps explain some of
the behaviour you outlined above. Essentially, if your stanza is
missing a signature tag it will be of equal precedence when compared to
other stanzas without a signature tag. Since our ref policy also
includes a 'default_package' type (no child tags attached and therefore
really meant to serve as a catch all), this will be selected over other
entries that are added after it which don't have a signature tag. This
might also explain why if you place your stanza first in the file
instead of with the UNION construct it seems to work. We just need to
beef up the comparator to sort based on more selectors -- the attached
patch does this.
Since the cp_mac is largely experimental in nature, our
documentation is this area is a bit lacking. I'll see if I can't just
add some comments to the top of the content_permissions.xml file to
avoid future headaches. I'll get some additions pushed to the cp_mac to
add the precedence rules and some greater guidance on configuration.
diff --git a/services/java/com/android/server/pm/ContentSecurityManager.java b/services/java/com/android/server/pm/ContentSecurityManager.java
index 6204e59..c46b793 100644
--- a/services/java/com/android/server/pm/ContentSecurityManager.java
+++ b/services/java/com/android/server/pm/ContentSecurityManager.java
@@ -141,6 +141,8 @@ public final class ContentSecurityManager {
/*
Precedence rules:
(1)signature defined over signature not defined
+ (2)package name defined over package name not defined
+ (3)permission set defined over permission set not defined
Throughout, there is no distinction between a stanza that
has more signatures then another. They are considered
@@ -156,6 +158,18 @@ public final class ContentSecurityManager {
if (a.mSignatures == null && b.mSignatures != null)
return 1;
+ // defined package name over not defined package name
+ if (a.mPackageName != null && b.mPackageName == null)
+ return -1;
+ if (a.mPackageName == null && b.mPackageName != null)
+ return 1;
+
+ // defined permission set over not defined permission set
+ if (a.mPermissionSet != null && b.mPermissionSet == null)
+ return -1;
+ if (a.mPermissionSet == null && b.mPermissionSet != null)
+ return 1;
+
// Equal precedence
return 0;
}