2023.09.06
CVE-2021-39659 | A-208267659 | DoS | 高 | 10、11、12 |
---|---|---|---|---|
patch
Fix sorting issue during emergency call attempt.
Fix the integer overflow/underflow caused by sorting of duplicate phoneaccounts during emergency call attempt.

分析
是我孤陋寡闻了,以前没注意过Java还会整数溢出:
Java的int是32位有符号整数类型,其最大值是0x7fffffff,最小值则是0x80000000,和C语言一样。即int表示的数的范围是-2147483648 ~ 2147483647之间。
下面的代码会根据package、label和hashcode等进行排序,但是在根据hashcode排序的时候,直接返回account1.hashCode() - account2.hashCode()
,这就可能导致整数上溢/下溢,从而导致排序出错。
// hashCode 返回的是int类型的值
public int hashCode()
比如:
account1.hashCode() < account2.hashCode()
,但是两者相减可能导致整数下溢,返回正数(表示前者大于后者,与真实情况不符)- 极端情况举例:
Integer.MIN_VALUE - 1 == 2147483647
- 极端情况举例:
account1.hashCode() > account2.hashCode()
,但是两者相加可能导致整数上溢,返回负数(表示前者小于后者,与真实情况不符)- 极端情况举例:
Integer.MAX_VALUE + 1 == -2147483648
- 极端情况举例:
public void sortSimPhoneAccountsForEmergency(List<PhoneAccount> accounts,
PhoneAccount userPreferredAccount) {
// Sort the accounts according to how we want to display them (ascending order).
accounts.sort((account1, account2) -> {
......
// Then order by package
String pkg1 = account1.getAccountHandle().getComponentName().getPackageName();
String pkg2 = account2.getAccountHandle().getComponentName().getPackageName();
retval = pkg1.compareTo(pkg2);
if (retval != 0) {
return retval;
}
// then order by label
String label1 = nullToEmpty(account1.getLabel().toString());
String label2 = nullToEmpty(account2.getLabel().toString());
retval = label1.compareTo(label2);
if (retval != 0) {
return retval;
}
// then by hashcode
return account1.hashCode() - account2.hashCode(); // 漏洞点
});
}
private static String nullToEmpty(String str) {
return str == null ? "" : str;
}
}
