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

Unverified Commit 23ec702f authored by Kevin F. Haggerty's avatar Kevin F. Haggerty
Browse files

Merge tag 'android-security-9.0.0_r70' into staging/lineage-16.0_merge_android-security-9.0.0_r70

Android security 9.0.0 release 70

* tag 'android-security-9.0.0_r70':
  Restrict alarm broadcast
  Fix the security issue that preloaded apps can get SSID & BSSID
  Detects all activities for whether showing work challenge

Change-Id: I1f2e95fbf3d9fbf34ae52a5ab41d76fcfb48b829
parents 83510e36 6f4c6abf
Loading
Loading
Loading
Loading
+9 −28
Original line number Original line Diff line number Diff line
@@ -863,27 +863,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    }
    }


    /**
    /**
     * Detects whether we should show a lock screen in front of this task for a locked user.
     * Find all task stacks containing {@param userId} and intercept them with an activity
     * <p>
     * We'll do this if either of the following holds:
     * <ul>
     *   <li>The top activity explicitly belongs to {@param userId}.</li>
     *   <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
     * </ul>
     *
     * @return {@code true} if the top activity looks like it belongs to {@param userId}.
     */
    private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) {
        // To handle the case that work app is in the task but just is not the top one.
        final ActivityRecord activityRecord = task.getTopActivity();
        final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);

        return (activityRecord != null && activityRecord.userId == userId)
                || (resultTo != null && resultTo.userId == userId);
    }

    /**
     * Find all visible task stacks containing {@param userId} and intercept them with an activity
     * to block out the contents and possibly start a credential-confirming intent.
     * to block out the contents and possibly start a credential-confirming intent.
     *
     *
     * @param userId user handle for the locked managed profile.
     * @param userId user handle for the locked managed profile.
@@ -898,13 +878,14 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                    final List<TaskRecord> tasks = stack.getAllTasks();
                    final List<TaskRecord> tasks = stack.getAllTasks();
                    for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
                    for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
                        final TaskRecord task = tasks.get(taskNdx);
                        final TaskRecord task = tasks.get(taskNdx);

                        for (int activityNdx = task.mActivities.size() - 1; activityNdx >= 0;
                        // Check the task for a top activity belonging to userId, or returning a
                                activityNdx--) {
                        // result to an activity belonging to userId. Example case: a document
                            final ActivityRecord activity = task.mActivities.get(activityNdx);
                        // picker for personal files, opened by a work app, should still get locked.
                            if (!activity.finishing && activity.userId == userId) {
                        if (taskTopActivityIsUser(task, userId)) {
                                mService.mTaskChangeNotificationController.notifyTaskProfileLocked(
                                mService.mTaskChangeNotificationController.notifyTaskProfileLocked(
                                        task.taskId, userId);
                                        task.taskId, userId);
                                break;
                            }
                        }
                        }
                    }
                    }
                }
                }
+0 −110
Original line number Original line Diff line number Diff line
@@ -45,22 +45,12 @@ import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.metrics.NetworkEvent;
import android.net.metrics.ValidationProbeEvent;
import android.net.metrics.ValidationProbeEvent;
import android.net.util.Stopwatch;
import android.net.util.Stopwatch;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Handler;
import android.os.Message;
import android.os.Message;
import android.os.SystemClock;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.LocalLog;
@@ -888,10 +878,6 @@ public class NetworkMonitor extends StateMachine {
        return mSettings.getSetting(mContext, Settings.Global.CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
        return mSettings.getSetting(mContext, Settings.Global.CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
    }
    }


    public boolean getWifiScansAlwaysAvailableDisabled() {
        return mSettings.getSetting(mContext, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0;
    }

    private String getCaptivePortalServerHttpsUrl() {
    private String getCaptivePortalServerHttpsUrl() {
        return mSettings.getSetting(mContext,
        return mSettings.getSetting(mContext,
                Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL);
                Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL);
@@ -1028,10 +1014,6 @@ public class NetworkMonitor extends StateMachine {


        long endTime = SystemClock.elapsedRealtime();
        long endTime = SystemClock.elapsedRealtime();


        sendNetworkConditionsBroadcast(true /* response received */,
                result.isPortal() /* isCaptivePortal */,
                startTime, endTime);

        return result;
        return result;
    }
    }


