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

Commit 32e4875f authored by Ricky Wai's avatar Ricky Wai Committed by Android (Google) Code Review
Browse files

Merge changes from topic "mount_isolate_apps_data"

* changes:
  App data directory isolation
  Pass app visible packages data directory info to zygote
parents f95cac8b 4482ab53
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -22,10 +22,13 @@ import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.system.Os;
import android.system.OsConstants;
import android.util.Pair;
import android.webkit.WebViewZygote;

import dalvik.system.VMRuntime;

import java.util.Map;

/**
 * Tools for managing OS processes.
 */
@@ -521,6 +524,8 @@ public class Process {
     * @param isTopApp whether the process starts for high priority application.
     * @param disabledCompatChanges null-ok list of disabled compat changes for the process being
     *                             started.
     * @param pkgDataInfoMap Map from related package names to private data directory
     *                       volume UUID and inode number.
     * @param zygoteArgs Additional arguments to supply to the zygote process.
     * @return An object that describes the result of the attempt to start the process.
     * @throws RuntimeException on fatal start failure
@@ -541,11 +546,14 @@ public class Process {
                                           @Nullable String packageName,
                                           boolean isTopApp,
                                           @Nullable long[] disabledCompatChanges,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   pkgDataInfoMap,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    /*useUsapPool=*/ true, isTopApp, disabledCompatChanges, zygoteArgs);
                    /*useUsapPool=*/ true, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, zygoteArgs);
    }

    /** @hide */
