首页
/ Bitcoin Core 0.11.1 版本解析:upnp 缓冲溢出修复、Low-S 签名规则与最小中继费用提升

Bitcoin Core 0.11.1 版本解析:upnp 缓冲溢出修复、Low-S 签名规则与最小中继费用提升

2026-09-06 14:45:25作者:裘晴惠Vivianne

本文基于 Bitcoin Core 官方 0.11.1 版本发布说明(release-notes-0.11.1.md)展开,完整覆盖该安全更新版本的升级/降级注意事项、三项关键变更(upnp 漏洞修复与默认禁用、Low-S 签名强制校验、最小中继费用默认值提升)的设计动机,并结合当前仓库源码说明相关机制在代码中的落点,帮助读者理解 0.11.1 为何要求尽快升级,以及这三项变更对节点行为、交易传播和挖矿策略的实际影响。

版本定位与安全升级建议

0.11.1 是一个安全修复版本(minor version release),官方建议“尽快升级至该版本”。该版本基于 0.11 分支,通过回移(backport)多个 0.12 开发分支上的修复,集中处理了网络层漏洞、交易可塑性攻击面和中继费用策略三个问题。

发布说明明确了两点使用前提:

  1. 升级操作:若运行的是旧版本,先将其完全关闭(老版本可能需要几分钟才能彻底退出),再执行安装程序(Windows)、替换 /Applications/Bitcoin-Qt(macOS)或覆盖 bitcoind/bitcoin-qt 二进制(Linux)。
  2. 降级风险:由于 0.10.0 起引入了 headers-first 同步与并行区块下载,区块文件与数据库不再向后兼容 0.10 之前的版本,详见下节。

升级与降级:区块存储不再向后兼容

发布说明的“Downgrade warning”一节解释了 0.10.0 之后的数据目录为何无法直接用于更早的版本:

  • 区块乱序存储:区块文件按收到顺序(而非高度顺序)写入磁盘,早期版本及部分配套工具无法处理这种布局,用更早版本执行 reindex 也会失败;
  • 区块索引包含“只有头没有块”的条目:新的区块索引数据库会保存尚未下载对应区块的头部记录(headers-first 同步的必要数据结构),早期版本不识别这种状态。

因此,发布说明给出的降级建议是:对整个数据目录做备份,否则降级后节点需要重新同步(或从 bootstrap.dat 导入)。完全同步完成的 0.10 数据目录在旧版本上“可能”可以直接使用,但官方明确声明这不受支持,且在旧版本尝试 reindex 时随时可能出错。

需要注意,这一兼容性约束不影响钱包的前向/后向兼容性——发布说明指出,从 0.11.x 降级到 0.10.x 未发现已知钱包问题。

变更一:修复捆绑 upnp 的缓冲溢出并默认禁用 upnp

漏洞背景

0.11.1 将捆绑的 miniupnpc 库更新至 1.9.20151008,修复了其在初次网络发现阶段的 XML 解析器缓冲溢出(对应 Cisco Talos 的 TALOS-2015-0035 报告,该漏洞由 Aleksandar Nikolic 发现)。

适用范围有一条重要限定:该漏洞只影响官方分发的可执行文件(其中捆绑了旧版 miniupnpc),不影响从源码自行编译或使用发行版软件包的用户。

默认禁用 upnp

除修复外,0.11.1 还通过 PR #6795(合并提交 4dbcec0,net: Disable upnp by default)默认关闭了 upnp 功能。发布说明给出的权衡是:

  • 代价:IPv4 网络上可达节点数量可能下降(节点无法再通过 upnp 主动为自身打洞/映射端口);
  • 收益:使未来的 libupnpc 漏洞不再构成结构性网络风险——即即使第三方库再出漏洞,攻击面也默认不存在。

这一“默认禁用、需要时再手动开启”的思路与 -upnp 命令行参数配合使用:用户如需恢复 upnp 行为,需在配置中显式开启,而非依赖默认值。

变更二:中继与挖矿前强制校验 Low-S 签名

这是 0.11.1 中影响最深远的策略变更,对应 PR #6769(71cc9d9,Test LowS in standardness, removes nuisance malleability vector)。

技术动机

