Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cccd63e authored by Nick Kralevich's avatar Nick Kralevich Committed by Android Git Automerger
Browse files

am 532536f1: am daa0ee13: am 4f8785f2: Merge "SELinuxMMAC additions to perform...

am 532536f1: am daa0ee13: am 4f8785f2: Merge "SELinuxMMAC additions to perform policy versioning checks."

* commit '532536f1':
  SELinuxMMAC additions to perform policy versioning checks.
parents 50ac763f 532536f1
Loading
Loading
Loading
Loading
+60 −59
Original line number Diff line number Diff line
@@ -52,25 +52,49 @@ public final class SELinuxMMAC {
    private static final boolean DEBUG_POLICY_INSTALL = DEBUG_POLICY || false;

    // Signature seinfo values read from policy.
    private static HashMap<Signature, Policy> sSigSeinfo =
        new HashMap<Signature, Policy>();
    private static HashMap<Signature, Policy> sSigSeinfo = new HashMap<Signature, Policy>();

    // Default seinfo read from policy.
    private static String sDefaultSeinfo = null;

    // Locations of potential install policy files.
    private static final File[] INSTALL_POLICY_FILE = {
        new File(Environment.getDataDirectory(), "security/mac_permissions.xml"),
        new File(Environment.getRootDirectory(), "etc/security/mac_permissions.xml"),
        null};
    // Data policy override version file.
    private static final String DATA_VERSION_FILE =
            Environment.getDataDirectory() + "/security/current/selinux_version";

    // Location of seapp_contexts policy file.
    private static final String SEAPP_CONTEXTS_FILE = "/seapp_contexts";
    // Base policy version file.
    private static final String BASE_VERSION_FILE = "/selinux_version";

    // Whether override security policies should be loaded.
    private static final boolean USE_OVERRIDE_POLICY = useOverridePolicy();

    // Data override mac_permissions.xml policy file.
    private static final String DATA_MAC_PERMISSIONS =
            Environment.getDataDirectory() + "/security/current/mac_permissions.xml";

    // Base mac_permissions.xml policy file.
    private static final String BASE_MAC_PERMISSIONS =
            Environment.getRootDirectory() + "/etc/security/mac_permissions.xml";

    // Determine which mac_permissions.xml file to use.
    private static final String MAC_PERMISSIONS = USE_OVERRIDE_POLICY ?
            DATA_MAC_PERMISSIONS : BASE_MAC_PERMISSIONS;

    // Data override seapp_contexts policy file.
    private static final String DATA_SEAPP_CONTEXTS =
            Environment.getDataDirectory() + "/security/current/seapp_contexts";

    // Base seapp_contexts policy file.
    private static final String BASE_SEAPP_CONTEXTS = "/seapp_contexts";

    // Determine which seapp_contexts file to use.
    private static final String SEAPP_CONTEXTS = USE_OVERRIDE_POLICY ?
            DATA_SEAPP_CONTEXTS : BASE_SEAPP_CONTEXTS;

    // Stores the hash of the last used seapp_contexts file.
    private static final String SEAPP_HASH_FILE =
            Environment.getDataDirectory().toString() + "/system/seapp_hash";


    // Signature policy stanzas
    static class Policy {
        private String seinfo;
@@ -112,51 +136,17 @@ public final class SELinuxMMAC {
        sDefaultSeinfo = null;
    }

    /**
     * Parses an MMAC install policy from a predefined list of locations.
     * @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 policyFile 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) {
        // Temp structures to hold the rules while we parse the xml file.
        // We add all the rules together once we know there's no structural problems.
        HashMap<Signature, Policy> sigSeinfo = new HashMap<Signature, Policy>();
        String defaultSeinfo = null;

        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;
        }
            policyFile = new FileReader(MAC_PERMISSIONS);
            Slog.d(TAG, "Using policy file " + MAC_PERMISSIONS);

        Slog.d(TAG, "Using install policy file " + policyFiles[i].getPath());

        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(policyFile);

@@ -199,20 +189,14 @@ public final class SELinuxMMAC {
                    XmlUtils.skipCurrentTag(parser);
                }
            }
        } catch (XmlPullParserException e) {
            // An error outside of a stanza means a structural problem
            // with the xml file. So ignore it.
            Slog.w(TAG, "Got exception parsing ", e);
        } catch (XmlPullParserException xpe) {
            Slog.w(TAG, "Got exception parsing " + MAC_PERMISSIONS, xpe);
            return false;
        } catch (IOException e) {
            Slog.w(TAG, "Got exception parsing ", e);
        } catch (IOException ioe) {
            Slog.w(TAG, "Got exception parsing " + MAC_PERMISSIONS, ioe);
            return false;
        } finally {
            try {
                policyFile.close();
            } catch (IOException e) {
                //omit
            }
            IoUtils.closeQuietly(policyFile);
        }

        flushInstallPolicy();
@@ -412,7 +396,7 @@ public final class SELinuxMMAC {
        // Any error with the seapp_contexts file should be fatal
        byte[] currentHash = null;
        try {
            currentHash = returnHash(SEAPP_CONTEXTS_FILE);
            currentHash = returnHash(SEAPP_CONTEXTS);
        } catch (IOException ioe) {
            Slog.e(TAG, "Error with hashing seapp_contexts.", ioe);
            return false;
@@ -434,7 +418,7 @@ public final class SELinuxMMAC {
     */
    public static void setRestoreconDone() {
        try {
            final byte[] currentHash = returnHash(SEAPP_CONTEXTS_FILE);
            final byte[] currentHash = returnHash(SEAPP_CONTEXTS);
            dumpHash(new File(SEAPP_HASH_FILE), currentHash);
        } catch (IOException ioe) {
            Slog.e(TAG, "Error with saving hash to " + SEAPP_HASH_FILE, ioe);
@@ -485,4 +469,21 @@ public final class SELinuxMMAC {
            throw new RuntimeException(nsae);  // impossible
        }
    }

    private static boolean useOverridePolicy() {
        try {
            final String overrideVersion = IoUtils.readFileAsString(DATA_VERSION_FILE);
            final String baseVersion = IoUtils.readFileAsString(BASE_VERSION_FILE);
            if (overrideVersion.equals(baseVersion)) {
                return true;
            }
            Slog.e(TAG, "Override policy version '" + overrideVersion + "' doesn't match " +
                   "base version '" + baseVersion + "'. Skipping override policy files.");
        } catch (FileNotFoundException fnfe) {
            // Override version file doesn't have to exist so silently ignore.
        } catch (IOException ioe) {
            Slog.w(TAG, "Skipping override policy files.", ioe);
        }
        return false;
    }
}