Stack Buffer Overflow in curl's OpenSSL Provider Handling
Medium
C
curl
Submitted None
Actions:
Reported by
oblivionsage
Vulnerability Details
Technical details and impact analysis
# Summary
Hello curl Team,
I found a stack buffer overflow in curl's OpenSSL provider handling code. The bug is in `ossl_set_provider()` function located in `lib/vtls/openssl.c`. When a provider name longer than `MAX_PROVIDER_LEN` is passed, the function copies it to a fixed-size buffer without proper length checking, causing stack overflow
# Vulnerability Location
The buffer overflow happens in `lib/vtls/openssl.c` at line 2003-2004:
```c
memcpy(name, curlx_str(&prov), curlx_strlen(&prov));
name[curlx_strlen(&prov)] = 0;
```
# Code Analysis
I was looking at curl's SSL engine handling and noticed something strange in the provider setup. Here is what happens:
1. The `ossl_set_provider()` function defines a fixed buffer:
```c
char name[MAX_PROVIDER_LEN + 1]; // line 1986
```
where `MAX_PROVIDER_LEN` is defined as 128 (line 1974 in the same file)
2. Later in the function (line 2003-2004), it copies data from the provider string:
```c
memcpy(name, curlx_str(&prov), curlx_strlen(&prov));
name[curlx_strlen(&prov)] = 0;
```
The problem is there's no check if `curlx_strlen(&prov)` is less than or equal to `MAX_PROVIDER_LEN`. This lets us overflow the stack-based buffer if we provide a string longer than 128 bytes
Also notice `name[curlx_strlen(&prov)] = 0;` this writes a null byte past the end of the buffer when overflow happens
# Reproducing the Bug
I tried to find ways to trigger this issue. The code path is:
1) `ossl_set_engine()` in `lib/vtls/openssl.c` calls `ossl_set_provider()`
2) `ossl_set_engine()` is called by `Curl_ssl_set_engine()`
3) `Curl_ssl_set_engine()` is triggered by `CURLOPT_SSLENGINE` option
I couldn't trigger a crash directly with curl command line because it stops with **"SSL Engine not found"**error before hitting the vulnerable code
# Proof of Concept
I created a minimal PoC that reproduces the exact vulnerable code pattern:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Same as in curl code
#define MAX_PROVIDER_LEN 128
typedef struct {
char *data;
size_t len;
} Curl_str;
// Mimicking curl's functions
char *curlx_str(Curl_str *s) {
return s->data;
}
size_t curlx_strlen(Curl_str *s) {
return s->len;
}
// Recreating the vulnerable function
void simulate_curl_provider_vulnerability(const char *iname) {
char name[MAX_PROVIDER_LEN + 1]; // Same buffer size as curl
Curl_str prov;
printf("[+] Input: %s\n", iname);
// Set up provider string
prov.data = (char *)iname;
prov.len = strlen(iname);
printf("[+] Provider length: %zu\n", prov.len);
printf("[+] Buffer size: %zu\n", sizeof(name));
// VULNERABLE PART - exactly as in curl source
memcpy(name, curlx_str(&prov), curlx_strlen(&prov));
name[curlx_strlen(&prov)] = 0;
printf("[+] Done\n");
}
int main(void) {
char *overflow_string = malloc(300);
// Creating long provider name to trigger overflow
strcpy(overflow_string, "pkcs11:");
for(int i = 0; i < 200; i++) {
strcat(overflow_string, "A");
}
// Call the vulnerable function
simulate_curl_provider_vulnerability(overflow_string);
free(overflow_string);
return 0;
}
```
When compiled with AddressSanitizer and run:
```bash
gcc -g -fsanitize=address -o poc poc.c
./poc
```
It clearly shows stack buffer overflow:
{F4365560}
Additional Notes
+ I tried to trigger this vulnerability directly using the curl command line tool but wasn't successful as curl returns an "SSL Engine not found" error before reaching the vulnerable code. However, the vulnerable code is clearly present in the curl source and confirmed with my PoC
+ I can provide more detailed analysis with GDB if needed
## Impact
This bug allows overwriting stack memory with controlled content. In specific contexts, it could cause to:
+ Remote code execution
+ Denial of service
+ Information disclosure
The severity depends on how this code is used in applications. It is most dangerous if an attacker can control provider name input
Thank you for reviewing also I can provide more detailed analysis with GDB if needed I didnt want to make the report very long
Report Details
Additional information and metadata
State
Closed
Substate
Not-Applicable
Submitted
Weakness
Stack Overflow