ECDSA 签名存在天然的二义性:对同一个 (r, s)s 也可以表示为 n - sn 为曲线阶)。两种形式都数学上有效,导致同一笔交易可以被构造出不同的 txid。Bitcoin Core 自 2013 年 9 月(提交 a28fb70e)起生成的签名就是规范化“低 S 值”(low-S)形式,但该实现直到 2014 年 3 月的 0.9 版本才进入正式发布;Bitcoinj 保持了相近的兼容期,Bitcoinjs 与 Electrum 则更新更晚。

0.11.1 要求节点在**中继(relay)和挖矿(mining)**时拒绝非低 S 形式的签名,其定位在发布说明中写得很明确:

  • 共识行为完全不变(consensus behavior is unchanged)——这不是软分叉,不修改链上有效性规则;
  • 若广泛部署,可消除 SIGHASH_ALL 的 P2PKH 交易上最后一个已知的“骚扰型”可塑性(nuisance malleability)攻击向量
  • 代价是会阻塞大多数由“足够过时”的软件构造的交易;
  • 它不替代 BIP62 或类似机制(矿工仍可协作篡改交易),也不替代钱包软件对可塑性的妥善处理(发布说明引用了 Andrychowicz 等人的论文《On the Malleability of Bitcoin Transactions》作为背景),它只是消除了那种“便宜且恼人”的 DoS 攻击手段。

当前源码中的实现落点

从当前仓库的源码结构看,低 S 校验已经演化为一条清晰的调用链:

  • 签名校验的核心函数是 CPubKey::CheckLowSsrc/pubkey.cpp)。其实现先用 ecdsa_signature_parse_der_lax 宽松解析 DER 编码签名,再调用 secp256k1_ecdsa_signature_normalize——若规范化改变了签名(返回非 0),说明原始签名的 S 不在半阶以下,即非 low-S 形式;
  • 该校验被集成进脚本解释器的验证标志体系(见 src/script/interpreter.cpp 中对 CPubKey::CheckLowS 的调用),成为脚本验证流程的一环,而不仅是 0.11.1 时期的“标准性测试”——从源码结构看,这意味着当前版本的低 S 约束已从 mempool 准入策略升级为脚本验证层的一部分;
  • 模糊测试亦覆盖该路径,src/test/fuzz/key.cpp 断言合法签名通过 CheckLowS 而非法签名被拒绝。

理解这一演进对把握 0.11.1 的意义很重要:当年它作为“标准性规则”引入以避免过早破坏兼容,随后在共识参数框架下逐步成为验证标志体系的一部分,这正是发布说明中“Consensus behavior is unchanged”这一声明在后续版本中被重新定义的过程。

变更三:-minrelaytxfee 默认值从 0.00001 提升到 0.00005

调整内容与动机

