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

Commit 558b0dd4 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by android-build-merger
Browse files

Consistent dump() permission checking. am: fe9a53bc

am: 020de028

Change-Id: Iffbf78a7b48cea41ed4b0763f2452738e084225c
parents 5b01105c 020de028
Loading
Loading
Loading
Loading
+94 −0
Original line number Diff line number Diff line
@@ -16,7 +16,12 @@

package com.android.internal.util;

import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Handler;
import android.util.Slog;

import java.io.PrintWriter;
import java.io.StringWriter;
@@ -25,6 +30,9 @@ import java.io.StringWriter;
 * Helper functions for dumping the state of system services.
 */
public final class DumpUtils {
    private static final String TAG = "DumpUtils";
    private static final boolean DEBUG = true;

    private DumpUtils() {
    }

@@ -55,4 +63,90 @@ public final class DumpUtils {
    public interface Dump {
        void dump(PrintWriter pw, String prefix);
    }

    private static void logMessage(PrintWriter pw, String msg) {
        if (DEBUG) Slog.v(TAG, msg);
        pw.println(msg);
    }

    /**
     * Verify that caller holds {@link android.Manifest.permission#DUMP}.
     *
     * @return true if access should be granted.
     * @hide
     */
    public static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
        if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
                    + " due to missing android.permission.DUMP permission");
            return false;
        } else {
            return true;
        }
    }

    /**
     * Verify that caller holds
     * {@link android.Manifest.permission#PACKAGE_USAGE_STATS} and that they
     * have {@link AppOpsManager#OP_GET_USAGE_STATS} access.
     *
     * @return true if access should be granted.
     * @hide
     */
    public static boolean checkUsageStatsPermission(Context context, String tag, PrintWriter pw) {
        // System internals always get access
        final int uid = Binder.getCallingUid();
        switch (uid) {
            case android.os.Process.ROOT_UID:
            case android.os.Process.SYSTEM_UID:
            case android.os.Process.SHELL_UID:
                return true;
        }

        // Caller always needs to hold permission
        if (context.checkCallingOrSelfPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
                != PackageManager.PERMISSION_GRANTED) {
            logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
                    + " due to missing android.permission.PACKAGE_USAGE_STATS permission");
            return false;
        }

        // And finally, caller needs to have appops access; this is totally
        // hacky, but it's the easiest way to wire this up without retrofitting
        // Binder.dump() to pass through package names.
        final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
        final String[] pkgs = context.getPackageManager().getPackagesForUid(uid);
        if (pkgs != null) {
            for (String pkg : pkgs) {
                if (appOps.checkOpNoThrow(AppOpsManager.OP_GET_USAGE_STATS, uid,
                        pkg) == AppOpsManager.MODE_ALLOWED) {
                    appOps.noteOp(AppOpsManager.OP_GET_USAGE_STATS, uid, pkg);
                    if (DEBUG) Slog.v(TAG, "Found package " + pkg + " with "
                                + "android:get_usage_stats access");
                    return true;
                }
            }
        }

        logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
                + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
                + " due to android:get_usage_stats app-op not allowed");
        return false;
    }

    /**
     * Verify that caller holds both {@link android.Manifest.permission#DUMP}
     * and {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, and that
     * they have {@link AppOpsManager#OP_GET_USAGE_STATS} access.
     *
     * @return true if access should be granted.
     * @hide
     */
    public static boolean checkDumpAndUsageStatsPermission(Context context, String tag,
            PrintWriter pw) {
        return checkDumpPermission(context, tag, pw) && checkUsageStatsPermission(context, tag, pw);
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IntPair;
import com.android.server.LocalServices;
import com.android.server.policy.AccessibilityShortcutController;
@@ -2360,7 +2361,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {

    @Override
    public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
        mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
        if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
        synchronized (mLock) {
            pw.println("ACCESSIBILITY MANAGER (dumpsys accessibility)");
            pw.println();
@@ -3658,7 +3659,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {

        @Override
        public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
            mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
            if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
            synchronized (mLock) {
                pw.append("Service[label=" + mAccessibilityServiceInfo.getResolveInfo()
                        .loadLabel(mContext.getPackageManager()));
+2 −4
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ import com.android.internal.appwidget.IAppWidgetHost;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.widget.IRemoteViewsAdapterConnection;
import com.android.internal.widget.IRemoteViewsFactory;
@@ -714,10 +715,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
                                                "Permission Denial: can't dump from from pid="
                                                + Binder.getCallingPid()
                                                + ", uid=" + Binder.getCallingUid());
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;

        synchronized (mLock) {
            if (args.length > 0 && "--proto".equals(args[0])) {
+2 −7
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.view.autofill.IAutoFillManagerClient;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -418,13 +419,7 @@ public final class AutofillManagerService extends SystemService {

        @Override
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            if (mContext.checkCallingPermission(
                    Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
                pw.println("Permission Denial: can't dump autofill from from pid="
                        + Binder.getCallingPid()
                        + ", uid=" + Binder.getCallingUid());
                return;
            }
            if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
            synchronized (mLock) {
                pw.print("Disabled users: "); pw.println(mDisabledUsers);
                final int size = mServicesCache.size();
+2 −1
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ import android.util.StringBuilderPrinter;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.backup.IBackupTransport;
import com.android.internal.backup.IObbBackupService;
import com.android.internal.util.DumpUtils;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.SystemConfig;
@@ -11138,7 +11139,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
    }
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
        long identityToken = Binder.clearCallingIdentity();
        try {
Loading