curl · Report #3037326
Free of uninitialized pointer in doh_decode_rdata_name()
How it was found
doh_decode_rdata_name() (lib/doh.c) frees an uninitialized pointer under certain conditions.
If the remaining buffer length *remaining is <= 0, line 1033 is executed, free()-ing the uninitialized pointer thename.bufr (source below, from v.8.12.1; the bug is still present in master branch as of 3/11/2025):
1020:static CURLcode doh_decode_rdata_name(unsigned char **buf, size_t *remaining,
1021: char **dnsname)
1022:{
...
1026: struct dynbuf thename;
1027:
1028: DEBUGASSERT(buf && remaining && dnsname);
1029: if(!buf || !remaining || !dnsname)
1030: return CURLE_OUT_OF_MEMORY;
1031: rem = (int)*remaining;
1032: if(rem <= 0) {
1033: Curl_dyn_free(&thename);
1034: return CURLE_OUT_OF_MEMORY;
1035: }
1036: Curl_dyn_init(&thename, CURL_MAXLEN_host_name);
Curl_dyn_free() does
Curl_safefree(s->bufr);
but s->bufr isn't initialized when line 1033 calls it. The bug is that line 1036 should be at the beginning of the function.
To illustrate the issue using Visual Studio 2022:
-
Build cURL with debugging information;
-
Set the command arguments for the
curlproject to-v --ssl-no-revoke --doh-url https://cloudflare-dns.com/dns-query https://www.google.com
and set that project as the startup project.
- Set a BP on line 1032.
- Run curl.
- When the BP fires, use the debugger to doctor
remto0. - Step into line 1033 and examine
s-bufr. Notice that it's uninitialized (it probably contains0xcccccccccccccccc, which Visual Studio uses in debug builds to poison uninitialized memory, so that using it is likely to produce an exception). - Step the call to
Curl_safefree()and watch it throw an access violation.
It appears that rem can be == 0 if the DOH server returns no RRDATA . This seems legal under https://www.rfc-editor.org/rfc/rfc1034 s.3.6 (" A domain name identifies a node. Each node has a set of resource information, which may be empty").
I do not have a test brace to verify this hypothesis.
Impact
Possibly any impact that is rooted in a use-after-free bug.