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
PhoneAccount
instances:CAPABILITY_SELF_MANAGED
: indicating that thisPhoneAccount
is 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
PhoneAccount
with theCAPABILITY_SELF_MANAGED
flag.
CAPABILITY_PLACE_EMERGENCY_CALLS
: indicating that thisPhoneAccount
is capable of placing emergency calls.Teams cannot handle emergency calling, so it does not register with the
CAPABILITY_PLACE_EMERGENCY_CALLS
flag.
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_CALLS
defined, e.g., those built by Teams.
sortSimPhoneAccountsForEmergency
: which sorts the list ofPhoneAccounts
in case there are multiple instances withCAPABILITY_PLACE_EMERGENCY_CALLS
defined because there must only be one emergency preferredPhoneAccount
on the deviceWhen comparing two
PhoneAccount
s, the method will, in the order as follows:checks which
PhoneAccount
supportsCAPABILITY_SIM_SUBSCRIPTION
, which is the “user-preferred” account, andwhich account is associated with a valid subscription ID and SIM slot index
If the two
PhoneAccount
instances 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
PhoneAccount
s to sort through, andother comparisons have likely succeeded at ranking the two
PhoneAccount
instances.
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
PhoneAccount
instance.Specifically, when the user is not signed in, a new, randomly generated UUID is used to create the
PhoneAccount
instance 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
PhoneAccount
instances created because the userId will be the same as the already registeredPhoneAccount
.Uninstalling and then reinstalling the app will clear all of the
PhoneAccount
instances it creates,which is one of the mitigation steps that Google recommends.
Therefore, an abundance of duplicate
PhoneAccount
instances 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
sortSimPhoneAccountsforEmergency
was 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
adjustAttemptsForEmergency
method to filter outPhoneAccount
instances that are self-managed, i.e., withCAPABILITY_SELF_MANAGED
defined.This will prevent
PhoneAccount
instances like the ones built by Teams from ever being passed to thesortSimPhoneAccountsforEmergency
method,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.