Encrypted File Systems Project. Installer modifications.
Started to modify isntaller for data redirection to a secure location.
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 5ed2d35..9f01c61 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -122,6 +122,8 @@
private static final boolean GET_CERTIFICATES = true;
+ private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
+
private static final int REMOVE_EVENTS =
FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
private static final int ADD_EVENTS =
@@ -160,6 +162,10 @@
// This is where all application persistent data goes.
final File mAppDataDir;
+ // If Encrypted File System feature is enabled, all application persistent data
+ // should go here instead.
+ final File mSecureAppDataDir;
+
// This is the object monitoring the framework dir.
final FileObserver mFrameworkInstallObserver;
@@ -422,6 +428,7 @@
File dataDir = Environment.getDataDirectory();
mAppDataDir = new File(dataDir, "data");
+ mSecureAppDataDir = new File(dataDir, "secure/data");
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
if (mInstaller == null) {
@@ -431,6 +438,7 @@
File miscDir = new File(dataDir, "misc");
miscDir.mkdirs();
mAppDataDir.mkdirs();
+ mSecureAppDataDir.mkdirs();
mDrmAppPrivateInstallDir.mkdirs();
}
@@ -573,7 +581,7 @@
mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists
}
//look for any incomplete package installations
- ArrayList<String> deletePkgsList = mSettings.getListOfIncompleteInstallPackages();
+ ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackages();
//clean up list
for(int i = 0; i < deletePkgsList.size(); i++) {
//clean up here
@@ -628,20 +636,20 @@
}
}
- void cleanupInstallFailedPackage(String packageName) {
+ void cleanupInstallFailedPackage(PackageSetting pkgSettings) {
if (mInstaller != null) {
- int retCode = mInstaller.remove(packageName);
+ boolean useSecureFS = useEncryptedFilesystemForPackage(pkgSettings.pkg);
+ int retCode = mInstaller.remove(pkgSettings.name, useSecureFS);
if (retCode < 0) {
Log.w(TAG, "Couldn't remove app data directory for package: "
- + packageName + ", retcode=" + retCode);
+ + pkgSettings.name + ", retcode=" + retCode);
}
} else {
//for emulator
- PackageParser.Package pkg = mPackages.get(packageName);
- File dataDir = new File(pkg.applicationInfo.dataDir);
+ File dataDir = new File(pkgSettings.pkg.applicationInfo.dataDir);
dataDir.delete();
}
- mSettings.removePackageLP(packageName);
+ mSettings.removePackageLP(pkgSettings.name);
}
void readPermissions() {
@@ -2155,6 +2163,11 @@
return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
}
+
+ private static boolean useEncryptedFilesystemForPackage(PackageParser.Package pkg) {
+ return Environment.isEncryptedFilesystemEnabled() &&
+ ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_NEVER_ENCRYPT) == 0);
+ }
private PackageParser.Package scanPackageLI(
File scanFile, File destCodeFile, File destResourceFile,
@@ -2364,8 +2377,9 @@
}
if (removeExisting) {
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
if (mInstaller != null) {
- int ret = mInstaller.remove(pkgName);
+ int ret = mInstaller.remove(pkgName, useEncryptedFSDir);
if (ret != 0) {
String msg = "System package " + pkg.packageName
+ " could not have data directory erased after signature change.";
@@ -2395,7 +2409,12 @@
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
// This is a normal package, need to make its data directory.
- dataPath = new File(mAppDataDir, pkgName);
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
+ if (useEncryptedFSDir) {
+ dataPath = new File(mSecureAppDataDir, pkgName);
+ } else {
+ dataPath = new File(mAppDataDir, pkgName);
+ }
if (dataPath.exists()) {
mOutPermissions[1] = 0;
FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
@@ -2408,7 +2427,7 @@
// If this is a system app, we can at least delete its
// current data so the application will still work.
if (mInstaller != null) {
- int ret = mInstaller.remove(pkgName);
+ int ret = mInstaller.remove(pkgName, useEncryptedFSDir);
if(ret >= 0) {
// Old data gone!
String msg = "System package " + pkg.packageName
@@ -2419,7 +2438,7 @@
recovered = true;
// And now re-install the app.
- ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
+ ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if (ret == -1) {
// Ack should not happen!
@@ -2459,7 +2478,7 @@
Log.v(TAG, "Want this data dir: " + dataPath);
//invoke installer to do the actual installation
if (mInstaller != null) {
- int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
+ int ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if(ret < 0) {
// Error from installer
@@ -3822,7 +3841,13 @@
PackageParser.Package pkg, boolean forwardLocked, boolean newInstall,
String installerPackageName, PackageInstalledInfo res) {
// Remember this for later, in case we need to rollback this install
- boolean dataDirExists = (new File(mAppDataDir, pkgName)).exists();
+ boolean dataDirExists;
+
+ if (useEncryptedFilesystemForPackage(pkg)) {
+ dataDirExists = (new File(mSecureAppDataDir, pkgName)).exists();
+ } else {
+ dataDirExists = (new File(mAppDataDir, pkgName)).exists();
+ }
res.name = pkgName;
synchronized(mPackages) {
if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(destFilePath)) {
@@ -4552,8 +4577,9 @@
deletedPs = mSettings.mPackages.get(packageName);
}
if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
if (mInstaller != null) {
- int retCode = mInstaller.remove(packageName);
+ int retCode = mInstaller.remove(packageName, useEncryptedFSDir);
if (retCode < 0) {
Log.w(TAG, "Couldn't remove app data or cache directory for package: "
+ packageName + ", retcode=" + retCode);
@@ -4795,6 +4821,8 @@
p = ps.pkg;
}
}
+ boolean useEncryptedFSDir = false;
+
if(!dataOnly) {
//need to check this only for fully installed applications
if (p == null) {
@@ -4806,9 +4834,10 @@
Log.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
+ useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
}
if (mInstaller != null) {
- int retCode = mInstaller.clearUserData(packageName);
+ int retCode = mInstaller.clearUserData(packageName, useEncryptedFSDir);
if (retCode < 0) {
Log.w(TAG, "Couldn't remove cache files for package: "
+ packageName);
@@ -4859,8 +4888,9 @@
Log.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
if (mInstaller != null) {
- int retCode = mInstaller.deleteCacheFiles(packageName);
+ int retCode = mInstaller.deleteCacheFiles(packageName, useEncryptedFSDir);
if (retCode < 0) {
Log.w(TAG, "Couldn't remove cache files for package: "
+ packageName);
@@ -4922,9 +4952,10 @@
}
publicSrcDir = isForwardLocked(p) ? applicationInfo.publicSourceDir : null;
}
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
if (mInstaller != null) {
int res = mInstaller.getSizeInfo(packageName, p.mPath,
- publicSrcDir, pStats);
+ publicSrcDir, pStats, useEncryptedFSDir);
if (res < 0) {
return false;
} else {
@@ -6132,11 +6163,18 @@
Settings() {
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
+ // TODO(oam): This secure dir creation needs to be moved somewhere else (later)
+ File systemSecureDir = new File(dataDir, "secure/system");
systemDir.mkdirs();
+ systemSecureDir.mkdirs();
FileUtils.setPermissions(systemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
+ FileUtils.setPermissions(systemSecureDir.toString(),
+ FileUtils.S_IRWXU|FileUtils.S_IRWXG
+ |FileUtils.S_IROTH|FileUtils.S_IXOTH,
+ -1, -1);
mSettingsFilename = new File(systemDir, "packages.xml");
mBackupSettingsFilename = new File(systemDir, "packages-backup.xml");
}
@@ -6807,15 +6845,15 @@
return mReadMessages.toString();
}
- ArrayList<String> getListOfIncompleteInstallPackages() {
+ ArrayList<PackageSetting> getListOfIncompleteInstallPackages() {
HashSet<String> kList = new HashSet<String>(mPackages.keySet());
Iterator<String> its = kList.iterator();
- ArrayList<String> ret = new ArrayList<String>();
+ ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
while(its.hasNext()) {
String key = its.next();
PackageSetting ps = mPackages.get(key);
if(ps.getInstallStatus() == PKG_INSTALL_INCOMPLETE) {
- ret.add(key);
+ ret.add(ps);
}
}
return ret;