Web Excursions 2021-12-11
Many Android apps with phone calling functionality build an instance of
PhoneAccount, including the Microsoft Teams app.Relevant here are two flags of
PhoneAccountinstances:CAPABILITY_SELF_MANAGED: indicating that thisPhoneAccountis responsible for managing its own Connections, i.e., a phone call or connection to a remote endpoint that carries voice and/or video traffic.Teams uses its own Skype backend to make phone calls, so it registers a
PhoneAccountwith theCAPABILITY_SELF_MANAGEDflag.
CAPABILITY_PLACE_EMERGENCY_CALLS: indicating that thisPhoneAccountis capable of placing emergency calls.Teams cannot handle emergency calling, so it does not register with the
CAPABILITY_PLACE_EMERGENCY_CALLSflag.
When dealing with emergency calls, Android uses, among others, two methods:
adjustAttemptsForEmergency: which gets a list of all registered instances of PhoneAccount and then the “user-preferred” one, i.e., the instance that should handle emergency calls.…but it has a flaw that it gets all registered instances of
PhoneAccount,including those without
CAPABILITY_PLACE_EMERGENCY_CALLSdefined, e.g., those built by Teams.
sortSimPhoneAccountsForEmergency: which sorts the list ofPhoneAccountsin case there are multiple instances withCAPABILITY_PLACE_EMERGENCY_CALLSdefined because there must only be one emergency preferredPhoneAccounton the deviceWhen comparing two
PhoneAccounts, the method will, in the order as follows:checks which
PhoneAccountsupportsCAPABILITY_SIM_SUBSCRIPTION, which is the “user-preferred” account, andwhich account is associated with a valid subscription ID and SIM slot index
If the two
PhoneAccountinstances being compared are the same, order the list by package name, label, and finally, by hashcode
…but it also has a flaw that when comparing hascodes, it simply conduct a subtraction
account1.hashCode() — account2.hashCode(),which may result in an integer overflow if the return value is out of (
Integer.MIN_VALUE,Integer.MAX_VALUE), i.e., (-2^31, +2^31-1).
Ususally, the chances of this mathematical calculation actually resulting in an integer overflow/underflow is really, really low because
There usually aren’t that many
PhoneAccounts to sort through, andother comparisons have likely succeeded at ranking the two
PhoneAccountinstances.
Unfortunately, Teams has a bug that when it is installed but the user has not signed in, every cold launch of the app results in the creation of another
PhoneAccountinstance.Specifically, when the user is not signed in, a new, randomly generated UUID is used to create the
PhoneAccountinstance that gets added to Android’sTelecomManager.Because Teams has a boot broadcast receiver, this also happens every time the phone is rebooted.
Users that have logged into the Teams app won’t have duplicate
PhoneAccountinstances created because the userId will be the same as the already registeredPhoneAccount.Uninstalling and then reinstalling the app will clear all of the
PhoneAccountinstances it creates,which is one of the mitigation steps that Google recommends.
Therefore, an abundance of duplicate
PhoneAccountinstances raises the possibility of triggering an integer overflow/underflow error when the user attempts to make an emergency call.It has not been determined and requires further analysis that whether or not the integer overflow/underflow error is the exact step where everything goes wrong.
This bug only affects Android devices running Android 10+ because
Teams app only registers PhoneAccounts if it’s running on API level 28+ (Android 9 Pie and later), and
the problematic implementation of
sortSimPhoneAccountsforEmergencywas committed to AOSP in mid-2019 and was included in the android10-release branch.
Several fixes are on the way and some were actually submitted before the incident:
On Nov 26, a Samsung engineer submitted a code change titled “fix the integer overflow/underflow caused by sorting of duplicate phoneaccounts during emergency call attempt” which apparently resolved exactly this issue.
This code change replaces the simple subtraction used to compare hashcodes with Integer.compare, which only returns -1, 0, or 1.
On Dec 9, a Googler submitted another code change that adds new lines to the
adjustAttemptsForEmergencymethod to filter outPhoneAccountinstances that are self-managed, i.e., withCAPABILITY_SELF_MANAGEDdefined.This will prevent
PhoneAccountinstances like the ones built by Teams from ever being passed to thesortSimPhoneAccountsforEmergencymethod,which is sensible since only the default phone service should handle emergency calls.
Microsoft will be rolling out a new version of Teams that will likely resolve the issue with duplicate PhoneAccount instances being created.
