首页 网络安全 正文

TeX Live SyncTeX中的安全漏洞CVE-2026-63729

摘要

栋科技漏洞库关注到TeX Live SyncTeX 解析器堆释放后使用漏洞,漏洞现已经被追踪为CVE-2026-63729,漏洞的CVSS 3.X评分6.6。

TeX Live 是跨平台、完整开源的 LaTeX 排版套装,Windows、macOS、Linux 系统都通用,是学术论文、公式、书籍排版最主流环境。

一、基本情况

TeX Live原生支持XeLaTeX、LuaLaTeX,搭配ctex宏包流畅处理中文,适配宋体、黑体系统字体,完美满足毕业论文、期刊排版需求。

TeX Live SyncTeX中的安全漏洞CVE-2026-63729

TeX Live搭配TeXworks、TeXstudio等编辑器使用,支持生成PDF,擅长复杂数学公式、参考文献、标准论文格式、简历、幻灯片制作。

栋科技漏洞库关注到TeX Live SyncTeX 解析器堆释放后使用漏洞,漏洞现已经被追踪为CVE-2026-63729,漏洞的CVSS 3.X评分6.6。

二、漏洞分析

CVE-2026-63729是一个Evince SyncTeX解析器堆释放后重用漏洞,在模糊测试过程中SyncTeX解析器被发现存在堆释放后重用漏洞。

解析畸形SyncTeX文件时会触发该漏洞,程序对已释放的内存区域执行读写操作,攻击者可利用漏实现任意代码执行或拒绝服务攻击。

具体来说,TeX Live是开源TeX排版发行版,内置的 SyncTeX 解析器(synctex_parser.c)被 GNOME Evince 等下游消费者嵌入使用;

用户或下游程序打开恶意构造的 .synctex 或 .synctex.gz 时,解析过程触发堆释放后使用漏洞,造成应用崩溃或潜在的任意代码执行。

受影响版本中,恶意 SyncTeX 文件可在 _synctex_post_process_ref 中生成一个父指针为 NULL 的 ref 节点;

当 _synctex_tree_parent(ref) 返回 NULL 时,__synctex_replace_ref 内部的摘除分支被跳过、ref 仍保留指向活动树的 sibling 指针;

函数随后无条件执行 synctex_node_free(ref),调用 _synctex_free_leaf 并沿未清零的 sibling 指针递归释放仍属于活动树的兄弟节点;

解析器在文档加载或后续遍历期间再次访问这些节点时即触发堆释放后使用。

(一)漏洞代码分析

漏洞成因:递归释放节点结构体时,未同步更新指向该节点的父节点、兄弟节点、关联节点指针。

递归释放逻辑:_synctex_free_node 函数(以及 _synctex_free_input 等同类销毁函数)会递归释放子节点与兄弟节点。

static void _synctex_free_node(synctex_node_p node) {
    if (node) {
        SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node);
        SYNCTEX_WILL_FREE(node);
        synctex_node_free(__synctex_tree_sibling(node)); // <--- Recursive free of sibling
        synctex_node_free(_synctex_tree_child(node));    // <--- Recursive free of child
        _synctex_free(node);                             // <--- Free current node
    }
    return;
}

(二)具体分析

调用synctex_node_free(__synctex_tree_sibling(node))时,程序会释放兄弟节点,

但在调用该函数前,既未将当前节点的兄弟指针置空,也未将该兄弟节点从节点树中剥离。

若该兄弟节点(或其任意子节点)存在其他引用(例如作为关联节点、迭代器的后继指针、别名指针等),这些引用就会成为野指针。

(三)触发条件

畸形 SyncTeX 文件会构造出一种场景:某个引用节点不存在父节点(_synctex_tree_parent(ref)返回空)。

由于缺失父节点,解析器的替换逻辑__synctex_replace_ref无法将该节点从兄弟链表中剥离。

后续解析器会无条件释放该引用节点,而该节点的兄弟指针仍完好,指向其余正常存活的节点树。

递归销毁逻辑会顺着指针遍历存活节点树,提前释放仍在使用的兄弟节点。

当解析器后续访问这些被提前释放的节点时,就会触发释放后重用漏洞。

三、POC概念验证

使用开启地址消毒器(AddressSanitizer)编译的 evince-thumbnailer 程序完成漏洞验证。

(一)验证步骤

启用 ASAN 编译 evince-thumbnailer

使用漏洞验证文件执行 evince-thumbnailer,配套文件为uaf.pdfuaf.synctex

管理员已设置登录后刷新可查看

(二)崩溃输出

程序运行日志证实 synctex_node_free 函数内存在堆释放后重用漏洞:

