#4369·ctags

[错误] V 解析器中的栈溢出 (parseExpression/parseExprList)

作者: oneafter创建于 2026年1月16日更新于 2026年3月2日

描述

我们在 Universal Ctags 的 V 语言解析器中发现了一个栈溢出漏洞。在解析深层嵌套表达式时,会发生无法控制的递归,导致崩溃。 ASAN 报告显示了 parseExpression 和 parseExprList 之间的无限递归循环,最终导致 getInputFilePosition 发生栈耗尽并崩溃。

环境

  • 操作系统: Linux x86_64
  • 编译器: Clang
  • 构建配置: 以 Release 模式启用 ASan。

漏洞详情

  • 目标: Universal Ctags (ctags)
  • 漏洞类型: CWE-674: 无法控制的递归 (栈溢出)
  • 函数: parseExpression / parseExprList
  • 位置: parsers/v.c:2744 (和 parsers/v.c:2721)
  • 根原因分析: V 解析器使用递归调用来处理表达式和表达式列表。循环如下: parseExpression 调用 parseExprList,而 parseExprList 又调用 parseExpression。
// parsers/v.c
static void parseExpression(...) {
    // ...
    parseExprList(...);
    // ...
}
static void parseExprList(...) {
    // ...
    parseExpression(...);
    // ...
}

表达式的嵌套深度似乎没有限制。使用深层嵌套结构 (例如深层嵌套括号或数组) 的特殊构建的 V 源文件会触发此无限递归。

重现

  1. 使用 Release 优化和启用 ASAN 构建 ctags。
  2. 使用崩溃文件 repro 运行:
./ctags -f /dev/null --sort=no poc.v
ASAN 报告
AddressSanitizer:DEADLYSIGNAL
=================================================================
==12961==ERROR: AddressSanitizer: stack-overflow on address 0x7ffec5913ec8 (pc 0x5626acc1b09a bp 0x7ffec5914710 sp 0x7ffec5913ed0 T0)
    #0 0x5626acc1b09a in __asan_memcpy (/src/ctags/ctags+0x19909a) (BuildId: 4e8981c500ee9870205e9d50b4bf13ab5c564fbe)
    #1 0x5626accee7c2 in getInputFilePosition /src/ctags/main/read.c:353:27
    #2 0x5626acff46f3 in readTokenFull /src/ctags/parsers/v.c:608:24
    #3 0x5626acff3ee2 in readToken /src/ctags/parsers/v.c:891:2
    #4 0x5626acff3ee2 in parseExpression /src/ctags/parsers/v.c:2721:3
    #5 0x5626acff795d in parseExprList /src/ctags/parsers/v.c
    #6 0x5626acff40c5 in parseExpression /src/ctags/parsers/v.c:2744:5
    #7 0x5626acff795d in parseExprList /src/ctags/parsers/v.c
    #8 0x5626acff40c5 in parseExpression /src/ctags/parsers/v.c:2744:5
    #9 0x5626acff795d in parseExprList /src/ctags/parsers/v.c
    #10 0x5626acff40c5 in parseExpression /src/ctags/parsers/v.c:2744:5
    #11 0x5626acff795d in parseExprList /src/ctags/parsers/v.c
    #12 0x5626acff40c5 in parseExpression /src/ctags/parsers/v.c:2744:5
    #13 0x5626acff795d in parseExprList /src/ctags/parsers/v.c
    #14 0x5626acff40c5 in parseExpression /src/ctags/parsers/v.c:2744:5
    #15 0x5626acff795d in parseExprList /src/ctags/parsers/v.c
    #16 0x5626acff40c5 in parseExpression /src/ctags/parsers/v.c:2744:5
    #17
…

内容来源: universal-ctags/ctags