0.11.1 将 -minrelaytxfee 的默认值由 0.00001 BTC/kvB 提升到 0.00005 BTC/kvB(PR #6793,e7bcc4a,Bump minrelaytxfee default)。发布说明解释了背景:

  • 当时的**交易洪泛(transaction flooding)**导致节点内存池(mempool)急剧膨胀,造成节点内存占用失控;
  • 这是一个临时措施,用于桥接到动态费用估计机制合并之时(该机制随后进入了 0.12 版本);
  • 该数值在 0.11 的发布说明中已被建议采用,0.11.1 正式落地。

当前源码中的实现落点

在当前仓库中,这一参数体系的演进痕迹清晰可见:

  • 默认值常量定义于 src/policy/policy.hDEFAULT_MIN_RELAY_TX_FEE{100},即 100 satoshi/kvB。对比 0.11.1 时期的 50 satoshi/kvB(0.00005),可以看到中继费用下限在此后进一步上调;注释亦明确它是“-minrelaytxfee 的默认值,交易中继的最低费用”;
  • 命令行参数在 src/init.cpp 注册,帮助文本说明了其语义:“低于此费率(BTC/kvB)的手续费在中继、挖矿与交易创建时视为零费用”;
  • src/kernel/mempool_options.h 将该常量作为 mempool 参数结构的初始值,src/node/mempool_args.cpp 中还存在 static_assert(DEFAULT_MIN_RELAY_TX_FEE == DEFAULT_INCREMENTAL_RELAY_FEE),说明最小中继费与增量中继费(-incrementalrelayfee)在结构上被约束为同值,二者共同定义了 mempool 限容与替换策略的费率下限;
  • 费用估计器侧,src/policy/fees/block_policy_estimator.h 的注释特别提到 MIN_BUCKET_FEERATE 历史上继承自 DEFAULT_MIN_RELAY_TX_FEE,并要求后者变更时同步更新——这印证了发布说明中“临时措施,桥接至动态方法”的历史脉络:0.12 引入的估计器确实从此常量继承了其最低费率桶。

对运维的直接含义是:若节点显式配置了低于新默认值的 -minrelaytxfee,仍会按配置值执行;而跟随默认值的节点在 0.11.1 之后会把 50 satoshi/kvB 以下的交易视为“零费”交易,在 mempool 已满时优先淘汰或拒绝这类低费交易。

0.11.1 完整变更日志

发布说明收录的 16 项行为级变更如下(PR 编号与合并提交哈希均沿用原文档):

PR 合并提交 变更说明
#6438 2531438 openssl:规避配置文件加载/竞态问题
#6439 980f820 更新 Debian netinstall 的 URL 位置
#6384 8e5a969 qt:对 SSL 连接强制 TLS1.0+
#6471 92401c2 Depends:qt 升级至 5.5
#6224 93b606a 对未请求区块的处理更加严格
#6571 100ac4e libbitcoinconsensus:避免多线程环境下的崩溃
#6545 649f5d9 timedata 采样最多保存 200 个
#6694 834e299 [QT] 修复 thin space 换行断行问题
#6703 1cd7952 向 0.11 回移 bug 修复
#6750 5ed8d0b 向 v0.11 回移 recent rejects
#6769 71cc9d9 标准性中测试 LowS,消除骚扰型可塑性向量
#6789 b4ad73f miniupnpc 更新至 1.9.20151008
#6785 b4dc33e 向 v0.11 回移:(strCommand == "tx") 中若 AlreadyHave() 则直接返回
#6412 0095b9a 测试新建 socket 是否可被 select()
#6795 4dbcec0 net:默认禁用 upnp
#6793 e7bcc4a 提升 minrelaytxfee 默认值

其中除三项重点变更(#6769、#6789/#6795、#6793)外,其余多为安全加固与稳定性回移:openssl 配置竞态、Qt TLS 版本下限、libbitcoinconsensus 多线程崩溃、未请求区块的更严格处理,均属于“防御纵深”类修复,与 0.11.1 作为安全版本的定位一致。

致谢

发布说明感谢了为 0.11.1 直接贡献代码的 21 位贡献者(Adam Weiss、Alex Morcos、Casey Rodarmor、Cory Fields、fanquake、Gregory Maxwell、Jonas Schnelli、J Ross Nicoll、Luke Dashjr、Pavel Janík、Pavel Vasin、Peter Todd、Pieter Wuille、randy-waterhouse、Ross Nicoll、Suhas Daftuar、tailsjoin、฿tcDrak、Tom Harding、Veres Lajos、Wladimir J. van der Laan),以及提供代码审查与安全研究支持的贡献者:IRC 用户 timothy 报告了相关问题,miniupnp 漏洞由 Cisco Talos 的 Aleksandar Nikolic 发现;译文则来自 Transifex 平台的翻译社区。

小结

0.11.1 虽然只是一个 0.11 分支上的小版本,但三项变更各自奠定了后续版本的重要机制:upnp 默认禁用确立了第三方网络库“默认关闭”的风险管理范式;Low-S 强制校验消除了当时 P2PKH 交易上最后剩余的廉价可塑性攻击向量,其校验逻辑在今天的仓库中仍能以 CPubKey::CheckLowS 与脚本验证标志的形态被追踪;-minrelaytxfee 提升到 0.00005 则是 mempool 洪泛治理的临时手段,为 0.12 动态费用估计器的引入铺平了道路——当前源码中估计器最低费率桶继承该常量、且与 -incrementalrelayfee 保持静态断言相等的结构,正是这一演进的直接证据。对仍在维护历史节点数据或研究节点策略演进的读者,这份发布说明与 0.11.0 发布说明0.12.0 发布说明 串联阅读,可以完整还原 2015 年前后 Bitcoin Core 交易策略的转型过程。

登录后查看全文
热门项目推荐
相关项目推荐