==1597649==ERROR: AddressSanitizer: heap-use-after-free on address 0x506000005d80 at pc 0x76e03618ca2a bp 0x7ffe0a07cb10 sp 0x7ffe0a07cb00
READ of size 8 at 0x506000005d80 thread T0
    #0 0x76e03618ca29 in synctex_node_free ../cut-n-paste/synctex/synctex_parser.c:288
    #1 0x76e03618ca29 in _synctex_free_leaf ../cut-n-paste/synctex/synctex_parser.c:920
    #2 0x76e03618ca29 in _synctex_free_leaf ../cut-n-paste/synctex/synctex_parser.c:916
    #3 0x76e0361b1bdb in synctex_node_free ../cut-n-paste/synctex/synctex_parser.c:288
    #4 0x76e0361b1bdb in _synctex_post_process_ref ../cut-n-paste/synctex/synctex_parser.c:5752
    #5 0x76e0361b6fe9 in _synctex_post_process ../cut-n-paste/synctex/synctex_parser.c:5877
    #6 0x76e0361b6fe9 in _synctex_scan_content ../cut-n-paste/synctex/synctex_parser.c:5958
    #7 0x76e0361b6fe9 in synctex_scanner_parse ../cut-n-paste/synctex/synctex_parser.c:6086
    #8 0x76e0361bb373 in synctex_scanner_new_with_output_file ../cut-n-paste/synctex/synctex_parser.c:6015
    #9 0x76e036170425 in ev_document_initialize_synctex ../libdocument/ev-document.c:377
    #10 0x76e036171b81 in ev_document_load_full ../libdocument/ev-document.c:433
    #11 0x76e0361760a4 in ev_document_factory_get_document_full ../libdocument/ev-document-factory.c:335
    #12 0x5582d6e84950 in evince_thumbnailer_get_document ../thumbnailer/evince-thumbnailer.c:165
    #13 0x5582d6e84950 in main ../thumbnailer/evince-thumbnailer.c:278
    #14 0x76e035a2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #15 0x76e035a2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #16 0x5582d6e850f4 in _start (/root/targets/evince/build_asan/thumbnailer/evince-thumbnailer+0x30f4) (BuildId: 59918a2795a5711a59a8f95a150e203786973f2f)

0x506000005d80 is located 0 bytes inside of 64-byte region [0x506000005d80,0x506000005dc0)
freed by thread T0 here:
    #0 0x76e0362fc4d8 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x76e0361b1bdb in synctex_node_free ../cut-n-paste/synctex/synctex_parser.c:288
    #2 0x76e0361b1bdb in _synctex_post_process_ref ../cut-n-paste/synctex/synctex_parser.c:5752
    #3 0x76e0361b6fe9 in _synctex_post_process ../cut-n-paste/synctex/synctex_parser.c:5877
    #4 0x76e0361b6fe9 in _synctex_scan_content ../cut-n-paste/synctex/synctex_parser.c:5958
    #5 0x76e0361b6fe9 in synctex_scanner_parse ../cut-n-paste/synctex/synctex_parser.c:6086
    #6 0x76e0361bb373 in synctex_scanner_new_with_output_file ../cut-n-paste/synctex/synctex_parser.c:6015
    #7 0x76e036170425 in ev_document_initialize_synctex ../libdocument/ev-document.c:377
    #8 0x76e036171b81 in ev_document_load_full ../libdocument/ev-document.c:433
    #9 0x76e0361760a4 in ev_document_factory_get_document_full ../libdocument/ev-document-factory.c:335
    #10 0x5582d6e84950 in evince_thumbnailer_get_document ../thumbnailer/evince-thumbnailer.c:165
    #11 0x5582d6e84950 in main ../thumbnailer/evince-thumbnailer.c:278
    #12 0x76e035a2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #13 0x76e035a2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #14 0x5582d6e850f4 in _start (/root/targets/evince/build_asan/thumbnailer/evince-thumbnailer+0x30f4) (BuildId: 59918a2795a5711a59a8f95a150e203786973f2f)

previously allocated by thread T0 here:
    #0 0x76e0362fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x76e0361bd8d4 in _synctex_malloc ../cut-n-paste/synctex/synctex_parser_utils.c:72
    #2 0x76e0361b5361 in _synctex_new_ref ../cut-n-paste/synctex/synctex_parser.c:1647
    #3 0x76e0361b5361 in _synctex_new_ref ../cut-n-paste/synctex/synctex_parser.c:1647
    #4 0x76e0361b5361 in _synctex_parse_new_ref ../cut-n-paste/synctex/synctex_parser.c:4943
    #5 0x76e0361b5361 in __synctex_parse_sfi ../cut-n-paste/synctex/synctex_parser.c:5553
    #6 0x76e0361b5361 in _synctex_scan_content ../cut-n-paste/synctex/synctex_parser.c:5956
    #7 0x76e0361b5361 in synctex_scanner_parse ../cut-n-paste/synctex/synctex_parser.c:6086
    #8 0x76e0361bb373 in synctex_scanner_new_with_output_file ../cut-n-paste/synctex/synctex_parser.c:6015
    #9 0x76e036170425 in ev_document_initialize_synctex ../libdocument/ev-document.c:377
    #10 0x76e036171b81 in ev_document_load_full ../libdocument/ev-document.c:433
    #11 0x76e0361760a4 in ev_document_factory_get_document_full ../libdocument/ev-document-factory.c:335
    #12 0x5582d6e84950 in evince_thumbnailer_get_document ../thumbnailer/evince-thumbnailer.c:165
    #13 0x5582d6e84950 in main ../thumbnailer/evince-thumbnailer.c:278
    #14 0x76e035a2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #15 0x76e035a2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #16 0x5582d6e850f4 in _start (/root/targets/evince/build_asan/thumbnailer/evince-thumbnailer+0x30f4) (BuildId: 59918a2795a5711a59a8f95a150e203786973f2f)

SUMMARY: AddressSanitizer: heap-use-after-free ../cut-n-paste/synctex/synctex_parser.c:288 in synctex_node_free
Shadow bytes around the buggy address:
  0x506000005b00: 00 00 00 fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x506000005b80: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x506000005c00: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x506000005c80: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
  0x506000005d00: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
=>0x506000005d80:[fd]fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
  0x506000005e00: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
  0x506000005e80: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
  0x506000005f00: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x506000005f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x506000006000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==1597649==ABORTING

四、影响范围

TeX Live 发行版:全部版本 ≤ TeX Live 2025(包含 2024、2023、2022 等所有旧年份完整套装)

五、修复建议

TeX Live 2026

六、参考链接

管理员已设置登录后刷新可查看



扫描二维码,在手机上阅读
评论
更换验证码
友情链接