@@ -1269,98 +1251,6 @@ public class NetworkMonitor extends StateMachine {
        return null;
        return null;
    }
    }


    /**
     * @param responseReceived - whether or not we received a valid HTTP response to our request.
     * If false, isCaptivePortal and responseTimestampMs are ignored
     * TODO: This should be moved to the transports.  The latency could be passed to the transports
     * along with the captive portal result.  Currently the TYPE_MOBILE broadcasts appear unused so
     * perhaps this could just be added to the WiFi transport only.
     */
    private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
            long requestTimestampMs, long responseTimestampMs) {
        if (getWifiScansAlwaysAvailableDisabled()) {
            return;
        }

        if (!systemReady) {
            return;
        }

        Intent latencyBroadcast =
                new Intent(ConnectivityConstants.ACTION_NETWORK_CONDITIONS_MEASURED);
        switch (mNetworkAgentInfo.networkInfo.getType()) {
            case ConnectivityManager.TYPE_WIFI:
                WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
                if (currentWifiInfo != null) {
                    // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not
                    // surrounded by double quotation marks (thus violating the Javadoc), but this
                    // was changed to match the Javadoc in API 17. Since clients may have started
                    // sanitizing the output of this method since API 17 was released, we should
                    // not change it here as it would become impossible to tell whether the SSID is
                    // simply being surrounded by quotes due to the API, or whether those quotes
                    // are actually part of the SSID.
                    latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_SSID,
                            currentWifiInfo.getSSID());
                    latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_BSSID,
                            currentWifiInfo.getBSSID());
                } else {
                    if (VDBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
                    return;
                }
                break;
            case ConnectivityManager.TYPE_MOBILE:
                latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_NETWORK_TYPE,
                        mTelephonyManager.getNetworkType());
                List<CellInfo> info = mTelephonyManager.getAllCellInfo();
                if (info == null) return;
                int numRegisteredCellInfo = 0;
                for (CellInfo cellInfo : info) {
                    if (cellInfo.isRegistered()) {
                        numRegisteredCellInfo++;
                        if (numRegisteredCellInfo > 1) {
                            if (VDBG) logw("more than one registered CellInfo." +
                                    " Can't tell which is active.  Bailing.");
                            return;
                        }
                        if (cellInfo instanceof CellInfoCdma) {
                            CellIdentityCdma cellId = ((CellInfoCdma) cellInfo).getCellIdentity();
                            latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_CELL_ID, cellId);
                        } else if (cellInfo instanceof CellInfoGsm) {
                            CellIdentityGsm cellId = ((CellInfoGsm) cellInfo).getCellIdentity();
                            latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_CELL_ID, cellId);
                        } else if (cellInfo instanceof CellInfoLte) {
                            CellIdentityLte cellId = ((CellInfoLte) cellInfo).getCellIdentity();
                            latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_CELL_ID, cellId);
                        } else if (cellInfo instanceof CellInfoWcdma) {
                            CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity();
                            latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_CELL_ID, cellId);
                        } else {
                            if (VDBG) logw("Registered cellinfo is unrecognized");
                            return;
                        }
                    }
                }
                break;
            default:
                return;
        }
        latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_CONNECTIVITY_TYPE,
                mNetworkAgentInfo.networkInfo.getType());
        latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_RESPONSE_RECEIVED,
                responseReceived);
        latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_REQUEST_TIMESTAMP_MS,
                requestTimestampMs);

        if (responseReceived) {
            latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_IS_CAPTIVE_PORTAL,
                    isCaptivePortal);
            latencyBroadcast.putExtra(ConnectivityConstants.EXTRA_RESPONSE_TIMESTAMP_MS,
                    responseTimestampMs);
        }
        mContext.sendBroadcastAsUser(latencyBroadcast, UserHandle.CURRENT,
                ConnectivityConstants.PERMISSION_ACCESS_NETWORK_CONDITIONS);
    }

    private void logNetworkEvent(int evtype) {
    private void logNetworkEvent(int evtype) {
        int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes();
        int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes();
        mMetricsLog.log(mNetId, transports, new NetworkEvent(evtype));
        mMetricsLog.log(mNetId, transports, new NetworkEvent(evtype));
+2 −0
Original line number Original line Diff line number Diff line
@@ -210,6 +210,7 @@ import com.android.server.lights.LightsManager;
import com.android.server.notification.ManagedServices.ManagedServiceInfo;
import com.android.server.notification.ManagedServices.ManagedServiceInfo;
import com.android.server.notification.ManagedServices.UserProfiles;
import com.android.server.notification.ManagedServices.UserProfiles;
import com.android.server.policy.PhoneWindowManager;
import com.android.server.policy.PhoneWindowManager;
import com.android.server.pm.PackageManagerService;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal;


@@ -4857,6 +4858,7 @@ public class NotificationManagerService extends SystemService {
            final PendingIntent pi = PendingIntent.getBroadcast(getContext(),
            final PendingIntent pi = PendingIntent.getBroadcast(getContext(),
                    REQUEST_CODE_TIMEOUT,
                    REQUEST_CODE_TIMEOUT,
                    new Intent(ACTION_NOTIFICATION_TIMEOUT)
                    new Intent(ACTION_NOTIFICATION_TIMEOUT)
                            .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
                            .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT)
                            .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT)
                                    .appendPath(record.getKey()).build())
                                    .appendPath(record.getKey()).build())
                            .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
                            .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+32 −2
Original line number Original line Diff line number Diff line
@@ -27,8 +27,7 @@ import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;


import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.am.ActivityStackSupervisor
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
        .MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertFalse;
@@ -46,6 +45,8 @@ import static org.mockito.Mockito.verify;
import android.app.ActivityOptions;
import android.app.ActivityOptions;
import android.app.WaitResult;
import android.app.WaitResult;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.MediumTest;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.runner.AndroidJUnit4;
@@ -407,4 +408,33 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
        // Assert that the primary stack is returned.
        // Assert that the primary stack is returned.
        assertEquals(primaryStack, result);
        assertEquals(primaryStack, result);
    }
    }

    @Test
    public void testLockAllProfileTasks() throws Exception {
        // Make an activity visible with the user id set to 1
        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(mFullscreenStack).build();
        final ActivityRecord activity = new ActivityBuilder(mService).setTask(task)
                .setUid(UserHandle.PER_USER_RANGE + 1).build();

        // Create another activity on top and the user id is 2
        final ActivityRecord topActivity = new ActivityBuilder(mService)
                .setTask(task).setUid(UserHandle.PER_USER_RANGE + 2).build();

        // Make sure the listeners will be notified for putting the task to locked state
        LocalTaskStackListener listener = new LocalTaskStackListener();
        mService.registerTaskStackListener(listener);
        mService.mStackSupervisor.lockAllProfileTasks(1);
        assertTrue(listener.mTaskProfileLocked);
        mService.unregisterTaskStackListener(listener);
    }

    private class LocalTaskStackListener extends android.app.TaskStackListener {
        boolean mTaskProfileLocked;

        @Override
        public void onTaskProfileLocked(int taskId, int userId) throws RemoteException {
            super.onTaskProfileLocked(taskId, userId);
            mTaskProfileLocked = true;
        }
    }
}
}
+27 −0
Original line number Original line Diff line number Diff line
@@ -64,6 +64,7 @@ import static org.mockito.Mockito.when;


