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

Commit 2a3e00a6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Added calling uid check for get/setSmscAddress." into rvc-dev am: bbe9528f am: 252fd725

Change-Id: I434555778f4776647bf4f5106501334b8dca72bd
parents 394bc037 252fd725
Loading
Loading
Loading
Loading
+36 −26
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.Binder;
import android.service.carrier.CarrierMessagingService;
import android.service.carrier.CarrierMessagingService;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.VisibleForTesting;
import com.android.telephony.Rlog;
import com.android.telephony.Rlog;


/**
/**
@@ -138,21 +139,11 @@ public class SmsPermissions {
     */
     */
    public boolean checkCallingOrSelfCanGetSmscAddress(String callingPackage, String message) {
    public boolean checkCallingOrSelfCanGetSmscAddress(String callingPackage, String message) {
        // Allow it to the default SMS app always.
        // Allow it to the default SMS app always.
        if (!isDefaultSmsPackage(callingPackage)) {
        if (!isCallerDefaultSmsPackage(callingPackage)) {
            try {
                // Allow it with READ_PRIVILEGED_PHONE_STATE or Carrier Privileges
            TelephonyPermissions
            TelephonyPermissions
                        .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
                        .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
                                mContext, mPhone.getSubId(), message);
                                mContext, mPhone.getSubId(), message);
            } catch (SecurityException e) { // To avoid crashing applications
                loge(message + ": Neither " + callingPackage + " is the default SMS app"
                        + " nor the caller has "
                        + android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
                        + ", or carrier privileges", e);
                return false;
            }
        }
        }

        return true;
        return true;
    }
    }


@@ -167,26 +158,45 @@ public class SmsPermissions {
     */
     */
    public boolean checkCallingOrSelfCanSetSmscAddress(String callingPackage, String message) {
    public boolean checkCallingOrSelfCanSetSmscAddress(String callingPackage, String message) {
        // Allow it to the default SMS app always.
        // Allow it to the default SMS app always.
        if (!isDefaultSmsPackage(callingPackage)) {
        if (!isCallerDefaultSmsPackage(callingPackage)) {
            try {
            // Allow it with MODIFY_PHONE_STATE or Carrier Privileges
            // Allow it with MODIFY_PHONE_STATE or Carrier Privileges
            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                    mContext, mPhone.getSubId(), message);
                    mContext, mPhone.getSubId(), message);
            } catch (SecurityException e) { // To avoid crashing applications
                loge(message + ": Neither " + callingPackage + " is the default SMS app"
                        + " nor the caller has " + android.Manifest.permission.MODIFY_PHONE_STATE
                        + ", or carrier privileges", e);
                return false;
            }
        }
        }

        return true;
        return true;
    }
    }


    /** Check if a package is default SMS app. */
    /** Check if a package is default SMS app. */
    public boolean isDefaultSmsPackage(String packageName) {
    @VisibleForTesting
    public boolean isCallerDefaultSmsPackage(String packageName) {
        if (packageNameMatchesCallingUid(packageName)) {
            return SmsApplication.isDefaultSmsApplication(mContext, packageName);
            return SmsApplication.isDefaultSmsApplication(mContext, packageName);
        }
        }
        return false;
    }

    /**
     * Check if the passed in packageName belongs to the calling uid.
     * @param packageName name of the package to check
     * @return true if package belongs to calling uid, false otherwise
     */
    @VisibleForTesting
    public boolean packageNameMatchesCallingUid(String packageName) {
        try {
            if (Binder.getCallingUid()
                    != mContext.getPackageManager().getPackageUid(packageName, 0)) {
                Log.e(LOG_TAG, "packageNameMatchesCallingUid: " + packageName + " uid "
                        + mContext.getPackageManager().getPackageUid(packageName, 0)
                        + " does not match calling uid " + Binder.getCallingUid());
                return false;
            }
        } catch (PackageManager.NameNotFoundException ex) {
            Log.e(LOG_TAG, "packageNameMatchesCallingUid: packageName " + packageName
                    + " not found");
            return false;
        }
        return true;
    }


    @UnsupportedAppUsage
    @UnsupportedAppUsage
    protected void log(String msg) {
    protected void log(String msg) {
+47 −3
Original line number Original line Diff line number Diff line
@@ -21,13 +21,19 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;


import android.Manifest;
import android.Manifest;
import android.app.AppOpsManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Binder;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HandlerThread;
import android.util.Log;


import org.junit.After;
import org.junit.After;
import org.junit.Before;
import org.junit.Before;
@@ -76,7 +82,7 @@ public class SmsPermissionsTest extends TelephonyTest {
                }
                }


                @Override
                @Override
                public boolean isDefaultSmsPackage(String packageName) {
                public boolean isCallerDefaultSmsPackage(String packageName) {
                    return mCallerIsDefaultSmsPackage;
                    return mCallerIsDefaultSmsPackage;
                }
                }
            };
            };
