cURL库中doh_decode_rdata_name()函数未初始化指针释放漏洞分析

本文详细分析了cURL库doh_decode_rdata_name()函数中存在的一个未初始化指针释放问题,包括漏洞触发条件、代码分析、调试验证方法以及开发团队的响应和修复过程。

Free of uninitialized pointer in doh_decode_rdata_name()

tdp3kel9g 向 curl 提交了一份报告。 2025年3月13日 21:59 UTC

漏洞描述

doh_decode_rdata_name() 函数(位于 lib/doh.c)在特定条件下会释放一个未初始化的指针。

如果剩余缓冲区长度 *remaining <= 0,将执行第1033行代码,对未初始化的指针 thename.bufr 进行 free() 操作(以下源代码来自 v.8.12.1;截至2025年3月11日,该漏洞在主分支中仍然存在):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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() 执行的操作:

1
Curl_safefree(s->bufr);

但在第1033行调用时,s->bufr 尚未初始化。问题的根源在于第1036行应该放在函数的开头。

漏洞验证

使用 Visual Studio 2022 演示该问题:

  1. 使用调试信息构建 cURL
  2. 为 curl 项目设置命令行参数:
    1
    
    -v --ssl-no-revoke --doh-url https://cloudflare-dns.com/dns-query https://www.google.com
    
  3. 将该项目设置为启动项目
  4. 在第1032行设置断点
  5. 运行 curl
  6. 当断点触发时,使用调试器将 rem 修改为 0
  7. 单步执行到第1033行并检查 s->bufr,注意它是未初始化的(可能包含 0xcccccccccccccccc,这是 Visual Studio 在调试构建中用于标记未初始化内存的值,使用它很可能会产生异常)
  8. 单步执行 Curl_safefree() 调用,观察它抛出访问冲突异常

潜在触发条件

如果 DOH 服务器返回空的 RRDATA,rem 可能等于 0。根据 RFC 1034 第3.6节(“域名标识一个节点。每个节点都有一组资源信息,可能为空”),这似乎是合法的。

目前没有测试用例来验证这一假设。

影响

可能产生任何基于释放后使用漏洞的影响。

开发团队响应

bagder (curl staff)2025年3月13日 22:01 UTC 发表评论: 感谢您的报告!我们将花时间调查您的报告,并尽快给您回复详细信息和可能的后续问题!很可能在24小时内。

bagder (curl staff)2025年3月13日 22:08 UTC 发表评论: 我认为这确实是一个真正的bug。但这不被视为安全问题,因为这是标记为实验性的功能,默认未启用。需要在构建时启用 HTTPS-RR 支持并在运行时使用。

bagder (curl staff)2025年3月13日 22:26 UTC 发表评论: 等等 - 这甚至不是一个bug。doh_decode_rdata_name 只会从 doh_resp_decode_httpsrr 以长度大于等于1的情况下被调用。

如果 doh_resp_decode_httpsrr 以长度小于2被调用,它会返回错误。然后它会减去2并使用变量中的余数调用该函数。

tdp3kel9g2025年3月13日 22:33 UTC 发表评论: 但是如果 doh_resp_decode_httpsrr() 中的初始长度为2,它通过测试,然后0被传递给 doh_decode_rdata_name()。

bagder (curl staff)2025年3月13日 22:36 UTC 发表评论: 第1097行:

1
2
if(len <= 2)
  return CURLE_BAD_FUNCTION_ARGUMENT;

这个检查会捕获 len == 2 的情况并返回错误。

bagder (curl staff)2025年3月13日 22:41 UTC 发表评论: 是的:https://github.com/curl/curl/pull/16710

报告状态

bagder (curl staff)2025年3月14日 07:20 UTC 关闭报告并将状态改为 Informative: 这是一个小的(当前无法触发的)bug,不是安全问题。

bagder (curl staff)2025年6月28日 12:27 UTC 请求披露此报告。

bagder (curl staff)2025年6月28日 21:10 UTC 披露此报告。

报告详情

  • 报告时间:2025年3月13日 21:59 UTC
  • 报告者:tdp3kel9g
  • 报告对象:curl
  • 报告ID:#3037326
  • 严重性:无评级 (—)
  • 披露时间:2025年6月28日 21:10 UTC
  • 弱点类型:释放后使用
  • CVE ID:无
  • 赏金:隐藏
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计