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

Commit 22487777 authored by Ashish Kumar Gaurav's avatar Ashish Kumar Gaurav Committed by Android (Google) Code Review
Browse files

Merge "Added logging of cases where getType is called without readPermission using westworld atom"

parents ee9312df 0ac7f422
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.os.Process.myUserHandle;
import static android.os.Trace.TRACE_TAG_DATABASE;

import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION;
import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_CHECK_URI_PERMISSION;
import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_ERROR;
import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_FRAMEWORK_PERMISSION;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -58,6 +63,7 @@ import android.util.Log;
import android.util.SparseBooleanArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;

import java.io.File;
import java.io.FileDescriptor;
@@ -300,7 +306,11 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            uri = maybeGetUriWithoutUserId(uri);
            traceBegin(TRACE_TAG_DATABASE, "getType: ", uri.getAuthority());
            try {
                return mInterface.getType(uri);
                final String type = mInterface.getType(uri);
                if (type != null) {
                    logGetTypeData(Binder.getCallingUid(), uri, type);
                }
                return type;
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
@@ -308,6 +318,48 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            }
        }

        // Utility function to log the getTypeData calls
        private void logGetTypeData(int callingUid, Uri uri, String type) {
            final int enumFrameworkPermission =
                    GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_FRAMEWORK_PERMISSION;
            final int enumCheckUriPermission =
                    GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_CHECK_URI_PERMISSION;
            final int enumError = GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_ERROR;

            try {
                final AttributionSource attributionSource = new AttributionSource.Builder(
                        callingUid).build();
                try {
                    if (enforceReadPermission(attributionSource, uri)
                            != PermissionChecker.PERMISSION_GRANTED) {
                        FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION,
                                enumFrameworkPermission,
                                callingUid, uri.getAuthority(), type);
                    } else {
                        final ProviderInfo cpi = mContext.getPackageManager()
                                .resolveContentProvider(uri.getAuthority(),
                                PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA));
                        if (cpi.forceUriPermissions
                                && mInterface.checkUriPermission(uri,
                                callingUid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
                                != PermissionChecker.PERMISSION_GRANTED) {
                            FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION,
                                    enumCheckUriPermission,
                                    callingUid, uri.getAuthority(), type);
                        }
                    }
                } catch (SecurityException e) {
                    FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION,
                            enumFrameworkPermission,
                            callingUid, uri.getAuthority(), type);
                }
            } catch (Exception e) {
                FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION,
                        enumError,
                        callingUid, uri.getAuthority(), type);
            }
        }

        @Override
        public void getTypeAsync(Uri uri, RemoteCallback callback) {
            final Bundle result = new Bundle();
+71 −1
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ import static android.os.Process.PROC_PARENS;
import static android.os.Process.PROC_SPACE_TERM;
import static android.os.Process.SYSTEM_UID;

import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION;
import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__AM_CHECK_URI_PERMISSION;
import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__AM_ERROR;
import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__AM_FRAMEWORK_PERMISSION;
import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_EVENT_REPORTED;
import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD;
import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM;
@@ -46,6 +50,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -1003,7 +1008,11 @@ public class ContentProviderHelper {
                };
                mService.mHandler.postDelayed(providerNotResponding, 1000);
                try {
                    return holder.provider.getType(uri);
                    final String type = holder.provider.getType(uri);
                    if (type != null) {
                        backgroundLogging(callingUid, callingPid, userId, uri, holder, type);
                    }
                    return type;
                } finally {
                    mService.mHandler.removeCallbacks(providerNotResponding);
                    // We need to clear the identity to call removeContentProviderExternalUnchecked
@@ -1060,6 +1069,10 @@ public class ContentProviderHelper {
                        Binder.restoreCallingIdentity(identity);
                    }
                    resultCallback.sendResult(result);
                    final String type = result.getPairValue();
                    if (type != null) {
                        backgroundLogging(callingUid, callingPid, userId, uri, holder, type);
                    }
                }));
            } else {
                resultCallback.sendResult(Bundle.EMPTY);
@@ -1070,6 +1083,63 @@ public class ContentProviderHelper {
        }
    }

    private void backgroundLogging(int callingUid, int callingPid, int userId, Uri uri,
            ContentProviderHolder holder, String type) {
        // Push the logging code in a different handlerThread.
        try {
            mService.mHandler.post(new Runnable() {
                @Override
                public void run() {
                    logGetTypeData(callingUid, callingPid, userId,
                            uri, holder, type);
                }
            });
        } catch (Exception e) {
            // To ensure logging does not break the getType calls.
        }
    }

    // Utility function to log the getTypeData calls
    private void logGetTypeData(int callingUid, int callingPid, int userId, Uri uri,
            ContentProviderHolder holder, String type) {
        try {
            boolean checkUser = true;
            final String authority = uri.getAuthority();
            if (isAuthorityRedirectedForCloneProfile(authority)) {
                UserManagerInternal umInternal =
                        LocalServices.getService(UserManagerInternal.class);
                UserInfo userInfo = umInternal.getUserInfo(userId);

                if (userInfo != null && userInfo.isCloneProfile()) {
                    userId = umInternal.getProfileParentId(userId);
                    checkUser = false;
                }
            }
            final ProviderInfo cpi = holder.info;
            final AttributionSource attributionSource =
                    new AttributionSource.Builder(callingUid).build();
            final String permissionCheck =
                    checkContentProviderPermission(cpi, callingPid, callingUid,
                            userId, checkUser, null);
            if (permissionCheck != null) {
                FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION,
                        GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__AM_FRAMEWORK_PERMISSION,
                        callingUid, authority, type);
            } else if (cpi.forceUriPermissions
                    && holder.provider.checkUriPermission(attributionSource,
                            uri, callingUid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
                            != PermissionChecker.PERMISSION_GRANTED) {
                FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION,
                        GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__AM_CHECK_URI_PERMISSION,
                        callingUid, authority, type);
            }
        } catch (Exception e) {
            FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION,
                    GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__AM_ERROR, callingUid,
                    uri.getAuthority(), type);
        }
    }

    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
        if (UserHandle.getUserId(callingUid) == userId) {
            return true;