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

Commit 83aacdee authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Update xattrs when creating cache directories.

Typically installd will create cache directories for an app, and
store those inode numbers in the parent directory.  However, when an
app deletes and recreates a cache directory, the (now invalid) inode
number is left floating around, and we could end up pointing at a
useful non-cache directory.

Fix this by updating the xattr when we create the cache directory
out in userspace.

Test: builds, boots
Bug: 34185870
Change-Id: I71526dd73230c938aceabd2c0a8e89d44cc1f169
parent 20f0d091
Loading
Loading
Loading
Loading
+23 −13
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
@@ -68,20 +67,18 @@ import android.os.storage.IStorageManager;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.text.TextUtils;
import android.system.StructStat;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.IntArray;
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.view.Display;
import android.view.DisplayAdjustments;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;

import dalvik.system.PathClassLoader;
import libcore.io.Memory;

import java.io.File;
import java.io.FileInputStream;
@@ -90,8 +87,7 @@ import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.nio.ByteOrder;
import java.util.Objects;

class ReceiverRestrictedContext extends ContextWrapper {
@@ -145,6 +141,9 @@ class ContextImpl extends Context {
    private final static String TAG = "ContextImpl";
    private final static boolean DEBUG = false;

    private static final String XATTR_INODE_CACHE = "user.inode_cache";
    private static final String XATTR_INODE_CODE_CACHE = "user.inode_code_cache";

    /**
     * Map from package name, to preference name, to cached preferences.
     */
@@ -530,15 +529,15 @@ class ContextImpl extends Context {
     * Common-path handling of app data dir creation
     */
    private static File ensurePrivateDirExists(File file) {
        return ensurePrivateDirExists(file, 0771, -1);
        return ensurePrivateDirExists(file, 0771, -1, null);
    }

    private static File ensurePrivateCacheDirExists(File file) {
    private static File ensurePrivateCacheDirExists(File file, String xattr) {
        final int gid = UserHandle.getCacheAppGid(Process.myUid());
        return ensurePrivateDirExists(file, 02771, gid);
        return ensurePrivateDirExists(file, 02771, gid, xattr);
    }

    private static File ensurePrivateDirExists(File file, int mode, int gid) {
    private static File ensurePrivateDirExists(File file, int mode, int gid, String xattr) {
        if (!file.exists()) {
            final String path = file.getAbsolutePath();
            try {
@@ -554,6 +553,17 @@ class ContextImpl extends Context {
                    Log.w(TAG, "Failed to ensure " + file + ": " + e.getMessage());
                }
            }

            if (xattr != null) {
                try {
                    final StructStat stat = Os.stat(file.getAbsolutePath());
                    final byte[] value = new byte[8];
                    Memory.pokeLong(value, 0, stat.st_ino, ByteOrder.nativeOrder());
                    Os.setxattr(file.getParentFile().getAbsolutePath(), xattr, value, 0);
                } catch (ErrnoException e) {
                    Log.w(TAG, "Failed to update " + xattr + ": " + e.getMessage());
                }
            }
        }
        return file;
    }
@@ -615,7 +625,7 @@ class ContextImpl extends Context {
            if (mCacheDir == null) {
                mCacheDir = new File(getDataDir(), "cache");
            }
            return ensurePrivateCacheDirExists(mCacheDir);
            return ensurePrivateCacheDirExists(mCacheDir, XATTR_INODE_CACHE);
        }
    }

@@ -625,7 +635,7 @@ class ContextImpl extends Context {
            if (mCodeCacheDir == null) {
                mCodeCacheDir = new File(getDataDir(), "code_cache");
            }
            return ensurePrivateCacheDirExists(mCodeCacheDir);
            return ensurePrivateCacheDirExists(mCodeCacheDir, XATTR_INODE_CODE_CACHE);
        }
    }