Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92091fa9 authored by Nick Kralevich's avatar Nick Kralevich
Browse files

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
parent 40efbd40
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 {
+65 −31
Original line number Diff line number Diff line
@@ -64,6 +64,15 @@ public abstract class Context {
     */
    public static final int MODE_PRIVATE = 0x0000;
    /**
     * 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
@@ -71,14 +80,21 @@ public abstract class Context {
     *     {@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.
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_WRITEABLE
     */
    @Deprecated
    public static final int MODE_WORLD_READABLE = 0x0001;
    /**
     * 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
@@ -86,8 +102,6 @@ public abstract class Context {
     *     {@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.
     * @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.
     * <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,12 +756,17 @@ 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.
     * @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.
     *
     * @return Returns a File object for the requested directory.  The directory
     *     will have been created if it does not already exist.
     *
@@ -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}
@@ -793,7 +828,6 @@ public abstract class Context {
     *     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
+11 −0
Original line number Diff line number Diff line
@@ -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". */
+16 −2
Original line number Diff line number Diff line
@@ -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());
    }

+9 −10
Original line number Diff line number Diff line
@@ -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
@@ -4031,7 +4029,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                        Log.v(TAG, "Want this data dir: " + dataPath);
                }
                // invoke installer to do the actual installation
                int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
                int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
                        pkg.applicationInfo.targetSdkVersion);
                if (ret < 0) {
                    // Error from installer
                    mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
Loading