import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.IActivityManager;
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.Notification;
@@ -71,6 +72,7 @@ import android.app.Notification.MessagingStyle.Message;
import android.app.NotificationChannel;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.usage.UsageStatsManagerInternal;
import android.app.usage.UsageStatsManagerInternal;
@@ -120,6 +122,7 @@ import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
import com.android.server.lights.LightsManager;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
import com.android.server.pm.PackageManagerService;


import org.junit.After;
import org.junit.After;
import org.junit.Before;
import org.junit.Before;
@@ -190,6 +193,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    IBinder mPermOwner;
    IBinder mPermOwner;
    @Mock
    @Mock
    IActivityManager mAm;
    IActivityManager mAm;
    @Mock
    AlarmManager mAlarmManager;


    // Use a Testable subclass so we can simulate calls from the system without failing.
    // Use a Testable subclass so we can simulate calls from the system without failing.
    private static class TestableNotificationManagerService extends NotificationManagerService {
    private static class TestableNotificationManagerService extends NotificationManagerService {
@@ -236,6 +241,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                Secure.NOTIFICATION_BADGING, 1,
                Secure.NOTIFICATION_BADGING, 1,
                UserHandle.getUserHandleForUid(mUid).getIdentifier());
                UserHandle.getUserHandleForUid(mUid).getIdentifier());


        mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager);

        mService = new TestableNotificationManagerService(mContext);
        mService = new TestableNotificationManagerService(mContext);


        // Use this testable looper.
        // Use this testable looper.
@@ -391,6 +398,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        return answers;
        return answers;
    }
    }


    @Test
    public void testLimitTimeOutBroadcast() {
        NotificationChannel channel = new NotificationChannel("id", "name",
                NotificationManager.IMPORTANCE_HIGH);
        Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
                .setContentTitle("foo")
                .setSmallIcon(android.R.drawable.sym_def_app_icon)
                .setTimeoutAfter(1);

        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        NotificationRecord r = new NotificationRecord(mContext, sbn, channel);

        mService.scheduleTimeoutLocked(r);
        ArgumentCaptor<PendingIntent> captor = ArgumentCaptor.forClass(PendingIntent.class);
        verify(mAlarmManager).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture());
        assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME,
                captor.getValue().getIntent().getPackage());
    }

    @Test
    @Test
    public void testCreateNotificationChannels_SingleChannel() throws Exception {
    public void testCreateNotificationChannels_SingleChannel() throws Exception {
        final NotificationChannel channel =
        final NotificationChannel channel =