FileDocCategorySizeDatePackage
SELinuxPolicyInstallReceiver.javaAPI DocAndroid 5.1 API6690Thu Mar 12 22:22:42 GMT 2015com.android.server.updates

SELinuxPolicyInstallReceiver

public class SELinuxPolicyInstallReceiver extends ConfigUpdateInstallReceiver

Fields Summary
private static final String
TAG
private static final String
sepolicyPath
private static final String
fileContextsPath
private static final String
propertyContextsPath
private static final String
seappContextsPath
private static final String
versionPath
private static final String
macPermissionsPath
private static final String
serviceContextsPath
Constructors Summary
public SELinuxPolicyInstallReceiver()


      
        super("/data/security/bundle", "sepolicy_bundle", "metadata/", "version");
    
Methods Summary
private voidapplyUpdate()

        Slog.i(TAG, "Applying SELinux policy");
        File contexts = new File(updateDir.getParentFile(), "contexts");
        File current = new File(updateDir.getParentFile(), "current");
        File update = new File(updateDir.getParentFile(), "update");
        File tmp = new File(updateDir.getParentFile(), "tmp");
        if (current.exists()) {
            Os.symlink(updateDir.getPath(), update.getPath());
            Os.rename(update.getPath(), current.getPath());
        } else {
            Os.symlink(updateDir.getPath(), current.getPath());
        }
        contexts.mkdirs();
        backupContexts(contexts);
        copyUpdate(contexts);
        Os.symlink(contexts.getPath(), tmp.getPath());
        Os.rename(tmp.getPath(), current.getPath());
        SystemProperties.set("selinux.reload_policy", "1");
    
private voidbackupContexts(java.io.File contexts)

        new File(contexts, versionPath).renameTo(
                new File(contexts, versionPath + "_backup"));

        new File(contexts, macPermissionsPath).renameTo(
                new File(contexts, macPermissionsPath + "_backup"));

        new File(contexts, seappContextsPath).renameTo(
                new File(contexts, seappContextsPath + "_backup"));

        new File(contexts, propertyContextsPath).renameTo(
                new File(contexts, propertyContextsPath + "_backup"));

        new File(contexts, fileContextsPath).renameTo(
                new File(contexts, fileContextsPath + "_backup"));

        new File(contexts, sepolicyPath).renameTo(
                new File(contexts, sepolicyPath + "_backup"));

        new File(contexts, serviceContextsPath).renameTo(
                new File(contexts, serviceContextsPath + "_backup"));
    
private voidcopyUpdate(java.io.File contexts)

        new File(updateDir, versionPath).renameTo(new File(contexts, versionPath));
        new File(updateDir, macPermissionsPath).renameTo(new File(contexts, macPermissionsPath));
        new File(updateDir, seappContextsPath).renameTo(new File(contexts, seappContextsPath));
        new File(updateDir, propertyContextsPath).renameTo(new File(contexts, propertyContextsPath));
        new File(updateDir, fileContextsPath).renameTo(new File(contexts, fileContextsPath));
        new File(updateDir, sepolicyPath).renameTo(new File(contexts, sepolicyPath));
        new File(updateDir, serviceContextsPath).renameTo(new File(contexts, serviceContextsPath));
    
private voidinstallFile(java.io.File destination, java.io.BufferedInputStream stream, int length)

        byte[] chunk = new byte[length];
        stream.read(chunk, 0, length);
        writeUpdate(updateDir, destination, Base64.decode(chunk, Base64.DEFAULT));
    
protected voidpostInstall(android.content.Context context, android.content.Intent intent)

        try {
            unpackBundle();
            applyUpdate();
        } catch (IllegalArgumentException e) {
            Slog.e(TAG, "SELinux policy update malformed: ", e);
        } catch (IOException e) {
            Slog.e(TAG, "Could not update selinux policy: ", e);
        } catch (ErrnoException e) {
            Slog.e(TAG, "Could not update selinux policy: ", e);
        }
    
private int[]readChunkLengths(java.io.BufferedInputStream bundle)

        int[] chunks = new int[7];
        chunks[0] = readInt(bundle);
        chunks[1] = readInt(bundle);
        chunks[2] = readInt(bundle);
        chunks[3] = readInt(bundle);
        chunks[4] = readInt(bundle);
        chunks[5] = readInt(bundle);
        chunks[6] = readInt(bundle);
        return chunks;
    
private intreadInt(java.io.BufferedInputStream reader)

        int value = 0;
        for (int i=0; i < 4; i++) {
            value = (value << 8) | reader.read();
        }
        return value;
    
private voidunpackBundle()

        BufferedInputStream stream = new BufferedInputStream(new FileInputStream(updateContent));
        try {
            int[] chunkLengths = readChunkLengths(stream);
            installFile(new File(updateDir, versionPath), stream, chunkLengths[0]);
            installFile(new File(updateDir, macPermissionsPath), stream, chunkLengths[1]);
            installFile(new File(updateDir, seappContextsPath), stream, chunkLengths[2]);
            installFile(new File(updateDir, propertyContextsPath), stream, chunkLengths[3]);
            installFile(new File(updateDir, fileContextsPath), stream, chunkLengths[4]);
            installFile(new File(updateDir, sepolicyPath), stream, chunkLengths[5]);
            installFile(new File(updateDir, serviceContextsPath), stream, chunkLengths[6]);
        } finally {
            IoUtils.closeQuietly(stream);
        }