diff options
| -rw-r--r-- | core/java/android/content/pm/ApplicationInfo.java | 8 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/SELinuxMMAC.java | 232 |
2 files changed, 53 insertions, 187 deletions
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 6feb86036791..914945b2f64a 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -531,12 +531,14 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** * String retrieved from the seinfo tag found in selinux policy. This value - * is useful in setting an SELinux security context on the process as well - * as its data directory. + * can be overridden with a value set through the mac_permissions.xml policy + * construct. This value is useful in setting an SELinux security context on + * the process as well as its data directory. The String default is being used + * here to represent a catchall label when no policy matches. * * {@hide} */ - public String seinfo; + public String seinfo = "default"; /** * Paths to all shared libraries this application is linked against. This diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java index c75a1d306a87..66170d453260 100644 --- a/services/core/java/com/android/server/pm/SELinuxMMAC.java +++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java @@ -136,9 +136,6 @@ public final class SELinuxMMAC { case "signer": policies.add(readSignerOrThrow(parser)); break; - case "default": - policies.add(readDefaultOrThrow(parser)); - break; default: skip(parser); } @@ -233,45 +230,6 @@ public final class SELinuxMMAC { } /** - * Loop over a default element looking for seinfo child tags. A {@link Policy} - * instance will be created and returned in the process. All other tags encountered - * will be skipped. - * - * @param parser an XmlPullParser object representing a default element. - * @return the constructed {@link Policy} instance - * @throws IOException - * @throws XmlPullParserException - * @throws IllegalArgumentException if any of the validation checks fail while - * parsing tag values. - * @throws IllegalStateException if any of the invariants fail when constructing - * the {@link Policy} instance. - */ - private static Policy readDefaultOrThrow(XmlPullParser parser) throws IOException, - XmlPullParserException { - - parser.require(XmlPullParser.START_TAG, null, "default"); - Policy.PolicyBuilder pb = new Policy.PolicyBuilder(); - pb.setAsDefaultPolicy(); - - while (parser.next() != XmlPullParser.END_TAG) { - if (parser.getEventType() != XmlPullParser.START_TAG) { - continue; - } - - String tagName = parser.getName(); - if ("seinfo".equals(tagName)) { - String seinfo = parser.getAttributeValue(null, "value"); - pb.setGlobalSeinfoOrThrow(seinfo); - readSeinfo(parser); - } else { - skip(parser); - } - } - - return pb.build(); - } - - /** * Loop over a package element looking for seinfo child tags. If found return the * value attribute of the seinfo tag, otherwise return null. All other tags encountered * will be skipped. @@ -337,35 +295,28 @@ public final class SELinuxMMAC { /** * Applies a security label to a package based on an seinfo tag taken from a matched - * policy. All signature based policy stanzas are consulted first and, if no match - * is found, the default policy stanza is then consulted. The security label is - * attached to the ApplicationInfo instance of the package in the event that a matching - * policy was found. + * policy. All signature based policy stanzas are consulted and, if no match is + * found, the default seinfo label of 'default' (set in ApplicationInfo object) is + * used. The security label is attached to the ApplicationInfo instance of the package + * in the event that a matching policy was found. * * @param pkg object representing the package to be labeled. - * @return boolean which determines whether a non null seinfo label was assigned - * to the package. A null value simply represents that no policy matched. */ - public static boolean assignSeinfoValue(PackageParser.Package pkg) { + public static void assignSeinfoValue(PackageParser.Package pkg) { synchronized (sPolicies) { for (Policy policy : sPolicies) { String seinfo = policy.getMatchedSeinfo(pkg); if (seinfo != null) { pkg.applicationInfo.seinfo = seinfo; - if (DEBUG_POLICY_INSTALL) { - Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " + - "seinfo=" + seinfo); - } - return true; + break; } } } if (DEBUG_POLICY_INSTALL) { - Slog.i(TAG, "package (" + pkg.packageName + ") doesn't match any policy; " + - "seinfo will remain null"); + Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " + + "seinfo=" + pkg.applicationInfo.seinfo); } - return false; } /** @@ -506,30 +457,16 @@ public final class SELinuxMMAC { * .build(); * } * </pre> - * <p> - * The following is an example of how to use {@link Policy.PolicyBuilder} to create a - * default based Policy instance. - * </p> - * <pre> - * {@code - * Policy policy = new Policy.PolicyBuilder() - * .setAsDefaultPolicy() - * .setGlobalSeinfoOrThrow("default") - * .build(); - * } - * </pre> */ final class Policy { private final String mSeinfo; - private final boolean mDefaultStanza; private final Set<Signature> mCerts; private final Map<String, String> mPkgMap; // Use the PolicyBuilder pattern to instantiate private Policy(PolicyBuilder builder) { mSeinfo = builder.mSeinfo; - mDefaultStanza = builder.mDefaultStanza; mCerts = Collections.unmodifiableSet(builder.mCerts); mPkgMap = Collections.unmodifiableMap(builder.mPkgMap); } @@ -545,15 +482,6 @@ final class Policy { } /** - * Return whether this policy object represents a default stanza. - * - * @return A boolean indicating if this object represents a default policy stanza. - */ - public boolean isDefaultStanza() { - return mDefaultStanza; - } - - /** * Return whether this policy object contains package name mapping refinements. * * @return A boolean indicating if this object has inner package name mappings. @@ -584,10 +512,6 @@ final class Policy { @Override public String toString() { StringBuilder sb = new StringBuilder(); - if (mDefaultStanza) { - sb.append("defaultStanza=true "); - } - for (Signature cert : mCerts) { sb.append("cert=" + cert.toCharsString().substring(0, 11) + "... "); } @@ -609,22 +533,15 @@ final class Policy { * is determined using the following steps: * </p> * <ul> - * <li> If this Policy instance is defined as a default stanza: - * <ul><li>Return the global seinfo value</li></ul> + * <li> All certs used to sign the apk and all certs stored with this policy + * instance are tested for set equality. If this fails then null is returned. + * </li> + * <li> If all certs match then an appropriate inner package stanza is + * searched based on package name alone. If matched, the stored seinfo + * value for that mapping is returned. * </li> - * <li> If this Policy instance is defined as a signer stanza: - * <ul> - * <li> All certs used to sign the apk and all certs stored with this policy - * instance are tested for set equality. If this fails then null is returned. - * </li> - * <li> If all certs match then an appropriate inner package stanza is - * searched based on package name alone. If matched, the stored seinfo - * value for that mapping is returned. - * </li> - * <li> If all certs matched and no inner package stanza matches then return - * the global seinfo value. The returned value can be null in this case. - * </li> - * </ul> + * <li> If all certs matched and no inner package stanza matches then return + * the global seinfo value. The returned value can be null in this case. * </li> * </ul> * <p> @@ -636,37 +553,34 @@ final class Policy { * A value of null can also be returned if no match occured. */ public String getMatchedSeinfo(PackageParser.Package pkg) { - if (!mDefaultStanza) { - // Check for exact signature matches across all certs. - Signature[] certs = mCerts.toArray(new Signature[0]); - if (!Signature.areExactMatch(certs, pkg.mSignatures)) { - return null; - } + // Check for exact signature matches across all certs. + Signature[] certs = mCerts.toArray(new Signature[0]); + if (!Signature.areExactMatch(certs, pkg.mSignatures)) { + return null; + } - // Check for inner package name matches given that the - // signature checks already passed. - String seinfoValue = mPkgMap.get(pkg.packageName); - if (seinfoValue != null) { - return seinfoValue; - } + // Check for inner package name matches given that the + // signature checks already passed. + String seinfoValue = mPkgMap.get(pkg.packageName); + if (seinfoValue != null) { + return seinfoValue; } - // Return the global seinfo value (even if it's null). + // Return the global seinfo value. return mSeinfo; } /** * A nested builder class to create {@link Policy} instances. A {@link Policy} * class instance represents one valid policy stanza found in a mac_permissions.xml - * file. A valid policy stanza is defined to be either a signer or default stanza - * which obeys the rules outlined in external/sepolicy/mac_permissions.xml. The - * {@link #build} method ensures a set of invariants are upheld enforcing the correct - * stanza structure before returning a valid Policy object. + * file. A valid policy stanza is defined to be a signer stanza which obeys the rules + * outlined in external/sepolicy/mac_permissions.xml. The {@link #build} method + * ensures a set of invariants are upheld enforcing the correct stanza structure + * before returning a valid Policy object. */ public static final class PolicyBuilder { private String mSeinfo; - private boolean mDefaultStanza; private final Set<Signature> mCerts; private final Map<String, String> mPkgMap; @@ -676,19 +590,6 @@ final class Policy { } /** - * Sets this stanza as a default stanza. All policy stanzas are assumed to - * be signer stanzas unless this method is explicitly called. Default stanzas - * are treated differently with respect to allowable child tags, ordering and - * when and how policy decisions are enforced. - * - * @return The reference to this PolicyBuilder. - */ - public PolicyBuilder setAsDefaultPolicy() { - mDefaultStanza = true; - return this; - } - - /** * Adds a signature to the set of certs used for validation checks. The purpose * being that all contained certs will need to be matched against all certs * contained with an apk. @@ -710,11 +611,8 @@ final class Policy { /** * Set the global seinfo tag for this policy stanza. The global seinfo tag - * represents the seinfo element that is used in one of two ways depending on - * its context. When attached to a signer tag the global seinfo represents an - * assignment when there isn't a further inner package refinement in policy. - * When used with a default tag, it represents the only allowable assignment - * value. + * when attached to a signer tag represents the assignment when there isn't a + * further inner package refinement in policy. * * @param seinfo the seinfo value given as a String. * @return The reference to this PolicyBuilder. @@ -740,9 +638,7 @@ final class Policy { /** * Create a package name to seinfo value mapping. Each mapping represents * the seinfo value that will be assigned to the described package name. - * These localized mappings allow the global seinfo to be overriden. This - * mapping provides no value when used in conjunction with a default stanza; - * enforced through the {@link #build} method. + * These localized mappings allow the global seinfo to be overriden. * * @param pkgName the android package name given to the app * @param seinfo the seinfo value that will be assigned to the passed pkgName @@ -799,51 +695,25 @@ final class Policy { * about the expected structure of a policy stanza. * Those invariants are: * </p> - * <ul> - * <li> If a default stanza - * <ul> - * <li> an attached global seinfo tag must be present </li> - * <li> no signatures and no package names can be present </li> - * </ul> - * </li> - * <li> If a signer stanza - * <ul> - * <li> at least one cert must be found </li> - * <li> either a global seinfo value is present OR at least one - * inner package mapping must be present BUT not both. </li> - * </ul> - * </li> - * </ul> - * + * <ul> + * <li> at least one cert must be found </li> + * <li> either a global seinfo value is present OR at least one + * inner package mapping must be present BUT not both. </li> + * </ul> * @return an instance of {@link Policy} with the options set from this builder * @throws IllegalStateException if an invariant is violated. */ public Policy build() { Policy p = new Policy(this); - if (p.mDefaultStanza) { - if (p.mSeinfo == null) { - String err = "Missing global seinfo tag with default stanza."; - throw new IllegalStateException(err); - } - if (p.mCerts.size() != 0) { - String err = "Certs not allowed with default stanza."; - throw new IllegalStateException(err); - } - if (!p.mPkgMap.isEmpty()) { - String err = "Inner package mappings not allowed with default stanza."; - throw new IllegalStateException(err); - } - } else { - if (p.mCerts.size() == 0) { - String err = "Missing certs with signer tag. Expecting at least one."; - throw new IllegalStateException(err); - } - if (!(p.mSeinfo == null ^ p.mPkgMap.isEmpty())) { - String err = "Only seinfo tag XOR package tags are allowed within " + - "a signer stanza."; - throw new IllegalStateException(err); - } + if (p.mCerts.isEmpty()) { + String err = "Missing certs with signer tag. Expecting at least one."; + throw new IllegalStateException(err); + } + if (!(p.mSeinfo == null ^ p.mPkgMap.isEmpty())) { + String err = "Only seinfo tag XOR package tags are allowed within " + + "a signer stanza."; + throw new IllegalStateException(err); } return p; @@ -858,7 +728,6 @@ final class Policy { * <ul> * <li> signer stanzas with inner package mappings </li> * <li> signer stanzas with global seinfo tags </li> - * <li> default stanza </li> * </ul> * This comparison also checks for duplicate entries on the input selectors. Any * found duplicates will be flagged and can be checked with {@link #foundDuplicate}. @@ -875,11 +744,6 @@ final class PolicyComparator implements Comparator<Policy> { @Override public int compare(Policy p1, Policy p2) { - // Give precedence to signature stanzas over default stanzas - if (p1.isDefaultStanza() != p2.isDefaultStanza()) { - return p1.isDefaultStanza() ? 1 : -1; - } - // Give precedence to stanzas with inner package mappings if (p1.hasInnerPackages() != p2.hasInnerPackages()) { return p1.hasInnerPackages() ? -1 : 1; @@ -887,7 +751,7 @@ final class PolicyComparator implements Comparator<Policy> { // Check for duplicate entries if (p1.getSignatures().equals(p2.getSignatures())) { - // Checks if default stanza or a signer w/o inner package names + // Checks if signer w/o inner package names if (p1.hasGlobalSeinfo()) { duplicateFound = true; Slog.e(SELinuxMMAC.TAG, "Duplicate policy entry: " + p1.toString()); |