diff options
author | Geremy Condra <gcondra@google.com> | 2013-04-12 23:48:19 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-04-12 23:48:20 +0000 |
commit | f0dffd0ab58f35630b0b70dcf778cf82010ef540 (patch) | |
tree | 3441e252df1a7462d7a44fcab51732a6ea85bc57 /services/java | |
parent | c1dedb6fc41855a03651924b2cc18b2d605413ed (diff) | |
parent | 7951ceb0d1b13c430ed72a8a9d92b66f757e5cac (diff) | |
download | frameworks_base-f0dffd0ab58f35630b0b70dcf778cf82010ef540.zip frameworks_base-f0dffd0ab58f35630b0b70dcf778cf82010ef540.tar.gz frameworks_base-f0dffd0ab58f35630b0b70dcf778cf82010ef540.tar.bz2 |
Merge "Add logic to handle changes to file_contexts during update."
Diffstat (limited to 'services/java')
-rw-r--r-- | services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java | 8 | ||||
-rw-r--r-- | services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java | 83 |
2 files changed, 80 insertions, 11 deletions
diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java index c94f7c1..9601e9a 100644 --- a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java +++ b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java @@ -56,9 +56,9 @@ public class ConfigUpdateInstallReceiver extends BroadcastReceiver { private static final String UPDATE_CERTIFICATE_KEY = "config_update_certificate"; - private final File updateDir; - private final File updateContent; - private final File updateVersion; + protected final File updateDir; + protected final File updateContent; + protected final File updateVersion; public ConfigUpdateInstallReceiver(String updateDir, String updateContentPath, String updateMetadataPath, String updateVersionPath) { @@ -222,7 +222,7 @@ public class ConfigUpdateInstallReceiver extends BroadcastReceiver { return signer.verify(Base64.decode(signature.getBytes(), Base64.DEFAULT)); } - private void writeUpdate(File dir, File file, byte[] content) throws IOException { + protected void writeUpdate(File dir, File file, byte[] content) throws IOException { FileOutputStream out = null; File tmp = null; try { diff --git a/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java b/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java index 748849e..f1ec092 100644 --- a/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java +++ b/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java @@ -18,28 +18,97 @@ package com.android.server.updates; import android.content.Context; import android.content.Intent; +import android.os.FileUtils; import android.os.SELinux; +import android.os.SystemProperties; import android.provider.Settings; import android.util.Base64; import android.util.Slog; +import java.io.File; import java.io.IOException; +import libcore.io.IoUtils; + public class SELinuxPolicyInstallReceiver extends ConfigUpdateInstallReceiver { + private static final String TAG = "SELinuxPolicyInstallReceiver"; + + private static final String sepolicyPath = "sepolicy"; + private static final String fileContextsPath = "file_contexts"; + private static final String propertyContextsPath = "property_contexts"; + private static final String seappContextsPath = "seapp_contexts"; + public SELinuxPolicyInstallReceiver() { - super("/data/security/", "sepolicy", "metadata/", "version"); + super("/data/security/", "sepolicy_bundle", "metadata/", "version"); } - @Override - protected void install(byte[] encodedContent, int version) throws IOException { - super.install(Base64.decode(encodedContent, Base64.DEFAULT), version); + private void installFile(File destination, String content) throws IOException { + backupFile(destination); + writeUpdate(updateDir, destination, Base64.decode(content, Base64.DEFAULT)); + } + + private void rollBackFile(File replace) throws IOException { + File backup = new File(replace.getCanonicalPath() + "_backup"); + FileUtils.copyFile(backup, replace); + } + + private void backupFile(File state) throws IOException { + File backup = new File(state.getCanonicalPath() + "_backup"); + FileUtils.copyFile(state, backup); + } + + private void unpackBundle() throws IOException { + // read the bundle + String bundle = IoUtils.readFileAsString(updateContent.getCanonicalPath()); + // split it into newline-separated base64'd chunks + String[] chunks = bundle.split("\n\n"); + // chunks are: + // 1. sepolicy + // 2. file_contexts + // 3. property_contexts + // 4. seapp_contexts + if (chunks.length != 4) { + throw new IOException("Invalid number of chunks"); + } + // install each of these + installFile(new File(updateDir, sepolicyPath), chunks[0]); + installFile(new File(updateDir, fileContextsPath), chunks[1]); + installFile(new File(updateDir, propertyContextsPath), chunks[2]); + installFile(new File(updateDir, seappContextsPath), chunks[3]); + } + + private void rollBackUpdate() { + try { + rollBackFile(new File(updateDir, sepolicyPath)); + rollBackFile(new File(updateDir, fileContextsPath)); + rollBackFile(new File(updateDir, propertyContextsPath)); + rollBackFile(new File(updateDir, seappContextsPath)); + } catch (IOException e) { + Slog.e(TAG, "Could not roll back selinux policy update: ", e); + } + } + + private void applyUpdate() { + Slog.i(TAG, "Reloading SELinux policy"); + SystemProperties.set("selinux.reload_policy", "1"); + } + + private void setEnforcingMode(Context context) { + boolean mode = Settings.Global.getInt(context.getContentResolver(), + Settings.Global.SELINUX_STATUS, 0) == 1; + SELinux.setSELinuxEnforce(mode); } @Override protected void postInstall(Context context, Intent intent) { - boolean mode = Settings.Global.getInt(context.getContentResolver(), - Settings.Global.SELINUX_STATUS, 0) == 1; - SELinux.setSELinuxEnforce(mode); + try { + unpackBundle(); + applyUpdate(); + setEnforcingMode(context); + } catch (IOException e) { + Slog.e(TAG, "Could not update selinux policy: ", e); + rollBackUpdate(); + } } } |