A Double-Free Vulnerability in International Components for Unicode (ICU)

International Components for Unicode (ICU), also known as libicu, is an open source project of mature C/C++ and Java libraries for Unicode support, software internationalization, and software globalization. It is widely portable to many operating systems and environments. It is used in hundreds of companies and organizations including Google, Apple, Microsoft, IBM, many car brands like Audi, BMW, etc. [ 1 ]

Our code scanner found a double-free vulnerability in this widely used library about a month ago. This double-free vulnerability has been hidden in the library for more than 10 years, affecting all current release versions (<= ICU 59.1). Now, it has been fixed in trunk [ 2 ].


As shown in Figure 1, this double-free vulnerability occurs in function ZoneMeta::createMetazoneMappings in file icu/i18n/zonemeta.cpp.

icu1

Figure 1

As shown in the above code, when current ‘status’ is marked as FAILURE, there are two operations on the variable ‘entry’. One is deleteOlsonToMetaMappingEntry(entry) and the other is uprv_free(entry). 

Figure 2

Figure 2

Looking into the function deleteOlsonToMetaMappingEntry (Figure 2), we observe that it actually does nothing except calling the function uprv_free again, which leads to a double-free vulnerability. A direct exploit of this vulnerability is a denial-of-service attack that makes a system crash with this double-free:

icu 3

Figure 3

Now, let’s see when this double-free can happen, i.e., when the variable ‘status’ is marked as FAILURE. As shown at the first line in Figure 1, ‘status’ may be changed in the constructor of class UVector, which contains the following code (Figure 4):

icu 4

Figure 4

This code snippet shows that the status becomes FAILURE when uprv_malloc() returns a null pointer, i.e., an out-of-memory exception happens. Although this seems improbable to happen in modern large servers, considering ICU is widely used in different application scenarios, we argue that it definitely can happen in following environments:

1.      In big-data era, it is quite possible in applications where large amounts of data are processed.

2.      This is quite possible in embedded systems. Note that ICU is widely used in many embedded systems. [ 3 ]

3.      This is quite possible if the function uprv_malloc is customized by users via common/cmemory.h::u_setMemoryFunctions(…). This flexibility significantly increases the risk of this vulnerability, because it is impossible to control when a user-defined memory-allocation function returns null pointer.