diff options
16 files changed, 632 insertions, 11 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index d19db32..4f6971b 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -32,7 +32,7 @@ dir_rec_t android_app_lib_dir; dir_rec_t android_media_dir; dir_rec_array_t android_system_dirs; -int install(const char *pkgname, uid_t uid, gid_t gid) +int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) { char pkgdir[PKG_PATH_MAX]; char libsymlink[PKG_PATH_MAX]; @@ -96,7 +96,7 @@ int install(const char *pkgname, uid_t uid, gid_t gid) } #ifdef HAVE_SELINUX - if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) { + if (selinux_android_setfilecon2(pkgdir, pkgname, seinfo, uid) < 0) { ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno)); unlink(libsymlink); unlink(pkgdir); diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c index 17a1a1f..73249cc 100644 --- a/cmds/installd/installd.c +++ b/cmds/installd/installd.c @@ -31,7 +31,7 @@ static int do_ping(char **arg, char reply[REPLY_MAX]) static int do_install(char **arg, char reply[REPLY_MAX]) { - return install(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */ + return install(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]); /* pkgname, uid, gid, seinfo */ } static int do_dexopt(char **arg, char reply[REPLY_MAX]) @@ -134,7 +134,7 @@ struct cmdinfo { struct cmdinfo cmds[] = { { "ping", 0, do_ping }, - { "install", 3, do_install }, + { "install", 4, do_install }, { "dexopt", 3, do_dexopt }, { "movedex", 2, do_move_dex }, { "rmdex", 1, do_rm_dex }, diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index a8461eb..5a68733 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -196,7 +196,7 @@ int ensure_media_user_dirs(userid_t userid); /* commands.c */ -int install(const char *pkgname, uid_t uid, gid_t gid); +int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo); int uninstall(const char *pkgname, uid_t persona); int renamepkg(const char *oldpkgname, const char *newpkgname); int fix_uid(const char *pkgname, uid_t uid, gid_t gid); diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index fa85145..ab32e48 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -399,6 +399,15 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public String[] resourceDirs; /** + * 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. + * + * {@hide} + */ + public String seinfo; + + /** * Paths to all shared libraries this application is linked against. This * field is only set if the {@link PackageManager#GET_SHARED_LIBRARY_FILES * PackageManager.GET_SHARED_LIBRARY_FILES} flag was used when retrieving @@ -502,6 +511,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { if (resourceDirs != null) { pw.println(prefix + "resourceDirs=" + resourceDirs); } + if (seinfo != null) { + pw.println(prefix + "seinfo=" + seinfo); + } pw.println(prefix + "dataDir=" + dataDir); if (sharedLibraryFiles != null) { pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles); @@ -569,6 +581,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { publicSourceDir = orig.publicSourceDir; nativeLibraryDir = orig.nativeLibraryDir; resourceDirs = orig.resourceDirs; + seinfo = orig.seinfo; sharedLibraryFiles = orig.sharedLibraryFiles; dataDir = orig.dataDir; uid = orig.uid; @@ -609,6 +622,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString(publicSourceDir); dest.writeString(nativeLibraryDir); dest.writeStringArray(resourceDirs); + dest.writeString(seinfo); dest.writeStringArray(sharedLibraryFiles); dest.writeString(dataDir); dest.writeInt(uid); @@ -648,6 +662,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { publicSourceDir = source.readString(); nativeLibraryDir = source.readString(); resourceDirs = source.readStringArray(); + seinfo = source.readString(); sharedLibraryFiles = source.readStringArray(); dataDir = source.readString(); uid = source.readInt(); diff --git a/core/java/android/content/pm/SELinuxMMAC.java b/core/java/android/content/pm/SELinuxMMAC.java new file mode 100644 index 0000000..2b5ecc1 --- /dev/null +++ b/core/java/android/content/pm/SELinuxMMAC.java @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageParser; +import android.content.pm.Signature; +import android.os.Environment; +import android.util.Slog; +import android.util.Xml; + +import com.android.internal.util.XmlUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +import java.util.HashMap; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +/** + * Centralized access to SELinux MMAC (middleware MAC) implementation. + * {@hide} + */ +public final class SELinuxMMAC { + + private static final String TAG = "SELinuxMMAC"; + + private static final boolean DEBUG_POLICY = false; + private static final boolean DEBUG_POLICY_INSTALL = DEBUG_POLICY || false; + + // Signature seinfo values read from policy. + private static final HashMap<Signature, String> sSigSeinfo = + new HashMap<Signature, String>(); + + // Package name seinfo values read from policy. + private static final HashMap<String, String> sPackageSeinfo = + new HashMap<String, String>(); + + // Locations of potential install policy files. + private static final File[] INSTALL_POLICY_FILE = { + new File(Environment.getDataDirectory(), "system/mac_permissions.xml"), + new File(Environment.getRootDirectory(), "etc/security/mac_permissions.xml"), + null}; + + private static void flushInstallPolicy() { + sSigSeinfo.clear(); + sPackageSeinfo.clear(); + } + + /** + * Parses an MMAC install policy from a predefined list of locations. + * @param none + * @return boolean indicating whether an install policy was correctly parsed. + */ + public static boolean readInstallPolicy() { + + return readInstallPolicy(INSTALL_POLICY_FILE); + } + + /** + * Parses an MMAC install policy given as an argument. + * @param File object representing the path of the policy. + * @return boolean indicating whether the install policy was correctly parsed. + */ + public static boolean readInstallPolicy(File policyFile) { + + return readInstallPolicy(new File[]{policyFile,null}); + } + + private static boolean readInstallPolicy(File[] policyFiles) { + + FileReader policyFile = null; + int i = 0; + while (policyFile == null && policyFiles != null && policyFiles[i] != null) { + try { + policyFile = new FileReader(policyFiles[i]); + break; + } catch (FileNotFoundException e) { + Slog.d(TAG,"Couldn't find install policy " + policyFiles[i].getPath()); + } + i++; + } + + if (policyFile == null) { + Slog.d(TAG, "No policy file found. All seinfo values will be null."); + return false; + } + + Slog.d(TAG, "Using install policy file " + policyFiles[i].getPath()); + + flushInstallPolicy(); + + try { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(policyFile); + + XmlUtils.beginDocument(parser, "policy"); + while (true) { + XmlUtils.nextElement(parser); + if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { + break; + } + + String tagName = parser.getName(); + if ("signer".equals(tagName)) { + String cert = parser.getAttributeValue(null, "signature"); + if (cert == null) { + Slog.w(TAG, "<signer> without signature at " + + parser.getPositionDescription()); + XmlUtils.skipCurrentTag(parser); + continue; + } + Signature signature; + try { + signature = new Signature(cert); + } catch (IllegalArgumentException e) { + Slog.w(TAG, "<signer> with bad signature at " + + parser.getPositionDescription(), e); + XmlUtils.skipCurrentTag(parser); + continue; + } + String seinfo = readSeinfoTag(parser); + if (seinfo != null) { + if (DEBUG_POLICY_INSTALL) + Slog.i(TAG, "<signer> tag: (" + cert + ") assigned seinfo=" + + seinfo); + + sSigSeinfo.put(signature, seinfo); + } + } else if ("default".equals(tagName)) { + String seinfo = readSeinfoTag(parser); + if (seinfo != null) { + if (DEBUG_POLICY_INSTALL) + Slog.i(TAG, "<default> tag assigned seinfo=" + seinfo); + + // The 'null' signature is the default seinfo value + sSigSeinfo.put(null, seinfo); + } + } else if ("package".equals(tagName)) { + String pkgName = parser.getAttributeValue(null, "name"); + if (pkgName == null) { + Slog.w(TAG, "<package> without name at " + + parser.getPositionDescription()); + XmlUtils.skipCurrentTag(parser); + continue; + } + String seinfo = readSeinfoTag(parser); + if (seinfo != null) { + if (DEBUG_POLICY_INSTALL) + Slog.i(TAG, "<package> tag: (" + pkgName + + ") assigned seinfo=" + seinfo); + + sPackageSeinfo.put(pkgName, seinfo); + } + } else { + XmlUtils.skipCurrentTag(parser); + continue; + } + } + } catch (XmlPullParserException e) { + Slog.w(TAG, "Got execption parsing ", e); + } catch (IOException e) { + Slog.w(TAG, "Got execption parsing ", e); + } + try { + policyFile.close(); + } catch (IOException e) { + //omit + } + return true; + } + + private static String readSeinfoTag(XmlPullParser parser) throws + IOException, XmlPullParserException { + + int type; + int outerDepth = parser.getDepth(); + String seinfo = null; + while ((type=parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG + || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG + || type == XmlPullParser.TEXT) { + continue; + } + + String tagName = parser.getName(); + if ("seinfo".equals(tagName)) { + String seinfoValue = parser.getAttributeValue(null, "value"); + if (seinfoValue != null) { + seinfo = seinfoValue; + } else { + Slog.w(TAG, "<seinfo> without value at " + + parser.getPositionDescription()); + } + } + XmlUtils.skipCurrentTag(parser); + } + return seinfo; + } + + /** + * Labels a package based on an seinfo tag from install policy. + * The label is attached to the ApplicationInfo instance of the package. + * @param PackageParser.Package object representing the package + * to labeled. + * @return String holding the value of the seinfo label that was assigned. + * Value may be null which indicates no seinfo label was assigned. + */ + public static void assignSeinfoValue(PackageParser.Package pkg) { + + // We just want one of the signatures to match. + for (Signature s : pkg.mSignatures) { + if (s == null) { + continue; + } + + if (sSigSeinfo.containsKey(s)) { + String seinfo = pkg.applicationInfo.seinfo = sSigSeinfo.get(s); + if (DEBUG_POLICY_INSTALL) + Slog.i(TAG, "package (" + pkg.packageName + + ") labeled with seinfo=" + seinfo); + + return; + } + } + + // Check for seinfo labeled by package. + if (sPackageSeinfo.containsKey(pkg.packageName)) { + String seinfo = pkg.applicationInfo.seinfo = sPackageSeinfo.get(pkg.packageName); + if (DEBUG_POLICY_INSTALL) + Slog.i(TAG, "package (" + pkg.packageName + + ") labeled with seinfo=" + seinfo); + return; + } + + // If we have a default seinfo value then great, otherwise + // we set a null object and that is what we started with. + String seinfo = pkg.applicationInfo.seinfo = sSigSeinfo.get(null); + if (DEBUG_POLICY_INSTALL) + Slog.i(TAG, "package (" + pkg.packageName + + ") labeled with seinfo=" + (seinfo == null ? "null" : seinfo)); + } +} diff --git a/core/tests/coretests/apks/mmac_install_platform/Android.mk b/core/tests/coretests/apks/mmac_install_platform/Android.mk new file mode 100644 index 0000000..bf150d3 --- /dev/null +++ b/core/tests/coretests/apks/mmac_install_platform/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PACKAGE_NAME := signed_platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_CERTIFICATE := platform + +include $(FrameworkCoreTests_BUILD_PACKAGE) diff --git a/core/tests/coretests/apks/mmac_install_platform/AndroidManifest.xml b/core/tests/coretests/apks/mmac_install_platform/AndroidManifest.xml new file mode 100644 index 0000000..fdb6894 --- /dev/null +++ b/core/tests/coretests/apks/mmac_install_platform/AndroidManifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<manifest + xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.coretests.mmac_install_platform"> + + <application android:hasCode="false"> + </application> + + +</manifest> diff --git a/core/tests/coretests/apks/mmac_install_platform/src/com/android/frameworks/coretests/DoNothing.java b/core/tests/coretests/apks/mmac_install_platform/src/com/android/frameworks/coretests/DoNothing.java new file mode 100644 index 0000000..51f8f19 --- /dev/null +++ b/core/tests/coretests/apks/mmac_install_platform/src/com/android/frameworks/coretests/DoNothing.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.frameworks.coretests; + +public class DoNothing { + +}
\ No newline at end of file diff --git a/core/tests/coretests/res/raw/mac_permissions_default.xml b/core/tests/coretests/res/raw/mac_permissions_default.xml new file mode 100644 index 0000000..3e17a8d --- /dev/null +++ b/core/tests/coretests/res/raw/mac_permissions_default.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<policy> + + <!-- shared dev key in AOSP --> + <signer signature="308204a830820390a003020102020900f2a73396bd38767a300d06092a864886f70d0101040500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3038303732333231353735395a170d3335313230393231353735395a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100c8c2dbfd094a2df45c3ff1a32ed21805ec72fc58d017971bd0f6b52c262d70819d191967e158dfd3a2c7f1b3e0e80ce545d79d2848220211eb86f0fd8312d37b420c113750cc94618ae872f4886463bdc4627caa0c0483c86493e3515571170338bfdcc4cd6addd1c0a2f35f5cf24ed3e4043a3e58e2b05e664ccde12bcb67735fd6df1249c369e62542bc0a4729e53917f5c38ffa52d17b73c9c73798ddb18ed481590875547e66bfc5daca4c25a6eb960ed96923709da302ba646cb496b325e86c5c8b2e7a3377b2bbe4c7cf33254291163f689152ac088550c83c508f4bf5adf0aed5a2dca0583f9ab0ad17650db7eea4b23fdb45885547d0feab72183889020103a381fc3081f9301d0603551d0e04160414cb4c7e2cdbb3f0ada98dab79968d172e9dbb1ed13081c90603551d230481c13081be8014cb4c7e2cdbb3f0ada98dab79968d172e9dbb1ed1a1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900f2a73396bd38767a300c0603551d13040530030101ff300d06092a864886f70d0101040500038201010040a8d096997959e917a36c44246b6bac2bae05437ecd89794118f7834720352d1c6f8a39b0869942f4da65981faa2951d33971129ec1921d795671c527d6e249f252829faf5b591310311e2de096500d568ad4114a656dc34a8c6f610453afc1ea7992dba4aa7b3f8543a6e35c0728de77fe97eeac83771fd0ec90f8e4449434ee0b6045783e70c7a2e460249260e003cf7608dc352a4c9ef706def4b26050e978ae2fffd7a3323787014915eb3cc874fcc7a9ae930877c5c8c7d1c2e2a8ee863c89180d1855cedba400e7ba43cccaa7243d397e7c0e8e8e4d7d4f92b6bbead49c0cf018069eddca2e7e2fb4668d89dbbd7950d0cd254180fa1eaafc2a556f84" > + <seinfo value="shared" /> + </signer> + + <default> + <seinfo value="default" /> + </default> + +</policy> diff --git a/core/tests/coretests/res/raw/mac_permissions_no_match.xml b/core/tests/coretests/res/raw/mac_permissions_no_match.xml new file mode 100644 index 0000000..4f8621a --- /dev/null +++ b/core/tests/coretests/res/raw/mac_permissions_no_match.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<policy> + + <!-- shared dev key in AOSP --> + <signer signature="308204a830820390a003020102020900f2a73396bd38767a300d06092a864886f70d0101040500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3038303732333231353735395a170d3335313230393231353735395a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100c8c2dbfd094a2df45c3ff1a32ed21805ec72fc58d017971bd0f6b52c262d70819d191967e158dfd3a2c7f1b3e0e80ce545d79d2848220211eb86f0fd8312d37b420c113750cc94618ae872f4886463bdc4627caa0c0483c86493e3515571170338bfdcc4cd6addd1c0a2f35f5cf24ed3e4043a3e58e2b05e664ccde12bcb67735fd6df1249c369e62542bc0a4729e53917f5c38ffa52d17b73c9c73798ddb18ed481590875547e66bfc5daca4c25a6eb960ed96923709da302ba646cb496b325e86c5c8b2e7a3377b2bbe4c7cf33254291163f689152ac088550c83c508f4bf5adf0aed5a2dca0583f9ab0ad17650db7eea4b23fdb45885547d0feab72183889020103a381fc3081f9301d0603551d0e04160414cb4c7e2cdbb3f0ada98dab79968d172e9dbb1ed13081c90603551d230481c13081be8014cb4c7e2cdbb3f0ada98dab79968d172e9dbb1ed1a1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900f2a73396bd38767a300c0603551d13040530030101ff300d06092a864886f70d0101040500038201010040a8d096997959e917a36c44246b6bac2bae05437ecd89794118f7834720352d1c6f8a39b0869942f4da65981faa2951d33971129ec1921d795671c527d6e249f252829faf5b591310311e2de096500d568ad4114a656dc34a8c6f610453afc1ea7992dba4aa7b3f8543a6e35c0728de77fe97eeac83771fd0ec90f8e4449434ee0b6045783e70c7a2e460249260e003cf7608dc352a4c9ef706def4b26050e978ae2fffd7a3323787014915eb3cc874fcc7a9ae930877c5c8c7d1c2e2a8ee863c89180d1855cedba400e7ba43cccaa7243d397e7c0e8e8e4d7d4f92b6bbead49c0cf018069eddca2e7e2fb4668d89dbbd7950d0cd254180fa1eaafc2a556f84" > + <seinfo value="shared" /> + </signer> + + <package name="bad.package.name" > + <seinfo value="per-package" /> + </package> + + <!-- no default value --> + +</policy> diff --git a/core/tests/coretests/res/raw/mac_permissions_package_name.xml b/core/tests/coretests/res/raw/mac_permissions_package_name.xml new file mode 100644 index 0000000..bdb081f --- /dev/null +++ b/core/tests/coretests/res/raw/mac_permissions_package_name.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<policy> + + <!-- shared dev key in AOSP --> + <signer signature="308204a830820390a003020102020900f2a73396bd38767a300d06092a864886f70d0101040500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3038303732333231353735395a170d3335313230393231353735395a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100c8c2dbfd094a2df45c3ff1a32ed21805ec72fc58d017971bd0f6b52c262d70819d191967e158dfd3a2c7f1b3e0e80ce545d79d2848220211eb86f0fd8312d37b420c113750cc94618ae872f4886463bdc4627caa0c0483c86493e3515571170338bfdcc4cd6addd1c0a2f35f5cf24ed3e4043a3e58e2b05e664ccde12bcb67735fd6df1249c369e62542bc0a4729e53917f5c38ffa52d17b73c9c73798ddb18ed481590875547e66bfc5daca4c25a6eb960ed96923709da302ba646cb496b325e86c5c8b2e7a3377b2bbe4c7cf33254291163f689152ac088550c83c508f4bf5adf0aed5a2dca0583f9ab0ad17650db7eea4b23fdb45885547d0feab72183889020103a381fc3081f9301d0603551d0e04160414cb4c7e2cdbb3f0ada98dab79968d172e9dbb1ed13081c90603551d230481c13081be8014cb4c7e2cdbb3f0ada98dab79968d172e9dbb1ed1a1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900f2a73396bd38767a300c0603551d13040530030101ff300d06092a864886f70d0101040500038201010040a8d096997959e917a36c44246b6bac2bae05437ecd89794118f7834720352d1c6f8a39b0869942f4da65981faa2951d33971129ec1921d795671c527d6e249f252829faf5b591310311e2de096500d568ad4114a656dc34a8c6f610453afc1ea7992dba4aa7b3f8543a6e35c0728de77fe97eeac83771fd0ec90f8e4449434ee0b6045783e70c7a2e460249260e003cf7608dc352a4c9ef706def4b26050e978ae2fffd7a3323787014915eb3cc874fcc7a9ae930877c5c8c7d1c2e2a8ee863c89180d1855cedba400e7ba43cccaa7243d397e7c0e8e8e4d7d4f92b6bbead49c0cf018069eddca2e7e2fb4668d89dbbd7950d0cd254180fa1eaafc2a556f84" > + <seinfo value="shared" /> + </signer> + + <package name="com.android.frameworks.coretests.mmac_install_platform" > + <seinfo value="per-package" /> + </package> + + <default> + <seinfo value="default" /> + </default> + +</policy> diff --git a/core/tests/coretests/res/raw/mac_permissions_signature.xml b/core/tests/coretests/res/raw/mac_permissions_signature.xml new file mode 100644 index 0000000..78050fb --- /dev/null +++ b/core/tests/coretests/res/raw/mac_permissions_signature.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<policy> + + <!-- Platform dev key with AOSP --> + <signer signature="308204a830820390a003020102020900b3998086d056cffa300d06092a864886f70d0101040500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3038303431353232343035305a170d3335303930313232343035305a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d003082010802820101009c780592ac0d5d381cdeaa65ecc8a6006e36480c6d7207b12011be50863aabe2b55d009adf7146d6f2202280c7cd4d7bdb26243b8a806c26b34b137523a49268224904dc01493e7c0acf1a05c874f69b037b60309d9074d24280e16bad2a8734361951eaf72a482d09b204b1875e12ac98c1aa773d6800b9eafde56d58bed8e8da16f9a360099c37a834a6dfedb7b6b44a049e07a269fccf2c5496f2cf36d64df90a3b8d8f34a3baab4cf53371ab27719b3ba58754ad0c53fc14e1db45d51e234fbbe93c9ba4edf9ce54261350ec535607bf69a2ff4aa07db5f7ea200d09a6c1b49e21402f89ed1190893aab5a9180f152e82f85a45753cf5fc19071c5eec827020103a381fc3081f9301d0603551d0e041604144fe4a0b3dd9cba29f71d7287c4e7c38f2086c2993081c90603551d230481c13081be80144fe4a0b3dd9cba29f71d7287c4e7c38f2086c299a1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900b3998086d056cffa300c0603551d13040530030101ff300d06092a864886f70d01010405000382010100572551b8d93a1f73de0f6d469f86dad6701400293c88a0cd7cd778b73dafcc197fab76e6212e56c1c761cfc42fd733de52c50ae08814cefc0a3b5a1a4346054d829f1d82b42b2048bf88b5d14929ef85f60edd12d72d55657e22e3e85d04c831d613d19938bb8982247fa321256ba12d1d6a8f92ea1db1c373317ba0c037f0d1aff645aef224979fba6e7a14bc025c71b98138cef3ddfc059617cf24845cf7b40d6382f7275ed738495ab6e5931b9421765c491b72fb68e080dbdb58c2029d347c8b328ce43ef6a8b15533edfbe989bd6a48dd4b202eda94c6ab8dd5b8399203daae2ed446232e4fe9bd961394c6300e5138e3cfd285e6e4e483538cb8b1b357" > + <seinfo value="platform" /> + </signer> + + <!-- Media dev key in AOSP --> + <signer signature="308204a830820390a003020102020900f2b98e6123572c4e300d06092a864886f70d0101040500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3038303431353233343035375a170d3335303930313233343035375a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100ae250c5a16ef97fc2869ac651b3217cc36ba0e86964168d58a049f40ce85867123a3ffb4f6d949c33cf2da3a05c23eacaa57d803889b1759bcf59e7c6f21890ae25085b7ed56aa626c0989ef9ccd36362ca0e8d1b9603fd4d8328767926ccc090c68b775ae7ff30934cc369ef2855a2667df0c667fd0c7cf5d8eba655806737303bb624726eabaedfb72f07ed7a76ab3cb9a381c4b7dcd809b140d891f00213be401f58d6a06a61eadc3a9c2f1c6567285b09ae09342a66fa421eaf93adf7573a028c331d70601ab3af7cc84033ece7c772a3a5b86b0dbe9d777c3a48aa9801edcee2781589f44d9e4113979600576a99410ba81091259dad98c6c68ff784b8f020103a381fc3081f9301d0603551d0e04160414ca293caa8bc0ed3e542eef4205a2bff2b57e4d753081c90603551d230481c13081be8014ca293caa8bc0ed3e542eef4205a2bff2b57e4d75a1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900f2b98e6123572c4e300c0603551d13040530030101ff300d06092a864886f70d0101040500038201010084de9516d5e4a87217a73da8487048f53373a5f733f390d61bdf3cc9e5251625bfcaa7c3159cae275d172a9ae1e876d5458127ac542f68290dd510c0029d8f51e0ee156b7b7b5acdb394241b8ec78b74e5c42c5cafae156caf5bd199a23a27524da072debbe378464a533630b0e4d0ffb7e08ecb701fadb6379c74467f6e00c6ed888595380792038756007872c8e3007af423a57a2cab3a282869b64c4b7bd5fc187d0a7e2415965d5aae4e07a6df751b4a75e9793c918a612b81cd0b628aee0168dc44e47b10d3593260849d6adf6d727dc24444c221d3f9ecc368cad07999f2b8105bc1f20d38d41066cc1411c257a96ea4349f5746565507e4e8020a1a81" > + <seinfo value="media" /> + </signer> + + <!-- shared dev key in AOSP --> + <signer signature="308204a830820390a003020102020900f2a73396bd38767a300d06092a864886f70d0101040500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3038303732333231353735395a170d3335313230393231353735395a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100c8c2dbfd094a2df45c3ff1a32ed21805ec72fc58d017971bd0f6b52c262d70819d191967e158dfd3a2c7f1b3e0e80ce545d79d2848220211eb86f0fd8312d37b420c113750cc94618ae872f4886463bdc4627caa0c0483c86493e3515571170338bfdcc4cd6addd1c0a2f35f5cf24ed3e4043a3e58e2b05e664ccde12bcb67735fd6df1249c369e62542bc0a4729e53917f5c38ffa52d17b73c9c73798ddb18ed481590875547e66bfc5daca4c25a6eb960ed96923709da302ba646cb496b325e86c5c8b2e7a3377b2bbe4c7cf33254291163f689152ac088550c83c508f4bf5adf0aed5a2dca0583f9ab0ad17650db7eea4b23fdb45885547d0feab72183889020103a381fc3081f9301d0603551d0e04160414cb4c7e2cdbb3f0ada98dab79968d172e9dbb1ed13081c90603551d230481c13081be8014cb4c7e2cdbb3f0ada98dab79968d172e9dbb1ed1a1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900f2a73396bd38767a300c0603551d13040530030101ff300d06092a864886f70d0101040500038201010040a8d096997959e917a36c44246b6bac2bae05437ecd89794118f7834720352d1c6f8a39b0869942f4da65981faa2951d33971129ec1921d795671c527d6e249f252829faf5b591310311e2de096500d568ad4114a656dc34a8c6f610453afc1ea7992dba4aa7b3f8543a6e35c0728de77fe97eeac83771fd0ec90f8e4449434ee0b6045783e70c7a2e460249260e003cf7608dc352a4c9ef706def4b26050e978ae2fffd7a3323787014915eb3cc874fcc7a9ae930877c5c8c7d1c2e2a8ee863c89180d1855cedba400e7ba43cccaa7243d397e7c0e8e8e4d7d4f92b6bbead49c0cf018069eddca2e7e2fb4668d89dbbd7950d0cd254180fa1eaafc2a556f84" > + <seinfo value="shared" /> + </signer> + + <!-- release dev key in AOSP --> + <signer signature="308204a830820390a003020102020900936eacbe07f201df300d06092a864886f70d0101050500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3038303232393031333334365a170d3335303731373031333334365a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100d6931904dec60b24b1edc762e0d9d8253e3ecd6ceb1de2ff068ca8e8bca8cd6bd3786ea70aa76ce60ebb0f993559ffd93e77a943e7e83d4b64b8e4fea2d3e656f1e267a81bbfb230b578c20443be4c7218b846f5211586f038a14e89c2be387f8ebecf8fcac3da1ee330c9ea93d0a7c3dc4af350220d50080732e0809717ee6a053359e6a694ec2cb3f284a0a466c87a94d83b31093a67372e2f6412c06e6d42f15818dffe0381cc0cd444da6cddc3b82458194801b32564134fbfde98c9287748dbf5676a540d8154c8bbca07b9e247553311c46b9af76fdeeccc8e69e7c8a2d08e782620943f99727d3c04fe72991d99df9bae38a0b2177fa31d5b6afee91f020103a381fc3081f9301d0603551d0e04160414485900563d272c46ae118605a47419ac09ca8c113081c90603551d230481c13081be8014485900563d272c46ae118605a47419ac09ca8c11a1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900936eacbe07f201df300c0603551d13040530030101ff300d06092a864886f70d010105050003820101007aaf968ceb50c441055118d0daabaf015b8a765a27a715a2c2b44f221415ffdace03095abfa42df70708726c2069e5c36eddae0400be29452c084bc27eb6a17eac9dbe182c204eb15311f455d824b656dbe4dc2240912d7586fe88951d01a8feb5ae5a4260535df83431052422468c36e22c2a5ef994d61dd7306ae4c9f6951ba3c12f1d1914ddc61f1a62da2df827f603fea5603b2c540dbd7c019c36bab29a4271c117df523cdbc5f3817a49e0efa60cbd7f74177e7a4f193d43f4220772666e4c4d83e1bd5a86087cf34f2dec21e245ca6c2bb016e683638050d2c430eea7c26a1c49d3760a58ab7f1a82cc938b4831384324bd0401fa12163a50570e684d" > + <seinfo value="release" /> + </signer> + + <default> + <seinfo value="default" /> + </default> + +</policy> diff --git a/core/tests/coretests/src/android/content/pm/SELinuxMMACTests.java b/core/tests/coretests/src/android/content/pm/SELinuxMMACTests.java new file mode 100644 index 0000000..f086113 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/SELinuxMMACTests.java @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import android.content.pm.PackageManagerTests; +import android.content.pm.SELinuxMMAC; +import android.content.res.Resources; +import android.content.res.Resources.NotFoundException; +import android.net.Uri; +import android.os.FileUtils; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.LargeTest; +import android.util.DisplayMetrics; +import android.util.Log; + +import com.android.frameworks.coretests.R; + +import java.io.File; +import java.io.FileReader; +import java.io.InputStream; + +public class SELinuxMMACTests extends AndroidTestCase { + + private static final String TAG = "SELinuxMMACTests"; + + private static File MAC_INSTALL_TMP; + private static File APK_INSTALL_TMP; + private static final String MAC_INSTALL_TMP_NAME = "mac_install_policy"; + private static final String APK_INSTALL_TMP_NAME = "install.apk"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + // Need a tmp file to hold the various mmac install files. + File filesDir = mContext.getFilesDir(); + MAC_INSTALL_TMP = new File(filesDir, MAC_INSTALL_TMP_NAME); + assertNotNull(MAC_INSTALL_TMP); + + // Need a tmp file to hold the apk + APK_INSTALL_TMP = new File(filesDir, APK_INSTALL_TMP_NAME); + assertNotNull(APK_INSTALL_TMP); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + // Just in case still around + MAC_INSTALL_TMP.delete(); + APK_INSTALL_TMP.delete(); + } + + void failStr(String errMsg) { + Log.w(TAG, "errMsg="+errMsg); + fail(errMsg); + } + + void failStr(Exception e) { + failStr(e.getMessage()); + } + + private PackageParser.Package parsePackage(Uri packageURI) { + final String archiveFilePath = packageURI.getPath(); + PackageParser packageParser = new PackageParser(archiveFilePath); + File sourceFile = new File(archiveFilePath); + DisplayMetrics metrics = new DisplayMetrics(); + metrics.setToDefaults(); + PackageParser.Package pkg = packageParser.parsePackage(sourceFile, + archiveFilePath, + metrics, 0); + assertNotNull(pkg); + assertTrue(packageParser.collectCertificates(pkg,0)); + packageParser = null; + return pkg; + } + + Uri getResourceURI(int fileResId, File outFile) { + Resources res = mContext.getResources(); + InputStream is = null; + try { + is = res.openRawResource(fileResId); + } catch (NotFoundException e) { + failStr("Failed to load resource with id: " + fileResId); + } + assertNotNull(is); + FileUtils.setPermissions(outFile.getPath(), + FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, + -1, -1); + assertTrue(FileUtils.copyToFile(is, outFile)); + FileUtils.setPermissions(outFile.getPath(), + FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, + -1, -1); + return Uri.fromFile(outFile); + } + + /** + * Takes the policy xml file as a resource, the apk as a resource, + * and the expected seinfo string. + * We mock a package install here by calling parsePackage. + */ + void checkSeinfoWithPolicy(int policyRes, int apkRes, + String expectedSeinfo) { + // grab policy file + Uri policyURI = getResourceURI(policyRes, MAC_INSTALL_TMP); + assertNotNull(policyURI); + // parse the policy file + boolean ret = SELinuxMMAC.readInstallPolicy(new File(policyURI.getPath())); + assertTrue(ret); + // grab the apk + Uri apkURI = getResourceURI(apkRes, APK_INSTALL_TMP); + assertNotNull(apkURI); + // "install" the apk + PackageParser.Package pkg = parsePackage(apkURI); + assertNotNull(pkg); + assertNotNull(pkg.packageName); + // check for correct seinfo label + SELinuxMMAC.assignSeinfoValue(pkg); + String seinfo = pkg.applicationInfo.seinfo; + if (seinfo == null) + seinfo = "null"; + assertEquals(expectedSeinfo, seinfo); + + // delete policy and apk + MAC_INSTALL_TMP.delete(); + APK_INSTALL_TMP.delete(); + } + + /* + * Requested policy file doesn't exist. + */ + @LargeTest + public void testPOLICY_BADPATH() { + boolean ret = SELinuxMMAC.readInstallPolicy(new File("/d/o/e/s/n/t/e/x/i/s/t")); + assertFalse(ret); + } + + /* + * Requested policy file is null object. + */ + @LargeTest + public void testPOLICY_NULL() { + boolean ret = SELinuxMMAC.readInstallPolicy(null); + assertFalse(ret); + } + + /* + * Parse an apk that should be labeled with signature stanza. + */ + @LargeTest + public void testSIGNATURE_LABEL() { + checkSeinfoWithPolicy(R.raw.mac_permissions_signature, R.raw.signed_platform, + "platform"); + } + + /* + * Parse an apk that should be labeled with default stanza. + */ + @LargeTest + public void testDEFAULT_LABEL() { + checkSeinfoWithPolicy(R.raw.mac_permissions_default, R.raw.signed_platform, + "default"); + } + + /* + * Parse an apk that should be labeled with package stanza. + */ + @LargeTest + public void testPACKAGENAME_LABEL() { + checkSeinfoWithPolicy(R.raw.mac_permissions_package_name, R.raw.signed_platform, + "per-package"); + } + + /* + * Parse an apk that should not be labeled. No matching entry in policy. + */ + @LargeTest + public void testNO_MATCHING_POLICY() { + checkSeinfoWithPolicy(R.raw.mac_permissions_no_match, R.raw.signed_platform, + "null"); + } +} diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index d7f9eb4..4c83116 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -2217,7 +2217,7 @@ public final class ActivityManagerService extends ActivityManagerNative // the PID of the new process, or else throw a RuntimeException. Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", app.processName, uid, uid, gids, debugFlags, mountExternal, - app.info.targetSdkVersion, null, null); + app.info.targetSdkVersion, app.info.seinfo, null); BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); synchronized (bs) { diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java index 71a6a01..ddb0d0b 100644 --- a/services/java/com/android/server/pm/Installer.java +++ b/services/java/com/android/server/pm/Installer.java @@ -188,7 +188,7 @@ public final class Installer { } } - public int install(String name, int uid, int gid) { + public int install(String name, int uid, int gid, String seinfo) { StringBuilder builder = new StringBuilder("install"); builder.append(' '); builder.append(name); @@ -196,6 +196,8 @@ public final class Installer { builder.append(uid); builder.append(' '); builder.append(gid); + builder.append(' '); + builder.append(seinfo != null ? seinfo : "!"); return execute(builder.toString()); } diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index f134854..0bf7be9 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -85,6 +85,7 @@ import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; +import android.content.pm.SELinuxMMAC; import android.content.pm.ServiceInfo; import android.content.pm.Signature; import android.content.pm.ManifestDigest; @@ -360,6 +361,9 @@ public class PackageManagerService extends IPackageManager.Stub { final HashMap<String, FeatureInfo> mAvailableFeatures = new HashMap<String, FeatureInfo>(); + // If mac_permissions.xml was found for seinfo labeling. + boolean mFoundPolicyFile; + // All available activities, for your resolving pleasure. final ActivityIntentResolver mActivities = new ActivityIntentResolver(); @@ -1158,6 +1162,13 @@ public class PackageManagerService extends IPackageManager.Stub { } } + // Find potential SELinux install policy + long startPolicyTime = SystemClock.uptimeMillis(); + mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); + Slog.i(TAG, "Time to scan SELinux install policy: " + + ((SystemClock.uptimeMillis()-startPolicyTime)/1000f) + + " seconds"); + // Find base frameworks (resource packages without code). mFrameworkInstallObserver = new AppDirObserver( mFrameworkDir.getPath(), OBSERVER_EVENTS, true); @@ -3597,9 +3608,9 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private int createDataDirsLI(String packageName, int uid) { + private int createDataDirsLI(String packageName, int uid, String seinfo) { int[] users = sUserManager.getUserIds(); - int res = mInstaller.install(packageName, uid, uid); + int res = mInstaller.install(packageName, uid, uid, seinfo); if (res < 0) { return res; } @@ -3646,6 +3657,10 @@ public class PackageManagerService extends IPackageManager.Stub { } mScanningPath = scanFile; + if (mFoundPolicyFile) { + SELinuxMMAC.assignSeinfoValue(pkg); + } + if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; } @@ -4014,7 +4029,8 @@ public class PackageManagerService extends IPackageManager.Stub { recovered = true; // And now re-install the app. - ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid); + ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, + pkg.applicationInfo.seinfo); if (ret == -1) { // Ack should not happen! msg = prefix + pkg.packageName @@ -4060,7 +4076,8 @@ public class PackageManagerService extends IPackageManager.Stub { Log.v(TAG, "Want this data dir: " + dataPath); } //invoke installer to do the actual installation - int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid); + int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, + pkg.applicationInfo.seinfo); if (ret < 0) { // Error from installer mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; |