@@ -205,7 +211,12 @@ public class SmsPermissionsTest extends TelephonyTest {
        Mockito.when(mMockContext.checkCallingOrSelfPermission(
        Mockito.when(mMockContext.checkCallingOrSelfPermission(
                    Manifest.permission.READ_PRIVILEGED_PHONE_STATE))
                    Manifest.permission.READ_PRIVILEGED_PHONE_STATE))
                .thenReturn(PERMISSION_DENIED);
                .thenReturn(PERMISSION_DENIED);
        assertFalse(mSmsPermissionsTest.checkCallingOrSelfCanGetSmscAddress(PACKAGE, MESSAGE));
        try {
            mSmsPermissionsTest.checkCallingOrSelfCanGetSmscAddress(PACKAGE, MESSAGE);
            fail();
        } catch (SecurityException e) {
            // expected
        }
    }
    }
    @Test
    @Test
    public void testCheckCallingOrSelfCanSetSmscAddressPermissions_defaultSmsApp() {
    public void testCheckCallingOrSelfCanSetSmscAddressPermissions_defaultSmsApp() {
@@ -231,6 +242,39 @@ public class SmsPermissionsTest extends TelephonyTest {
                mTelephonyManager);
                mTelephonyManager);
        Mockito.when(mMockContext.checkCallingOrSelfPermission(
        Mockito.when(mMockContext.checkCallingOrSelfPermission(
                Manifest.permission.MODIFY_PHONE_STATE)).thenReturn(PERMISSION_DENIED);
                Manifest.permission.MODIFY_PHONE_STATE)).thenReturn(PERMISSION_DENIED);
        try {
            assertFalse(mSmsPermissionsTest.checkCallingOrSelfCanSetSmscAddress(PACKAGE, MESSAGE));
            assertFalse(mSmsPermissionsTest.checkCallingOrSelfCanSetSmscAddress(PACKAGE, MESSAGE));
            fail();
        } catch (SecurityException e) {
            // expected
        }
    }

    @Test
    public void testPackageNameMatchesCallingUid() {
        PackageManager mockPackageManager = mock(PackageManager.class);
        doReturn(mockPackageManager).when(mMockContext).getPackageManager();

        // test matching case
        try {
            doReturn(Binder.getCallingUid()).when(mockPackageManager)
                    .getPackageUid(eq(PACKAGE), anyInt());
        } catch (Exception e) {
            Log.e(TAG, "testPackageNameMatchesCallingUid: unable to setup mocks");
            fail();
        }
        assertTrue(new SmsPermissions(mMockPhone, mMockContext, mMockAppOps)
                .packageNameMatchesCallingUid(PACKAGE));

        // test mis-match case
        try {
            doReturn(Binder.getCallingUid() + 1).when(mockPackageManager)
                    .getPackageUid(eq(PACKAGE), anyInt());
        } catch (Exception e) {
            Log.e(TAG, "testPackageNameMatchesCallingUid: unable to setup mocks");
            fail();
        }
        assertFalse(new SmsPermissions(mMockPhone, mMockContext, mMockAppOps)
                .packageNameMatchesCallingUid(PACKAGE));
    }
    }
}
}