@@ -563,10 +571,13 @@ public class Process {
                                                  @Nullable String packageName,
                                                  @Nullable long[] disabledCompatChanges,
                                                  @Nullable String[] zygoteArgs) {
        // Webview zygote can't access app private data files, so doesn't need to know its data
        // info.
        return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    /*useUsapPool=*/ false, /*isTopApp=*/ false, disabledCompatChanges, zygoteArgs);
                    /*useUsapPool=*/ false, /*isTopApp=*/ false, disabledCompatChanges,
                    /* pkgDataInfoMap */ null, zygoteArgs);
    }

    /**
+33 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.pm.ApplicationInfo;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
@@ -39,6 +40,7 @@ import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/*package*/ class ZygoteStartFailedEx extends Exception {
@@ -310,6 +312,8 @@ public class ZygoteProcess {
     *                             started.
     * @param zygoteArgs Additional arguments to supply to the zygote process.
     * @param isTopApp Whether the process starts for high priority application.
     * @param pkgDataInfoMap Map from related package names to private data directory
     *                       volume UUID and inode number.
     *
     * @return An object that describes the result of the attempt to start the process.
     * @throws RuntimeException on fatal start failure
@@ -328,6 +332,8 @@ public class ZygoteProcess {
                                                  boolean useUsapPool,
                                                  boolean isTopApp,
                                                  @Nullable long[] disabledCompatChanges,
                                                  @Nullable Map<String, Pair<String, Long>>
                                                          pkgDataInfoMap,
                                                  @Nullable String[] zygoteArgs) {
        // TODO (chriswailes): Is there a better place to check this value?
        if (fetchUsapPoolEnabledPropWithMinInterval()) {
@@ -338,7 +344,8 @@ public class ZygoteProcess {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, useUsapPool, isTopApp, disabledCompatChanges, zygoteArgs);
                    packageName, useUsapPool, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
@@ -539,6 +546,8 @@ public class ZygoteProcess {
     * @param packageName null-ok the name of the package this process belongs to.
     * @param isTopApp Whether the process starts for high priority application.
     * @param disabledCompatChanges a list of disabled compat changes for the process being started.
     * @param pkgDataInfoMap Map from related package names to private data directory volume UUID
     *                       and inode number.
     * @param extraArgs Additional arguments to supply to the zygote process.
     * @return An object that describes the result of the attempt to start the process.
     * @throws ZygoteStartFailedEx if process start failed for any reason
@@ -559,6 +568,8 @@ public class ZygoteProcess {
                                                      boolean useUsapPool,
                                                      boolean isTopApp,
                                                      @Nullable long[] disabledCompatChanges,
                                                      @Nullable Map<String, Pair<String, Long>>
                                                              pkgDataInfoMap,
                                                      @Nullable String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<>();
@@ -635,6 +646,24 @@ public class ZygoteProcess {
        if (isTopApp) {
            argsForZygote.add(Zygote.START_AS_TOP_APP_ARG);
        }
        if (pkgDataInfoMap != null && pkgDataInfoMap.size() > 0) {
            StringBuilder sb = new StringBuilder();
            sb.append(Zygote.PKG_DATA_INFO_MAP);
            sb.append("=");
            boolean started = false;
            for (Map.Entry<String, Pair<String, Long>> entry : pkgDataInfoMap.entrySet()) {
                if (started) {
                    sb.append(',');
                }
                started = true;
                sb.append(entry.getKey());
                sb.append(',');
                sb.append(entry.getValue().first);
                sb.append(',');
                sb.append(entry.getValue().second);
            }
            argsForZygote.add(sb.toString());
        }

        if (disabledCompatChanges != null && disabledCompatChanges.length > 0) {
            StringBuilder sb = new StringBuilder();
@@ -1182,12 +1211,14 @@ public class ZygoteProcess {

        Process.ProcessStartResult result;
        try {
            // As app zygote is for generating isolated process, at the end it can't access
            // apps data, so doesn't need to its data info.
            result = startViaZygote(processClass, niceName, uid, gid,
                    gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
                    abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
                    true /* startChildZygote */, null /* packageName */,
                    false /* useUsapPool */, false /* isTopApp */,
                    null /* disabledCompatChanges */, extraArgs);
                    null /* disabledCompatChanges */, null /* pkgDataInfoMap */, extraArgs);
        } catch (ZygoteStartFailedEx ex) {
            throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
        }
+19 −7
Original line number Diff line number Diff line
@@ -151,6 +151,9 @@ public final class Zygote {
    /** Make the new process have top application priority. */
    public static final String START_AS_TOP_APP_ARG = "--is-top-app";

    /** List of packages with the same uid, and its app data info: volume uuid and inode. */
    public static final String PKG_DATA_INFO_MAP = "--pkg-data-info-map";

    /**
     * An extraArg passed when a zygote process is forking a child-zygote, specifying a name
     * in the abstract socket namespace. This socket name is what the new child zygote
@@ -254,6 +257,8 @@ public final class Zygote {
     * @param instructionSet null-ok the instruction set to use.
     * @param appDataDir null-ok the data directory of the app.
     * @param isTopApp true if the process is for top (high priority) application.
     * @param pkgDataInfoList A list that stores related packages and its app data
     * info: volume uuid and inode.
     *
     * @return 0 if this is the child, pid of the child
     * if this is the parent, or -1 on error.
@@ -261,12 +266,13 @@ public final class Zygote {
    static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
            int targetSdkVersion, boolean isTopApp) {
            int targetSdkVersion, boolean isTopApp, String[] pkgDataInfoList) {
        ZygoteHooks.preFork();

        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp);
                fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
                pkgDataInfoList);
        // Enable tracing as soon as possible for the child process.
        if (pid == 0) {
            Zygote.disableExecuteOnly(targetSdkVersion);
@@ -286,7 +292,7 @@ public final class Zygote {
    private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
            int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
            int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
            String appDataDir, boolean isTopApp);
            String appDataDir, boolean isTopApp, String[] pkgDataInfoList);

    /**
     * Specialize an unspecialized app process.  The current VM must have been started
@@ -309,12 +315,16 @@ public final class Zygote {
     * @param instructionSet null-ok  The instruction set to use.
     * @param appDataDir null-ok  The data directory of the app.
     * @param isTopApp  True if the process is for top (high priority) application.
     * @param pkgDataInfoList A list that stores related packages and its app data
     * info: volume uuid and inode.
     */
    private static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, int mountExternal, String seInfo, String niceName,
            boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp) {
            boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp,
            String[] pkgDataInfoList) {
        nativeSpecializeAppProcess(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
                niceName, startChildZygote, instructionSet, appDataDir, isTopApp);
                niceName, startChildZygote, instructionSet, appDataDir, isTopApp,
                pkgDataInfoList);

        // Enable tracing as soon as possible for the child process.
        Trace.setTracingEnabled(true, runtimeFlags);
@@ -336,7 +346,8 @@ public final class Zygote {

    private static native void nativeSpecializeAppProcess(int uid, int gid, int[] gids,
            int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
            boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp);
            boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp,
            String[] pkgDataInfoList);

    /**
     * Called to do any initialization before starting an application.
@@ -665,7 +676,8 @@ public final class Zygote {
            specializeAppProcess(args.mUid, args.mGid, args.mGids,
                                 args.mRuntimeFlags, rlimits, args.mMountExternal,
                                 args.mSeInfo, args.mNiceName, args.mStartChildZygote,
                                 args.mInstructionSet, args.mAppDataDir, args.mIsTopApp);
                                 args.mInstructionSet, args.mAppDataDir, args.mIsTopApp,
                                 args.mPkgDataInfoList);

            disableExecuteOnly(args.mTargetSdkVersion);

+8 −0
Original line number Diff line number Diff line
@@ -220,6 +220,12 @@ class ZygoteArguments {
     */
    long[] mDisabledCompatChanges = null;

    /**
     * A list that stores all related packages and its data info: volume uuid and inode.
     * Null if it does need to do app data isolation.
     */
    String[] mPkgDataInfoList;

    /**
     * Constructs instance and parses args
     *
@@ -437,6 +443,8 @@ class ZygoteArguments {
                for (int i = 0; i < length; i++) {
                    mDisabledCompatChanges[i] = Long.parseLong(params[i]);
                }
            } else if (arg.startsWith(Zygote.PKG_DATA_INFO_MAP)) {
                mPkgDataInfoList = getAssignmentList(arg);
            } else {
                break;
            }
+1 −1
Original line number Diff line number Diff line
@@ -258,7 +258,7 @@ class ZygoteConnection {
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion,
                parsedArgs.mIsTopApp);
                parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList);

        try {
            if (pid == 0) {
Loading