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

Commit 90a96507 authored by Andreas Gampe's avatar Andreas Gampe Committed by Android (Google) Code Review
Browse files

Merge "resolve merge conflicts of 9034b271 to master"

parents db1b3cfb 1185eebe
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@ package com.android.internal.os;

import android.os.Process;
import android.os.Trace;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.system.StructCapUserData;
import android.system.StructCapUserHeader;
import android.util.BootTimingsTraceLog;
import android.util.Slog;
import com.android.internal.os.Zygote.MethodAndArgsCaller;
@@ -122,6 +127,7 @@ public class WrapperInit {
        command.append(' ');
        command.append(targetSdkVersion);
        Zygote.appendQuotedShellArgs(command, args);
        preserveCapabilities();
        Zygote.execShell(command.toString());
    }

@@ -159,4 +165,57 @@ public class WrapperInit {

        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

    /**
     * Copy current capabilities to ambient capabilities. This is required for apps using
     * capabilities, as execv will re-evaluate the capability set, and the set of sh is
     * empty. Ambient capabilities have to be set to inherit them effectively.
     *
     * Note: This is BEST EFFORT ONLY. In case capabilities can't be raised, this function
     *       will silently return. In THIS CASE ONLY, as this is a development feature, it
     *       is better to return and try to run anyways, instead of blocking the wrapped app.
     *       This is acceptable here as failure will leave the wrapped app with strictly less
     *       capabilities, which may make it crash, but not exceed its allowances.
     */
    private static void preserveCapabilities() {
        StructCapUserHeader header = new StructCapUserHeader(
                OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
        StructCapUserData[] data;
        try {
            data = Os.capget(header);
        } catch (ErrnoException e) {
            Slog.e(RuntimeInit.TAG, "RuntimeInit: Failed capget", e);
            return;
        }

        if (data[0].permitted != data[0].inheritable ||
                data[1].permitted != data[1].inheritable) {
            data[0] = new StructCapUserData(data[0].effective, data[0].permitted,
                    data[0].permitted);
            data[1] = new StructCapUserData(data[1].effective, data[1].permitted,
                    data[1].permitted);
            try {
                Os.capset(header, data);
            } catch (ErrnoException e) {
                Slog.e(RuntimeInit.TAG, "RuntimeInit: Failed capset", e);
                return;
            }
        }

        for (int i = 0; i < 64; i++) {
            int dataIndex = OsConstants.CAP_TO_INDEX(i);
            int capMask = OsConstants.CAP_TO_MASK(i);
            if ((data[dataIndex].inheritable & capMask) != 0) {
                try {
                    Os.prctl(OsConstants.PR_CAP_AMBIENT, OsConstants.PR_CAP_AMBIENT_RAISE, i, 0,
                            0);
                } catch (ErrnoException ex) {
                    // Only log here. Try to run the wrapped application even without this
                    // ambient capability. It may crash after fork, but at least we'll try.
                    Slog.e(RuntimeInit.TAG, "RuntimeInit: Failed to raise ambient capability "
                            + i, ex);
                }
            }
        }
    }
}