Loading services/core/java/com/android/server/pm/PackageManagerService.java +9 −37 Original line number Diff line number Diff line Loading @@ -19781,8 +19781,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); boolean restoreconNeeded = false; // First look for stale data that doesn't belong, and check if things // have changed since we did our last restorecon if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { Loading @@ -19793,8 +19791,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); + " was still locked; this would have caused massive data loss!"); } restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); final File[] files = FileUtils.listFilesOrEmpty(ceDir); for (File file : files) { final String packageName = file.getName(); Loading @@ -19812,8 +19808,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); final File[] files = FileUtils.listFilesOrEmpty(deDir); for (File file : files) { final String packageName = file.getName(); Loading Loading @@ -19848,29 +19842,19 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } if (ps.getInstalled(userId)) { prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded); prepareAppDataLIF(ps.pkg, userId, flags); if (maybeMigrateAppDataLIF(ps.pkg, userId)) { // We may have just shuffled around app data directories, so // prepare them one more time prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded); prepareAppDataLIF(ps.pkg, userId, flags); } preparedCount++; } } if (restoreconNeeded) { if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { SELinuxMMAC.setRestoreconDone(ceDir); } if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { SELinuxMMAC.setRestoreconDone(deDir); } } Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages; restoreconNeeded was " + restoreconNeeded); Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); } /** Loading Loading @@ -19905,9 +19889,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } if (ps.getInstalled(user.id)) { // Whenever an app changes, force a restorecon of its data // TODO: when user data is locked, mark that we're still dirty prepareAppDataLIF(pkg, user.id, flags, true); prepareAppDataLIF(pkg, user.id, flags); } } } Loading @@ -19920,24 +19903,22 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); * will try recovering system apps by wiping data; third-party app data is * left intact. */ private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags, boolean restoreconNeeded) { private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } prepareAppDataLeafLIF(pkg, userId, flags, restoreconNeeded); prepareAppDataLeafLIF(pkg, userId, flags); final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; for (int i = 0; i < childCount; i++) { prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags, restoreconNeeded); prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); } } private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags, boolean restoreconNeeded) { private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { if (DEBUG_APP_DATA) { Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); + Integer.toHexString(flags)); } final String volumeUuid = pkg.volumeUuid; Loading Loading @@ -19967,15 +19948,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } if (restoreconNeeded) { try { mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, app.seinfo); } catch (InstallerException e) { Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); } } if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { try { // CE storage is unlocked right now, so read out the inode and services/core/java/com/android/server/pm/SELinuxMMAC.java +0 −81 Original line number Diff line number Diff line Loading @@ -19,10 +19,6 @@ package com.android.server.pm; import android.content.pm.PackageParser; import android.content.pm.Signature; import android.os.Environment; import android.os.SystemProperties; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.util.Slog; import android.util.Xml; Loading @@ -34,10 +30,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; Loading Loading @@ -65,24 +58,10 @@ public final class SELinuxMMAC { // to synchronize access during policy load and access attempts. private static List<Policy> sPolicies = new ArrayList<>(); private static final String PROP_FORCE_RESTORECON = "sys.force_restorecon"; /** Path to version on rootfs */ private static final File VERSION_FILE = new File("/selinux_version"); /** Path to MAC permissions on system image */ private static final File MAC_PERMISSIONS = new File(Environment.getRootDirectory(), "/etc/security/mac_permissions.xml"); /** Path to app contexts on rootfs */ private static final File SEAPP_CONTEXTS = new File("/seapp_contexts"); /** Calculated hash of {@link #SEAPP_CONTEXTS} */ private static final byte[] SEAPP_CONTEXTS_HASH = returnHash(SEAPP_CONTEXTS); /** Attribute where {@link #SEAPP_CONTEXTS_HASH} is stored */ private static final String XATTR_SEAPP_HASH = "user.seapp_hash"; // Append privapp to existing seinfo label private static final String PRIVILEGED_APP_STR = ":privapp"; Loading Loading @@ -313,66 +292,6 @@ public final class SELinuxMMAC { "seinfo=" + pkg.applicationInfo.seinfo); } } /** * Determines if a recursive restorecon on the given package data directory * is needed. It does this by comparing the SHA-1 of the seapp_contexts file * against the stored hash in an xattr. * <p> * Note that the xattr isn't in the 'security' namespace, so this should * only be run on directories owned by the system. * * @return Returns true if the restorecon should occur or false otherwise. */ public static boolean isRestoreconNeeded(File file) { // To investigate boot timing, allow a property to always force restorecon if (SystemProperties.getBoolean(PROP_FORCE_RESTORECON, false)) { return true; } try { final byte[] buf = new byte[20]; final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SEAPP_HASH, buf); if ((len == 20) && Arrays.equals(SEAPP_CONTEXTS_HASH, buf)) { return false; } } catch (ErrnoException e) { if (e.errno != OsConstants.ENODATA) { Slog.e(TAG, "Failed to read seapp hash for " + file, e); } } return true; } /** * Stores the SHA-1 of the seapp_contexts into an xattr. * <p> * Note that the xattr isn't in the 'security' namespace, so this should * only be run on directories owned by the system. */ public static void setRestoreconDone(File file) { try { Os.setxattr(file.getAbsolutePath(), XATTR_SEAPP_HASH, SEAPP_CONTEXTS_HASH, 0); } catch (ErrnoException e) { Slog.e(TAG, "Failed to persist seapp hash in " + file, e); } } /** * Return the SHA-1 of a file. * * @param file The path to the file given as a string. * @return Returns the SHA-1 of the file as a byte array. */ private static byte[] returnHash(File file) { try { final byte[] contents = IoUtils.readFileAsByteArray(file.getAbsolutePath()); return MessageDigest.getInstance("SHA-1").digest(contents); } catch (IOException | NoSuchAlgorithmException e) { throw new RuntimeException(e); } } } /** Loading Loading
services/core/java/com/android/server/pm/PackageManagerService.java +9 −37 Original line number Diff line number Diff line Loading @@ -19781,8 +19781,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); boolean restoreconNeeded = false; // First look for stale data that doesn't belong, and check if things // have changed since we did our last restorecon if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { Loading @@ -19793,8 +19791,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); + " was still locked; this would have caused massive data loss!"); } restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); final File[] files = FileUtils.listFilesOrEmpty(ceDir); for (File file : files) { final String packageName = file.getName(); Loading @@ -19812,8 +19808,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); final File[] files = FileUtils.listFilesOrEmpty(deDir); for (File file : files) { final String packageName = file.getName(); Loading Loading @@ -19848,29 +19842,19 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } if (ps.getInstalled(userId)) { prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded); prepareAppDataLIF(ps.pkg, userId, flags); if (maybeMigrateAppDataLIF(ps.pkg, userId)) { // We may have just shuffled around app data directories, so // prepare them one more time prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded); prepareAppDataLIF(ps.pkg, userId, flags); } preparedCount++; } } if (restoreconNeeded) { if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { SELinuxMMAC.setRestoreconDone(ceDir); } if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { SELinuxMMAC.setRestoreconDone(deDir); } } Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages; restoreconNeeded was " + restoreconNeeded); Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); } /** Loading Loading @@ -19905,9 +19889,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } if (ps.getInstalled(user.id)) { // Whenever an app changes, force a restorecon of its data // TODO: when user data is locked, mark that we're still dirty prepareAppDataLIF(pkg, user.id, flags, true); prepareAppDataLIF(pkg, user.id, flags); } } } Loading @@ -19920,24 +19903,22 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); * will try recovering system apps by wiping data; third-party app data is * left intact. */ private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags, boolean restoreconNeeded) { private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } prepareAppDataLeafLIF(pkg, userId, flags, restoreconNeeded); prepareAppDataLeafLIF(pkg, userId, flags); final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; for (int i = 0; i < childCount; i++) { prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags, restoreconNeeded); prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); } } private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags, boolean restoreconNeeded) { private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { if (DEBUG_APP_DATA) { Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); + Integer.toHexString(flags)); } final String volumeUuid = pkg.volumeUuid; Loading Loading @@ -19967,15 +19948,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } if (restoreconNeeded) { try { mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, app.seinfo); } catch (InstallerException e) { Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); } } if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { try { // CE storage is unlocked right now, so read out the inode and
services/core/java/com/android/server/pm/SELinuxMMAC.java +0 −81 Original line number Diff line number Diff line Loading @@ -19,10 +19,6 @@ package com.android.server.pm; import android.content.pm.PackageParser; import android.content.pm.Signature; import android.os.Environment; import android.os.SystemProperties; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.util.Slog; import android.util.Xml; Loading @@ -34,10 +30,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; Loading Loading @@ -65,24 +58,10 @@ public final class SELinuxMMAC { // to synchronize access during policy load and access attempts. private static List<Policy> sPolicies = new ArrayList<>(); private static final String PROP_FORCE_RESTORECON = "sys.force_restorecon"; /** Path to version on rootfs */ private static final File VERSION_FILE = new File("/selinux_version"); /** Path to MAC permissions on system image */ private static final File MAC_PERMISSIONS = new File(Environment.getRootDirectory(), "/etc/security/mac_permissions.xml"); /** Path to app contexts on rootfs */ private static final File SEAPP_CONTEXTS = new File("/seapp_contexts"); /** Calculated hash of {@link #SEAPP_CONTEXTS} */ private static final byte[] SEAPP_CONTEXTS_HASH = returnHash(SEAPP_CONTEXTS); /** Attribute where {@link #SEAPP_CONTEXTS_HASH} is stored */ private static final String XATTR_SEAPP_HASH = "user.seapp_hash"; // Append privapp to existing seinfo label private static final String PRIVILEGED_APP_STR = ":privapp"; Loading Loading @@ -313,66 +292,6 @@ public final class SELinuxMMAC { "seinfo=" + pkg.applicationInfo.seinfo); } } /** * Determines if a recursive restorecon on the given package data directory * is needed. It does this by comparing the SHA-1 of the seapp_contexts file * against the stored hash in an xattr. * <p> * Note that the xattr isn't in the 'security' namespace, so this should * only be run on directories owned by the system. * * @return Returns true if the restorecon should occur or false otherwise. */ public static boolean isRestoreconNeeded(File file) { // To investigate boot timing, allow a property to always force restorecon if (SystemProperties.getBoolean(PROP_FORCE_RESTORECON, false)) { return true; } try { final byte[] buf = new byte[20]; final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SEAPP_HASH, buf); if ((len == 20) && Arrays.equals(SEAPP_CONTEXTS_HASH, buf)) { return false; } } catch (ErrnoException e) { if (e.errno != OsConstants.ENODATA) { Slog.e(TAG, "Failed to read seapp hash for " + file, e); } } return true; } /** * Stores the SHA-1 of the seapp_contexts into an xattr. * <p> * Note that the xattr isn't in the 'security' namespace, so this should * only be run on directories owned by the system. */ public static void setRestoreconDone(File file) { try { Os.setxattr(file.getAbsolutePath(), XATTR_SEAPP_HASH, SEAPP_CONTEXTS_HASH, 0); } catch (ErrnoException e) { Slog.e(TAG, "Failed to persist seapp hash in " + file, e); } } /** * Return the SHA-1 of a file. * * @param file The path to the file given as a string. * @return Returns the SHA-1 of the file as a byte array. */ private static byte[] returnHash(File file) { try { final byte[] contents = IoUtils.readFileAsByteArray(file.getAbsolutePath()); return MessageDigest.getInstance("SHA-1").digest(contents); } catch (IOException | NoSuchAlgorithmException e) { throw new RuntimeException(e); } } } /** Loading