Merge "Merge commit '8fb7520a6d7720f69661f6fae9fd868726359dec' into HEAD" into nyc-mr1-dev-plus-aosp
This commit is contained in:
@@ -19802,8 +19802,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) {
|
||||
@@ -19814,8 +19812,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();
|
||||
@@ -19833,8 +19829,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();
|
||||
@@ -19869,29 +19863,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");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -19926,9 +19910,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19941,24 +19924,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;
|
||||
@@ -19988,15 +19969,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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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";
|
||||
|
||||
@@ -313,65 +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 = Os.getxattr(file.getAbsolutePath(), XATTR_SEAPP_HASH);
|
||||
if ((buf.length == 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user