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

Commit 634dc42c authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Throw when using deprecated file modes.

installd no longer grants o+x to private app data directories for
apps targeting N, so the long-deprecated MODE_WORLD_READABLE and
MODE_WORLD_WRITEABLE flags no longer have any effect, which may lead
to frustrating debugging sessions.

So to help clearly communicate that these flags no longer work, let's
throw when an app targeting N tries using them.

Bug: 26886867
Change-Id: I97dae6182fc3c55639ff37a39c4aae6dd0bed507
parent 35871f2c
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -5501,8 +5501,7 @@ public class Activity extends ContextThemeWrapper
     * class name as the preferences name.
     *
     * @param mode Operating mode.  Use {@link #MODE_PRIVATE} for the default
     *             operation, {@link #MODE_WORLD_READABLE} and
     *             {@link #MODE_WORLD_WRITEABLE} to control permissions.
     *             operation.
     *
     * @return Returns the single SharedPreferences instance that can be used
     *         to retrieve and modify the preference values.
+16 −2
Original line number Diff line number Diff line
@@ -340,6 +340,7 @@ class ContextImpl extends Context {

    @Override
    public SharedPreferences getSharedPreferences(File file, int mode) {
        checkMode(mode);
        SharedPreferencesImpl sp;
        synchronized (ContextImpl.class) {
            final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
@@ -455,8 +456,8 @@ class ContextImpl extends Context {
    }

    @Override
    public FileOutputStream openFileOutput(String name, int mode)
        throws FileNotFoundException {
    public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException {
        checkMode(mode);
        final boolean append = (mode&MODE_APPEND) != 0;
        File f = makeFilename(getFilesDir(), name);
        try {
@@ -638,6 +639,7 @@ class ContextImpl extends Context {
    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
            DatabaseErrorHandler errorHandler) {
        checkMode(mode);
        File f = getDatabasePath(name);
        int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
        if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
@@ -1917,6 +1919,7 @@ class ContextImpl extends Context {

    @Override
    public File getDir(String name, int mode) {
        checkMode(mode);
        name = "app_" + name;
        File file = makeFilename(getDataDirFile(), name);
        if (!file.exists()) {
@@ -2069,6 +2072,17 @@ class ContextImpl extends Context {
        return mActivityToken;
    }

    private void checkMode(int mode) {
        if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.N) {
            if ((mode & MODE_WORLD_READABLE) != 0) {
                throw new SecurityException("MODE_WORLD_READABLE no longer supported");
            }
            if ((mode & MODE_WORLD_WRITEABLE) != 0) {
                throw new SecurityException("MODE_WORLD_WRITEABLE no longer supported");
            }
        }
    }

    @SuppressWarnings("deprecation")
    static void setFilePermissionsFromMode(String name, int mode,
            int extraPermissions) {
+62 −65
Original line number Diff line number Diff line
@@ -82,40 +82,49 @@ public abstract class Context {
     * File creation mode: the default mode, where the created file can only
     * be accessed by the calling application (or all applications sharing the
     * same user ID).
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     */
    public static final int MODE_PRIVATE = 0x0000;

    /**
     * File creation mode: allow all other applications to have read access to
     * the created file.
     * <p>
     * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
     * mode will throw a {@link SecurityException}.
     *
     * @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.
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_WRITEABLE
     *             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 android.support.v4.content.FileProvider
     * @see Intent#FLAG_GRANT_WRITE_URI_PERMISSION
     */
    @Deprecated
    public static final int MODE_WORLD_READABLE = 0x0001;

    /**
     * File creation mode: allow all other applications to have write access to
     * the created file.
     * <p>
     * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
     * mode will throw a {@link SecurityException}.
     *
     * @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.
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     *             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 android.support.v4.content.FileProvider
     * @see Intent#FLAG_GRANT_WRITE_URI_PERMISSION
     */
    @Deprecated
    public static final int MODE_WORLD_WRITEABLE = 0x0002;

    /**
     * File creation mode: for use with {@link #openFileOutput}, if the file
     * already exists then write data to the end of the existing file
@@ -657,15 +666,12 @@ public abstract class Context {
     * does not exist, it will be created when you retrieve an
     * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
     * @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.
     *
     * @return The single {@link SharedPreferences} instance that can be used
     *         to retrieve and modify the preference values.
     *
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     */
    public abstract SharedPreferences getSharedPreferences(String name, int mode);

@@ -680,16 +686,13 @@ public abstract class Context {
     * does not exist, it will be created when you retrieve an
     * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
     * @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.
     *
     * @return The single {@link SharedPreferences} instance that can be used
     *         to retrieve and modify the preference values.
     *
     * @see #getSharedPreferencesPath(String)
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     */
    public abstract SharedPreferences getSharedPreferences(File file, int mode);

@@ -747,14 +750,11 @@ public abstract class Context {
     * @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.
     *            default operation. Use {@link #MODE_APPEND} to append to an
     *            existing file.
     * @return The resulting {@link FileOutputStream}.
     * @see #MODE_APPEND
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     * @see #openFileInput
     * @see #fileList
     * @see #deleteFile
@@ -1315,8 +1315,7 @@ public abstract class Context {
     * @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.
     * default operation.
     *
     * @return A {@link File} object for the requested directory.  The directory
     * will have been created if it does not already exist.
@@ -1331,19 +1330,16 @@ public abstract class Context {
     *
     * @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}
     *     and {@link #MODE_WORLD_WRITEABLE} to control permissions.
     *     Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
     *     Use {@link #MODE_NO_LOCALIZED_COLLATORS} to disable localized collators.
     *            default operation. Use
     *            {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead
     *            logging by default. Use {@link #MODE_NO_LOCALIZED_COLLATORS}
     *            to disable localized collators.
     * @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.
     *
     * @throws android.database.sqlite.SQLiteException if the database file
     *             could not be opened.
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     * @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
     * @see #MODE_NO_LOCALIZED_COLLATORS
     * @see #deleteDatabase
@@ -1354,26 +1350,27 @@ public abstract class Context {
    /**
     * Open a new private SQLiteDatabase associated with this Context's
     * application package. Creates the database file if it doesn't exist.
     *
     * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
     * used to handle corruption when sqlite reports database corruption.</p>
     * <p>
     * Accepts input param: a concrete instance of {@link DatabaseErrorHandler}
     * to be used to handle corruption when sqlite reports database corruption.
     * </p>
     *
     * @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}
     *     and {@link #MODE_WORLD_WRITEABLE} to control permissions.
     *     Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
     *     Use {@link #MODE_NO_LOCALIZED_COLLATORS} to disable localized collators.
     *            default operation. Use
     *            {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead
     *            logging by default. Use {@link #MODE_NO_LOCALIZED_COLLATORS}
     *            to disable localized collators.
     * @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.
     * @param errorHandler the {@link DatabaseErrorHandler} to be used when
     *            sqlite reports database 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.
     *
     * @throws android.database.sqlite.SQLiteException if the database file
     *             could not be opened.
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     * @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
     * @see #MODE_NO_LOCALIZED_COLLATORS
     * @see #deleteDatabase