am 4f8785f2: Merge "SELinuxMMAC additions to perform policy versioning checks."
* commit '4f8785f28e6305d427cc3e483248828c9b9b06a2': SELinuxMMAC additions to perform policy versioning checks.
This commit is contained in:
@@ -52,25 +52,49 @@ public final class SELinuxMMAC {
|
|||||||
private static final boolean DEBUG_POLICY_INSTALL = DEBUG_POLICY || false;
|
private static final boolean DEBUG_POLICY_INSTALL = DEBUG_POLICY || false;
|
||||||
|
|
||||||
// Signature seinfo values read from policy.
|
// Signature seinfo values read from policy.
|
||||||
private static HashMap<Signature, Policy> sSigSeinfo =
|
private static HashMap<Signature, Policy> sSigSeinfo = new HashMap<Signature, Policy>();
|
||||||
new HashMap<Signature, Policy>();
|
|
||||||
|
|
||||||
// Default seinfo read from policy.
|
// Default seinfo read from policy.
|
||||||
private static String sDefaultSeinfo = null;
|
private static String sDefaultSeinfo = null;
|
||||||
|
|
||||||
// Locations of potential install policy files.
|
// Data policy override version file.
|
||||||
private static final File[] INSTALL_POLICY_FILE = {
|
private static final String DATA_VERSION_FILE =
|
||||||
new File(Environment.getDataDirectory(), "security/mac_permissions.xml"),
|
Environment.getDataDirectory() + "/security/current/selinux_version";
|
||||||
new File(Environment.getRootDirectory(), "etc/security/mac_permissions.xml"),
|
|
||||||
null};
|
|
||||||
|
|
||||||
// Location of seapp_contexts policy file.
|
// Base policy version file.
|
||||||
private static final String SEAPP_CONTEXTS_FILE = "/seapp_contexts";
|
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.
|
// Stores the hash of the last used seapp_contexts file.
|
||||||
private static final String SEAPP_HASH_FILE =
|
private static final String SEAPP_HASH_FILE =
|
||||||
Environment.getDataDirectory().toString() + "/system/seapp_hash";
|
Environment.getDataDirectory().toString() + "/system/seapp_hash";
|
||||||
|
|
||||||
|
|
||||||
// Signature policy stanzas
|
// Signature policy stanzas
|
||||||
static class Policy {
|
static class Policy {
|
||||||
private String seinfo;
|
private String seinfo;
|
||||||
@@ -112,51 +136,17 @@ public final class SELinuxMMAC {
|
|||||||
sDefaultSeinfo = null;
|
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() {
|
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.
|
// 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.
|
// We add all the rules together once we know there's no structural problems.
|
||||||
HashMap<Signature, Policy> sigSeinfo = new HashMap<Signature, Policy>();
|
HashMap<Signature, Policy> sigSeinfo = new HashMap<Signature, Policy>();
|
||||||
String defaultSeinfo = null;
|
String defaultSeinfo = null;
|
||||||
|
|
||||||
FileReader policyFile = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Slog.d(TAG, "Using install policy file " + policyFiles[i].getPath());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
policyFile = new FileReader(MAC_PERMISSIONS);
|
||||||
|
Slog.d(TAG, "Using policy file " + MAC_PERMISSIONS);
|
||||||
|
|
||||||
XmlPullParser parser = Xml.newPullParser();
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
parser.setInput(policyFile);
|
parser.setInput(policyFile);
|
||||||
|
|
||||||
@@ -199,20 +189,14 @@ public final class SELinuxMMAC {
|
|||||||
XmlUtils.skipCurrentTag(parser);
|
XmlUtils.skipCurrentTag(parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (XmlPullParserException e) {
|
} catch (XmlPullParserException xpe) {
|
||||||
// An error outside of a stanza means a structural problem
|
Slog.w(TAG, "Got exception parsing " + MAC_PERMISSIONS, xpe);
|
||||||
// with the xml file. So ignore it.
|
|
||||||
Slog.w(TAG, "Got exception parsing ", e);
|
|
||||||
return false;
|
return false;
|
||||||
} catch (IOException e) {
|
} catch (IOException ioe) {
|
||||||
Slog.w(TAG, "Got exception parsing ", e);
|
Slog.w(TAG, "Got exception parsing " + MAC_PERMISSIONS, ioe);
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
IoUtils.closeQuietly(policyFile);
|
||||||
policyFile.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
//omit
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flushInstallPolicy();
|
flushInstallPolicy();
|
||||||
@@ -412,7 +396,7 @@ public final class SELinuxMMAC {
|
|||||||
// Any error with the seapp_contexts file should be fatal
|
// Any error with the seapp_contexts file should be fatal
|
||||||
byte[] currentHash = null;
|
byte[] currentHash = null;
|
||||||
try {
|
try {
|
||||||
currentHash = returnHash(SEAPP_CONTEXTS_FILE);
|
currentHash = returnHash(SEAPP_CONTEXTS);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Slog.e(TAG, "Error with hashing seapp_contexts.", ioe);
|
Slog.e(TAG, "Error with hashing seapp_contexts.", ioe);
|
||||||
return false;
|
return false;
|
||||||
@@ -434,7 +418,7 @@ public final class SELinuxMMAC {
|
|||||||
*/
|
*/
|
||||||
public static void setRestoreconDone() {
|
public static void setRestoreconDone() {
|
||||||
try {
|
try {
|
||||||
final byte[] currentHash = returnHash(SEAPP_CONTEXTS_FILE);
|
final byte[] currentHash = returnHash(SEAPP_CONTEXTS);
|
||||||
dumpHash(new File(SEAPP_HASH_FILE), currentHash);
|
dumpHash(new File(SEAPP_HASH_FILE), currentHash);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Slog.e(TAG, "Error with saving hash to " + SEAPP_HASH_FILE, 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
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user