CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
NONE
Integrity Impact
NONE
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
AI Score
Confidence
High
EPSS
Percentile
30.3%
Libcurl at commit 04739054cdac5a0614fb94e3655e313c03399f35 contains an invalid invocation of free()
in the function utf8asn1str()
at lib/vtls/x509asn1.c:397.
The relevant code can be seen below:
static CURLcode
utf8asn1str(struct dynbuf *to, int type, const char *from, const char *end)
{
// --- snip ---
if(type == CURL_ASN1_UTF8_STRING) {
// --- snip ---
}
else {
while(!result && (from < end)) {
char buf[4]; /* decode buffer */
// --- snip ---
if(wc >= 0x00200000) {
free(buf);
/* Invalid char. size for target encoding. */
return CURLE_WEIRD_SERVER_REPLY;
}
}
}
}
buf
is located on the stack and not the heap, which means that buf
will be falsely treated as a heap chunk.
This poses a security risk because the address of buf
can be returned in subsequent calls to malloc()
, which causes
the stack contents at that point to be overwritten.
The stack holds data that determines the control flow of the application. This can either be local variables that indirectly
determine the control flow of their corresponding functions or security-critical metadata liked saved framepointers or return addresses.
If an attacker manages to overwrite these kinds of stack contents he/she can gain control over the control flow of the application.
Consider the following scenario that demonstrates how to leverage the invalid free()
to overwrite return addresses:
free()
malloc()
callOne environment where that scenario could work out is Ubuntu bionic, where the glibc does not check whether the argument to free()
actually refers to a valid heap chunk.
The fix for this vulnerability is pretty straight forward, just remove the call to free()
:
diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c
index cea88e668..ddfb65344 100644
--- a/lib/vtls/x509asn1.c
+++ b/lib/vtls/x509asn1.c
@@ -394,7 +394,6 @@ utf8asn1str(struct dynbuf *to, int type, const char *from, const char *end)
if(wc >= 0x00000800) {
if(wc >= 0x00010000) {
if(wc >= 0x00200000) {
- free(buf);
/* Invalid char. size for target encoding. */
return CURLE_WEIRD_SERVER_REPLY;
}
I assess the impact of this vulnerability to be “High” because
free()
is easy to trigger since it happens during the TLS handshake