近日,一项来自瑞士洛桑联邦理工学院(EPFL)和Google的联合研究成果引起了广泛关注。由EPFL的Han Zheng和Mathias Payer,Google DeepMind的Ilia Shumailov,以及Google的Tianqi Fan和Aiden Hall共同完成的研究论文《Fixing 7,400 Bugs for 1$: Cheap Crash-Site Program Repair》于2025年5月在arXiv预印本服务器上发表(arXiv:2505.13103v1)。这项研究针对当前自动化程序修复领域的痛点提出了创新性解决方案,让我们一起来看看他们是如何以惊人的低成本修复软件漏洞的。
一、软件漏洞修复的现状挑战
想象一下,你是一位负责保护一座古老城堡安全的守卫。最近,城堡周围的防御墙出现了越来越多的裂缝(漏洞),而且发现裂缝的速度远远超过了你能修复的速度。更糟糕的是,每次你修复一处裂缝,检查时往往又会发现新的裂缝。这就是当今软件安全面临的困境。
现代软件系统极其复杂,这种复杂性在带来更丰富功能的同时,也引入了大量可被利用的安全漏洞。为了主动保护用户免受恶意威胁,研究人员开发了称为"模糊测试"(fuzzing)的技术,自动化地寻找这些漏洞。过去几年,模糊测试技术在各种复杂且安全关键的系统中展现了惊人的效果,从网页浏览器到Linux内核,从MacOS到虚拟机管理程序。
然而,随着模糊测试技术的进步,开发者们面临着修复所发现漏洞的巨大压力。例如,尽管投入了大量维护努力,Syzbot(一个Linux内核漏洞报告平台)上仍有超过1,500个未解决的内核bug报告。现代模糊测试工具发现漏洞的速度远远超过了开发者修复它们的能力。更糟糕的是,修复漏洞的过程需要重新进行模糊测试来检查修复效果,而这又往往会发现额外的漏洞。
这种bug发现率与修复率之间不断扩大的差距已经导致积压数量超出了开发人员有效分类和修复的能力。这一挑战凸显了对自动化程序修复(APR)解决方案的迫切需求。最近大型语言模型(LLMs)的进步为解决这一挑战提供了一个有希望的方向,促使研究人员开发出各种新型自动化程序修复技术。
二、当前修复方法的局限性
尽管已有的自动化程序修复技术相当有前景,但它们在策略上存在一个根本性问题。当前的APR代理工具尝试通过识别和修复漏洞的根本原因来解决问题。这种策略在理论上非常完美,就像医生不仅要处理疾病症状,还要找出并治疗疾病的根本原因。但在实际应用中,这种方法面临着巨大挑战。
首先,根本原因分析本质上复杂,有时甚至是不可能完成的任务。想象一下在一座迷宫般的古老房子里寻找漏水的源头——你看到客厅地板上有水,但实际的漏水点可能是屋顶,甚至可能是城市主供水管道的问题!同样,软件漏洞的真正来源可能与表现出问题的代码相距甚远。
其次,当前的根本原因修复方法通常需要昂贵且重量级的LLM后端支持,这使得个别开发者难以采用和大规模部署这些解决方案。这就像需要一台昂贵的MRI机器来诊断每一个头痛问题——成本太高,无法广泛应用。
此外,根本原因分析依赖于LLM准确执行多个推理任务的能力。如果在这些阶段中的任何一个环节出现不精确,就可能需要多次修复尝试,进一步增加LLM查询的数量和相关的运行时成本。这就像医生需要进行一系列复杂的检查和测试,每一步都可能引入错误,导致反复就诊,最终花费更多时间和金钱。
三、WilliamT:崩溃点修复的创新方案
与这些不精确、高成本的根本原因导向方法相比,研究团队提出了一种轻量级的、临时性修复方法,它优先阻止直接利用漏洞,而不是立即修复根本原因。这种方法被命名为"崩溃点修复"(crash-site repair)。
这种方法的灵感来自于一个民间英雄故事的主角威廉·泰尔(William Tell),他在压力下只有一次机会射中放在孩子头上的苹果。类似地,研究团队开发的修复工具WilliamT旨在"一次性"修复,快速阻止漏洞被利用。
WilliamT的工作原理是接收模糊测试生成的漏洞验证样例(PoC)和安全检查工具(Sanitizer)输出作为输入。它采用基于正则表达式的方法进行故障定位和补丁生成,只在必要时才使用LLM进行根本原因分析。
想象一下,WilliamT就像一名熟练的急救医生,当看到病人胸口有明显伤口并且大量失血时,首先会立即止血和包扎伤口(崩溃点修复),而不是立刻进行深入的身体检查来确定伤口的根本原因(可能是汽车事故或其他伤害)。这种方法可以在专科医生(开发者)有时间进行深入调查的同时,先控制立即的威胁。
通过最小化对LLM的依赖,并通过预定义的bug模板约束其输出,WilliamT大幅减少了查询成本,并实现了在更小、更便宜的LLM上部署的可能性。这使WilliamT成为一个可扩展且实用的APR解决方案,特别适合资源受限的环境。
四、崩溃点修复与根本原因修复的对比
为了更好地理解WilliamT的工作原理,让我们看一个具体案例。在igraph库中,由于索引变量yy_c超出了全局数组yy_current_state的边界,出现了全局缓冲区溢出漏洞。有趣的是,这段代码并非手动编写,而是由flex自动生成的。真正的根本原因在于对编译标志的不正确使用,开发者最终通过修改CMakefile解决了这个问题。
这个例子表明,有效的修复有时需要跨域分析——覆盖构建系统、代码生成器和运行时行为——这些能力超出了当前大型语言模型(LLMs)的范围,因为它们在上下文容量和抽象推理方面存在限制。
为了解决这个挑战,研究团队从Chrome开发指南中汲取灵感,该指南建议在根本原因修复可用之前插入检查语句(即断言)来降低被利用的风险。这种策略将潜在可利用的漏洞转变为有意的、可控的崩溃,给开发者时间实现永久解决方案。
基于这一原则,WilliamT通过利用预定义的模板和崩溃点分析直接在崩溃点之前插入补丁。具体来说,研究团队专注于四种广泛流行的可利用漏洞类别:堆缓冲区溢出(HBO)、全局缓冲区溢出(GBO)、栈缓冲区溢出(SBO)和堆释放后使用(UAF)。每个类别都与一个模板相关联,该模板封装了常见的崩溃模式和补丁策略。
这种崩溃点修复范式显著简化了漏洞修复的复杂性,避免了对精确根本原因定位的需求。因此,WilliamT在实现可比的修复效果的同时,仅需不到1%的LLM查询消耗,使其更适合部署在资源受限或本地LLM环境中。
五、WilliamT系统设计
WilliamT的设计目标是消除与LLM相关的过高查询成本,将APR代理扩展到较小模型上。该系统以ClusterFuzz生成的漏洞验证样例(PoC)和可重现的Docker镜像作为输入,最终为易受攻击的程序生成一个一次性补丁。WilliamT包括两个主要组件:基于正则表达式的上下文检索和模板引导的补丁生成。
在基于正则表达式的上下文检索阶段,WilliamT在提供的Docker环境中重现PoC,利用安全检查工具(Sanitizer)报告通过基于正则表达式的匹配来识别崩溃点。这种方法将上下文提取任务从令牌密集型LLM查询中卸载出来,显著提高了性能和可扩展性。虽然崩溃点并不总是等同于真正的根本原因,但在崩溃点之前生成补丁足以缓解利用风险。因此,WilliamT为LLM代理提供了围绕崩溃点的焦点上下文。
对于模板引导的补丁生成,直接提示LLM生成修复通常会导致任意且不一致的输出,这在很大程度上取决于LLM的内部能力。为了解决这个问题,WilliamT根据其内存损坏类型(例如,堆缓冲区溢出、全局缓冲区溢出、栈缓冲区溢出、堆释放后使用)对每个漏洞进行分类。对于每种漏洞类别,WilliamT选择一个预定义的补丁模板,并引导LLM仅识别与补丁相关的关键变量。这种基于模板的约束显著减轻了LLM的认知负担,通过卸载大部分补丁生成逻辑,只要求LLM执行最小的崩溃点分析。这种代理设计使得较小的LLM能够以显著降低的资源需求实现合理的性能。
六、评估结果与比较
研究团队使用ARVO(一个高质量的数据集,包含来自250多个真实世界软件项目的5,000多个内存损坏漏洞)对WilliamT进行了评估。与手动构建的基准或不可重现的数据集相比,ARVO确保所有漏洞都是真实且可重现的。研究选择了所有可在15分钟内编译完成的HBO、SOF、UAF和GOF漏洞(共358个漏洞)进行测试。
研究团队将WilliamT与最先进的APR工具进行了比较,包括AutoCodeRover-S、Agentless和VulMaster。由于AutoCodeRover-S不是开源的,他们导入了AutoCodeRover-S为所有三个SoTA提供的修复方案,并包括使用相同LLM模型(gpt-4o-2024-08-06)的WilliamT以确保公平比较。
评估结果显示,CodeRover-S实现了54.5%的最高合理修复率,其次是WilliamT,成功修复了46.1%的漏洞。相比之下,Agentless表现明显较差,修复率为33.8%,而VulMaster仅解决了5个漏洞。尽管WilliamT的修复性能略低于CodeRover-S,但它需要的资源却低了几个数量级。CodeRover-S每次尝试一个补丁,每个漏洞最多进行三次尝试,总共最多需要18次尝试。相比之下,WilliamT只进行一次试验,在整个修复过程中仅应用一个补丁。这种一次性设计显著降低了计算和令牌成本。
在令牌和时间成本比较方面,使用GPT-4o模型时,WilliamT每个漏洞仅需0.0026美元,而CodeRover-S则需要约0.93美元。换句话说,在花费相同金额的情况下,WilliamT能够修复比CodeRover-S多357倍的漏洞。
这种效率直接导致了两个系统之间在修复时间上的显著差异。WilliamT完成整个过程——包括预处理和基于LLM的分析——平均只需不到一分钟。相比之下,CodeRover-S完成一项任务大约需要43.5分钟。关键区别在于它们各自的修复策略:CodeRover-S采用多迭代修复循环,这不仅延长了编译时间,还对系统资源造成了相当大的负担。相反,WilliamT利用单次补丁方法,避免了重复编译的开销,显著降低了CPU消耗并加速了整个修复工作流程。
七、WilliamT的扩展性和与其他工具的互补性
研究团队分析了SoTA系统之间合理修复的重叠情况。尽管CodeRover-S整体修复的漏洞略多于WilliamT,但每个系统解决的漏洞集在很大程度上是不相交的。换句话说,WilliamT和CodeRover-S倾向于修复不同的漏洞。具体来说,WilliamT成功解决了50个既不被CodeRover-S也不被Agentless解决的漏洞,而CodeRover-S独占修复了52个漏洞。Agentless贡献了15个既不被WilliamT也不被CodeRover-S覆盖的独特合理修复。
这种低重叠突显了WilliamT的互补性,表明它可以与其他代理工具有效结合使用。当使用GPT-4o作为后端时,WilliamT可以以不到0.68美元的价格修复所有358个漏洞——这比用CodeRover-S修复单个漏洞的成本还低。
此外,优化的管道——先执行WilliamT,然后将WilliamT失败的案例应用CodeRover-S——比单独使用CodeRover-S额外实现了60个合理修复,即修复率提高了29.6%,同时将总成本降低了45.9%。
为了证明WilliamT的通用性,研究团队在不同的LLM上测试了WilliamT,包括DeepSeek(R1、V3)、ChatGPT(4o、o3-mini)、Claude(3.5-Haiku和3.7-Sonnet),以及可以部署在4090 GPU甚至Mac Mini M4上的本地LLM,包括Gemma3(1B、4B、12B、27B)。
在所有模型中,Claude35-haiku达到了47.5%的最高修复率。Claude37-sonnet和GPT-4o紧随其后,修复率分别为46.4%和46.1%。DeepSeek也表现良好,使用推理模型修复了159个漏洞,使用聊天模型修复了158个。GPT-o3-mini表现略低,修复了153个漏洞,成功率为43.9%。
值得注意的是,研究团队特别关注较小的语言模型,尤其是Gemma3系列,发现它们相对于前沿模型表现得相当好。特别是,Gemma3:27B在所有模型中排名第二,达到了GPT-4o性能的96.4%。虽然Gemma3的12B和4B版本在性能上表现出明显下降,但它们仍然能够修复39.4%和38.0%的漏洞。
重要的是,Gemma3:27B模型足够轻量,可以在单个消费级GPU(如RTX 4090)上运行,甚至可以在Mac Mini M4上运行。这不仅展示了WilliamT的可扩展性,还展示了它在本地开发者机器上部署的实用可行性。
八、讨论与局限性
WilliamT在崩溃点分析准确识别相关变量且补丁插入在目标代码中语义有效时可以生成正确的补丁。在这部分中,研究团队检查了WilliamT中潜在假阳性的来源,重点关注对补丁合理性的内部和外部威胁。内部而言,不准确可能来自不正确的崩溃点分析或语义破坏性的补丁插入。外部而言,评估期间使用的不精确合理修复指标可能无法区分正确与不正确的补丁。
不正确的崩溃点分析可能导致LLM返回的关键变量不准确。这个问题可能源于两个主要因素:首先,提供给LLM的代码片段可能由于上下文有限而缺少正确的变量,尤其是当所需变量位于最终崩溃帧之外时;其次,变量识别的精度受到LLM能力和提示工程有效性的限制。
WilliamT当前在崩溃点上方一行插入生成的补丁。虽然这种方法原则上可行,但在实践中可能导致语义错误和编译失败。例如,如果崩溃发生在条件块内(例如,在if (...)语句内),简单插入可能会破坏控制流并使程序结构无效。在评估中,"无补丁"失败约占所有漏洞的37%,其中许多是由这种语义违反引起的。
当前评估遵循先前工作中的标准合理性标准,即验证生成的补丁是否防止原始崩溃。然而,这个指标并不确保程序的功能得到保留。因此,它可能高估真正正确修复的数量,并在所有评估系统中引入假阳性。这一限制突显了需要更严格的指标,这些指标考虑到语义正确性和更广泛的行为保留。
九、结论与未来展望
随着发现的安全漏洞数量不断增加,迫切需要更好的自动化程序修复工具。与大多数现有APR工具依赖于复杂的根本原因分析不同,研究团队提出了崩溃点修复方法,以简化修复过程并提高精度。研究团队还引入了模板引导的补丁生成技术,在保持修复有效性的同时降低使用LLM的高成本。
研究团队实现了原型系统WilliamT,并针对最先进的工具进行了评估。结果表明,将WilliamT与性能最佳的工具CodeRover-S结合使用,可以将令牌使用量减少45.9%,并将修复率提高29.6%。此外,WilliamT可以在Mac Mini上与本地LLM良好协作,显示出其在低成本、本地开发方面的潜力。
总的来说,这项研究为自动程序修复领域提供了一种新的思路,通过关注崩溃点而非根本原因,大大降低了修复的复杂性和成本,同时保持了较高的有效性。这种方法特别适合当前漏洞发现率远超修复能力的情况,为开发者提供了一种快速、低成本的临时修复方案,同时给予他们更多时间进行深入调查和永久修复。
好文章,需要你的鼓励
这项研究探索了如何通过"LLM情境调节"和"持续工作流程提示"技术来提高大型语言模型在验证化学分子式时的准确性。研究者发现,普通提示方法往往不可靠,因为LLM倾向于自动"纠正"错误而非指出它们。然而,通过精心设计的情境调节提示,研究成功引导Gemini 2.5 Pro不仅识别出文本中的错误,还发现了之前人工审阅未察觉的图像中的分子式错误。这一概念验证研究表明,即使不修改模型本身,也能通过适当的提示策略显著提高LLM在科学技术文档细节验证中的表现。
复旦大学研究团队开发的uLLSAM模型成功将多模态大语言模型(MLLMs)与分割一切模型(SAM)结合,解决了显微镜图像分析的跨域泛化难题。通过创新的视觉-语言语义对齐模块(VLSA)和语义边界正则化(SBR)技术,该模型在9个领域内数据集上提升了7.71%的分割准确度,在10个从未见过的数据集上也展现了10.08%的性能提升。这一统一框架能同时处理光学和电子显微镜图像,大大提高了生物医学图像分析的效率和准确性,为科研人员提供了强大的自动化分析工具。
斯坦福大学等机构研究团队利用强化学习训练大语言模型,使其能够优化汇编代码性能。研究构建了8,072个程序的数据集,并通过近端策略优化(PPO)训练模型生成既正确又高效的汇编代码。实验表明,训练后的Qwen2.5-Coder-7B-PPO模型实现了96.0%的测试通过率和1.47倍平均加速比,超越包括Claude-3.7-sonnet在内的所有其他模型。研究发现模型能识别编译器忽略的优化机会,如用单一指令替代整个循环,为性能敏感应用提供了有价值的优化途径。
这项研究提出了一种改进的声乐效果风格迁移方法,通过在推理时间优化过程中引入高斯先验知识,解决了传统ST-ITO方法忽视参数合理性的问题。研究团队基于DiffVox数据集构建了专业效果器参数分布模型,将风格迁移转化为最大后验概率估计问题。实验结果表明,该方法显著优于基准方法,参数均方误差降低了33%,并在主观听感测试中获得最高评分。这一创新为音频处理领域融合数据驱动和专业知识提供了新思路。