summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2012-12-12 16:24:31 -0800
committerNick Kralevich <nnk@google.com>2012-12-14 11:53:10 -0800
commit92091fa9636403728fe94cc83400495a8612c2d3 (patch)
treed1a0969ae2cd2bcddd5a0d2dfc2be100a732bd85
parent40efbd40606fc31863d3de90f062db431ba7fb47 (diff)
downloadframeworks_base-92091fa9636403728fe94cc83400495a8612c2d3.zip
frameworks_base-92091fa9636403728fe94cc83400495a8612c2d3.tar.gz
frameworks_base-92091fa9636403728fe94cc83400495a8612c2d3.tar.bz2
App home directories are now 0700 for targetSdkVersion > 17
Pass targetSdkVersion to installd so it knows the appropriate permissions to apply to the app's home directory. Bug: 7208882 Change-Id: Ia62ed36b32ee5af01077fb10a586024411be8ed4
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/content/Context.java96
-rw-r--r--core/java/android/os/Build.java11
-rw-r--r--services/java/com/android/server/pm/Installer.java18
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java19
-rw-r--r--services/java/com/android/server/pm/Settings.java6
6 files changed, 106 insertions, 45 deletions
diff --git a/api/current.txt b/api/current.txt
index 57d65ba..28344b5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15737,6 +15737,7 @@ package android.os {
field public static final int ICE_CREAM_SANDWICH_MR1 = 15; // 0xf
field public static final int JELLY_BEAN = 16; // 0x10
field public static final int JELLY_BEAN_MR1 = 17; // 0x11
+ field public static final int K = 10000; // 0x2710
}
public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7aa2507..257f84e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -64,30 +64,44 @@ public abstract class Context {
*/
public static final int MODE_PRIVATE = 0x0000;
/**
- * @deprecated Creating world-readable files is very dangerous, and likely
- * to cause security holes in applications. It is strongly discouraged;
- * instead, applications should use more formal mechanism for interactions
- * such as {@link ContentProvider}, {@link BroadcastReceiver}, and
- * {@link android.app.Service}. There are no guarantees that this
- * access mode will remain on a file, such as when it goes through a
- * backup and restore.
* File creation mode: allow all other applications to have read access
* to the created file.
+ *
+ * <b>Note:</b> Applications with {@code targetSdkVersion}
+ * {@link android.os.Build.VERSION_CODES#K} or greater have home directories
+ * with {@code 0700} permissions. Because an application's home directory
+ * is no longer world-accessible, world-readable files created within the
+ * application's home directory will not be accessible to other applications.
+ *
+ * @deprecated Creating world-readable files is very dangerous, and likely
+ * to cause security holes in applications. It is strongly discouraged;
+ * instead, applications should use more formal mechanism for interactions
+ * such as {@link ContentProvider}, {@link BroadcastReceiver}, and
+ * {@link android.app.Service}. There are no guarantees that this
+ * access mode will remain on a file, such as when it goes through a
+ * backup and restore.
* @see #MODE_PRIVATE
* @see #MODE_WORLD_WRITEABLE
*/
@Deprecated
public static final int MODE_WORLD_READABLE = 0x0001;
/**
- * @deprecated Creating world-writable files is very dangerous, and likely
- * to cause security holes in applications. It is strongly discouraged;
- * instead, applications should use more formal mechanism for interactions
- * such as {@link ContentProvider}, {@link BroadcastReceiver}, and
- * {@link android.app.Service}. There are no guarantees that this
- * access mode will remain on a file, such as when it goes through a
- * backup and restore.
* File creation mode: allow all other applications to have write access
* to the created file.
+ *
+ * <b>Note:</b> Applications with {@code targetSdkVersion}
+ * {@link android.os.Build.VERSION_CODES#K} or greater have home directories
+ * with {@code 0700} permissions. Because an application's home directory
+ * is no longer world-accessible, world-writable files created within the
+ * application's home directory will not be accessible to other applications.
+ *
+ * @deprecated Creating world-writable files is very dangerous, and likely
+ * to cause security holes in applications. It is strongly discouraged;
+ * instead, applications should use more formal mechanism for interactions
+ * such as {@link ContentProvider}, {@link BroadcastReceiver}, and
+ * {@link android.app.Service}. There are no guarantees that this
+ * access mode will remain on a file, such as when it goes through a
+ * backup and restore.
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
*/
@@ -501,18 +515,22 @@ public abstract class Context {
throws FileNotFoundException;
/**
- * Open a private file associated with this Context's application package
+ * Open a file associated with this Context's application package
* for writing. Creates the file if it doesn't already exist.
*
- * @param name The name of the file to open; can not contain path
- * separators.
- * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
- * default operation, {@link #MODE_APPEND} to append to an existing file,
- * {@link #MODE_WORLD_READABLE} and {@link #MODE_WORLD_WRITEABLE} to control
- * permissions.
+ * <b>Note:</b> Applications with {@code targetSdkVersion}
+ * {@link android.os.Build.VERSION_CODES#K} or greater have home directories
+ * with {@code 0700} permissions. Because an application's home directory
+ * is no longer world-accessible, files created with {@code mode}
+ * {@link #MODE_WORLD_READABLE} or {@link #MODE_WORLD_WRITEABLE} will not be
+ * accessible to other applications.
*
+ * @param name The name of the file to open; can not contain path separators.
+ * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
+ * default operation, {@link #MODE_APPEND} to append to an existing file,
+ * {@link #MODE_WORLD_READABLE} and {@link #MODE_WORLD_WRITEABLE} to control
+ * permissions.
* @return FileOutputStream Resulting output stream.
- *
* @see #MODE_APPEND
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
@@ -738,14 +756,19 @@ public abstract class Context {
* application; you can only set the mode of the entire directory, not
* of individual files.
*
+ * <b>Note:</b> Applications with {@code targetSdkVersion}
+ * {@link android.os.Build.VERSION_CODES#K} or greater have home directories
+ * with {@code 0700} permissions. Because an application's home directory
+ * is no longer world-accessible, world-readable / world-writable directories
+ * created using this method will not be accessible to other applications.
+ *
* @param name Name of the directory to retrieve. This is a directory
- * that is created as part of your application data.
+ * that is created as part of your application data.
* @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
- * default operation, {@link #MODE_WORLD_READABLE} and
- * {@link #MODE_WORLD_WRITEABLE} to control permissions.
- *
+ * default operation, {@link #MODE_WORLD_READABLE} and
+ * {@link #MODE_WORLD_WRITEABLE} to control permissions.
* @return Returns a File object for the requested directory. The directory
- * will have been created if it does not already exist.
+ * will have been created if it does not already exist.
*
* @see #openFileOutput(String, int)
*/
@@ -755,6 +778,13 @@ public abstract class Context {
* Open a new private SQLiteDatabase associated with this Context's
* application package. Create the database file if it doesn't exist.
*
+ * <b>Note:</b> Applications with {@code targetSdkVersion}
+ * {@link android.os.Build.VERSION_CODES#K} or greater have home directories
+ * with {@code 0700} permissions. Because an application's home directory
+ * is no longer world-accessible, {@code SQLiteDatabase}s created with {@code mode}
+ * {@link #MODE_WORLD_READABLE} or {@link #MODE_WORLD_WRITEABLE} will not be
+ * accessible to other applications.
+ *
* @param name The name (unique in the application package) of the database.
* @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
* default operation, {@link #MODE_WORLD_READABLE}
@@ -762,10 +792,8 @@ public abstract class Context {
* Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
* @param factory An optional factory class that is called to instantiate a
* cursor when query is called.
- *
* @return The contents of a newly created database with the given name.
* @throws android.database.sqlite.SQLiteException if the database file could not be opened.
- *
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
* @see #MODE_WORLD_WRITEABLE
@@ -782,6 +810,13 @@ public abstract class Context {
* <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
* used to handle corruption when sqlite reports database corruption.</p>
*
+ * <b>Note:</b> Applications with {@code targetSdkVersion}
+ * {@link android.os.Build.VERSION_CODES#K} or greater have home directories
+ * with {@code 0700} permissions. Because an application's home directory
+ * is no longer world-accessible, {@code SQLiteDatabase}s created with {@code mode}
+ * {@link #MODE_WORLD_READABLE} or {@link #MODE_WORLD_WRITEABLE} will not be
+ * accessible to other applications.
+ *
* @param name The name (unique in the application package) of the database.
* @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
* default operation, {@link #MODE_WORLD_READABLE}
@@ -790,10 +825,9 @@ public abstract class Context {
* @param factory An optional factory class that is called to instantiate a
* cursor when query is called.
* @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
- * corruption. if null, {@link android.database.DefaultDatabaseErrorHandler} is assumed.
+ * corruption. if null, {@link android.database.DefaultDatabaseErrorHandler} is assumed.
* @return The contents of a newly created database with the given name.
* @throws android.database.sqlite.SQLiteException if the database file could not be opened.
- *
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
* @see #MODE_WORLD_WRITEABLE
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index a7f39d5..d69d2a6 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -431,6 +431,17 @@ public class Build {
* </ul>
*/
public static final int JELLY_BEAN_MR1 = 17;
+
+ /**
+ * Android X.X: "K". Just "K"
+ *
+ * <p>Applications targeting this or a later release will get these
+ * new changes in behavior:</p>
+ * <ul>
+ * <li>Application home directory permissions are now {@code 0700}.</li>
+ * </ul>
+ */
+ public static final int K = CUR_DEVELOPMENT;
}
/** The type of build, like "user" or "eng". */
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 02a2c1b..e96820f 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -188,7 +188,12 @@ public final class Installer {
}
}
- public int install(String name, int uid, int gid) {
+ /**
+ * @param restrictHomeDir if {@code true}, installd will create the application's
+ * home directory with {@code 0700} permissions. If false, {@code 0751} will
+ * be used instead.
+ */
+ public int install(String name, int uid, int gid, boolean restrictHomeDir) {
StringBuilder builder = new StringBuilder("install");
builder.append(' ');
builder.append(name);
@@ -196,6 +201,8 @@ public final class Installer {
builder.append(uid);
builder.append(' ');
builder.append(gid);
+ builder.append(' ');
+ builder.append(restrictHomeDir);
return execute(builder.toString());
}
@@ -263,7 +270,12 @@ public final class Installer {
return execute(builder.toString());
}
- public int createUserData(String name, int uid, int userId) {
+ /**
+ * @param restrictHomeDir if {@code true}, installd will create the application's
+ * home directory with {@code 0700} permissions. If false, {@code 0751} will
+ * be used instead.
+ */
+ public int createUserData(String name, int uid, int userId, boolean restrictHomeDir) {
StringBuilder builder = new StringBuilder("mkuserdata");
builder.append(' ');
builder.append(name);
@@ -271,6 +283,8 @@ public final class Installer {
builder.append(uid);
builder.append(' ');
builder.append(userId);
+ builder.append(' ');
+ builder.append(restrictHomeDir);
return execute(builder.toString());
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 2238f17..aa2b461 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -24,7 +24,6 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static com.android.internal.util.ArrayUtils.appendInt;
import static com.android.internal.util.ArrayUtils.removeInt;
-import static libcore.io.OsConstants.S_ISLNK;
import static libcore.io.OsConstants.S_IRWXU;
import static libcore.io.OsConstants.S_IRGRP;
import static libcore.io.OsConstants.S_IXGRP;
@@ -111,7 +110,6 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.Environment.UserEnvironment;
-import android.provider.Settings.Secure;
import android.security.SystemKeyStore;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -148,13 +146,11 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;
-import libcore.io.OsConstants;
import libcore.io.StructStat;
/**
@@ -3582,16 +3578,17 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- private int createDataDirsLI(String packageName, int uid) {
+ private int createDataDirsLI(String packageName, int uid, int targetSdkVersion) {
int[] users = sUserManager.getUserIds();
- int res = mInstaller.install(packageName, uid, uid);
+ boolean restrictHomeDir = (targetSdkVersion >= Build.VERSION_CODES.K);
+ int res = mInstaller.install(packageName, uid, uid, restrictHomeDir);
if (res < 0) {
return res;
}
for (int user : users) {
if (user != 0) {
res = mInstaller.createUserData(packageName,
- UserHandle.getUid(user, uid), user);
+ UserHandle.getUid(user, uid), user, restrictHomeDir);
if (res < 0) {
return res;
}
@@ -3985,7 +3982,8 @@ public class PackageManagerService extends IPackageManager.Stub {
recovered = true;
// And now re-install the app.
- ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
+ ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
+ pkg.applicationInfo.targetSdkVersion);
if (ret == -1) {
// Ack should not happen!
msg = prefix + pkg.packageName
@@ -4030,8 +4028,9 @@ public class PackageManagerService extends IPackageManager.Stub {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.v(TAG, "Want this data dir: " + dataPath);
}
- //invoke installer to do the actual installation
- int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
+ // invoke installer to do the actual installation
+ int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
+ pkg.applicationInfo.targetSdkVersion);
if (ret < 0) {
// Error from installer
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 06f11bc..f791a6e 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -25,7 +25,6 @@ import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.XmlUtils;
-import com.android.server.IntentResolver;
import com.android.server.pm.PackageManagerService.DumpState;
import org.xmlpull.v1.XmlPullParser;
@@ -46,6 +45,7 @@ import android.content.pm.UserInfo;
import android.content.pm.PackageUserState;
import android.content.pm.VerifierDeviceIdentity;
import android.os.Binder;
+import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Process;
@@ -2335,9 +2335,11 @@ final class Settings {
for (PackageSetting ps : mPackages.values()) {
// Only system apps are initially installed.
ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
+ boolean restrictHomeDir = (ps.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.K);
// Need to create a data directory for all apps under this user.
installer.createUserData(ps.name,
- UserHandle.getUid(userHandle, ps.appId), userHandle);
+ UserHandle.getUid(userHandle, ps.appId), userHandle,
+ restrictHomeDir);
}
readDefaultPreferredAppsLPw(userHandle);
writePackageRestrictionsLPr(userHandle);