← LeisureLinux 文章索引
LeisureLinux · 微信公众号文章

六年、360 个补丁:Linux 内核终于把 strncpy() 扫地出门

安全/漏洞 阅读原文(微信)↗

所有 strncpy() 已被五个语义明确的函数取代,一个贯穿 6 年的安全工程画上句号。

Linux 7.2 合并窗口已完成最终清理,内核源码库不再出现 strncpy()。

━━━ ━━━ ━━━

一个「危险」的函数终于退休

2026 年 6 月 20 日,Last merge commit 落地——Linux 内核中最后一处 strncpy() 调用被替换,标志着这个函数在内核中彻底消失。

这场清理历时 6 年,动用 超过 360 个补丁,参与的开发者遍布内核各子系统:从文件系统、网络栈,到驱动层、架构代码——每一个 strncpy() 都被审计、替换、测试,然后删除。

Linus Torvalds 对这个函数的态度可以用两个字概括:「危险」。在内核文档中,strncpy() 被直接标记为「主动危险」——不是「不推荐」,是「actively dangerous」。

strncpy() 错在哪?

strncpy(src, dst, n) 的语义复杂且反直觉:

  • 如果 src 长度 ≥ n——不追加 NUL 终止符dst 末尾没有 \0,使用时必然越界。
  • 如果 src 长度 \< n——剩余字节全部用 \0 填充,性能浪费。
  • 返回值永远是 dst,不是拷贝的字符数,你根本不知道实际拷贝了多少。

这三个问题导致了内核中大量「默认不 NUL 终止」的隐式未定义行为:

char buf[8];
strncpy(buf, "hello world", sizeof(buf));
// buf = "hello w" → 没有 \0
printf("%s", buf);  // 读越界,打印垃圾数据

甚至更隐蔽的是,内核经常用 strncpy 来「顺便做清 0」,导致代码意图完全模糊。维护者看到 strncpy无法判断作者到底想做什么

为什么拆成 5 个函数?

分析发现,内核中 strncpy() 实际上被用于 5 种完全不同的语义场景,只是当时都用同一个函数糊弄过去了:

原始用法 实际意图 替代函数
拷贝并确保 NUL 终止但不填充 安全字符串拷贝 strscpy()
拷贝 + 尾部零填充 安全拷贝 + 静态清零 strscpy_pad()
拷贝定长字段(不需要 NUL) 固定宽度内存拷贝 strtomem_pad()
带显式填充的有界拷贝 缓冲区安全填充 memcpy_and_pad()
明确已知长度的内存拷贝 普通内存复制 memcpy()

关键设计思路是:用函数名暴露开发者意图

看代码的人不再需要猜测「这里要不要 NUL?填充用不用?目标多大?」——函数签名本身就告诉你了。

谁是「操刀人」?

这个清理工程的主要推动者是 Kees Cook(内核安全团队核心成员,也是 Chrome OS 安全负责人)。他从 2020 年左右就开始逐步推进这项工作,逐个子系统、逐个文件地替换 strncpy()

Linus Torvalds 曾在 2021 年评论 strncpy:「我讨厌这个函数,它应该被扔进语言的垃圾堆。」

六年过去,它真的被扔进去了。

对开发者意味着什么?

如果你写内核模块或驱动,从现在起 strncpy() 在编译时会报错。请按以下规则选择替代品:

  1. 能用 strscpy() 就优先用——它保证 NUL 终止,返回实际拷贝长度(负数=截断)
  2. 需要清空剩余缓冲区strscpy_pad()
  3. 目标缓冲区固定宽度且不需要字符串语义strtomem_pad()
  4. 只是内存拷贝,跟字符串无关memcpy()memcpy_and_pad()

一个简单的迁移对照:

// ❌ 旧:意图不明
strncpy(dev->name, src, IFNAMSIZ);

// ✅ 新:显式语义
strscpy(dev->name, src, IFNAMSIZ);

尾声

360 个补丁,6 年时间,换来的是一行 #include 的删除——以及内核安全水位线的整体抬升。

在 C 语言的世界里,字符串处理永远是 Bug 的温床。strncpy 被清退不只是「换个函数名」,更是内核社区对 代码可读性即安全性 理念的一次集体实践。

函数名就是文档。别让阅读者猜你的意图。

━━━ ━━━ ━━━

📝 文末互动:你在工作中写过 strncpy 的 Bug 吗?用 strscpy 之后有没有踩过其他坑?留言说说你的经历。

🔜 下期预告:Linux 7.2 还有哪些重量级合并?SPOILER:BPF 模块化、Rust for Linux 又有新进展。

一个字符就能提权到 root?Linux 内核 CVE-2026-23111 深度剖析

Linux SLUB 分配器深度拆解:malloc 背后内核在干什么?

Copy Fail 内核漏洞已经在各大主流发行版 Ubuntu, Debian 修复,请尽快升级!

Jens Axboe 操刀新款 Linux 内核补丁:拟将单核 I/O 吞吐性能飙升 60%

Linux 7.1 内核补丁:彻底解决 Sheaves 内存优化中的锁竞争与路径冗余

【内核前沿】Linux 7.0 手动内联优化:UDP 吞吐量暴力提升 12%

本文整理自微信公众号 LeisureLinux 的原创内容(Linux / AI / 安全 硬核技术)。

· 阅读原文(微信公众号)

· 关注公众号 LeisureLinux,第一时间获取技术深度内容。

LeisureLinux 公众号二维码(微信扫一扫关注)