过程中 开发者讨论 linux内核的 关于和l 主题一套 修复漏洞的补丁 代码中的 Spectre 用于处理链表, 变得很清楚 对于很多开发者来说,这个问题 如果可以更容易解决 在内核代码中被允许 C que 符合更新版本的标准。
而且目前添加到 Linux Kernel 的代码必须符合 89 年形成的 ANSI C (C1989) 规范。
这就是为什么 与幽灵有关的问题 在代码中是因为 se 一直使用迭代器 在循环之后单独定义。
尽管它通常速度很快,但内核项目依赖于许多较旧的工具。 虽然批评者喜欢关注社区对电子邮件的广泛使用,但可能更严重的不合时宜是使用 1989 年版本的 C 语言标准的内核代码,该标准是在 30 多年前内核项目开始之前编纂的标准。 看起来这种长期的做法可能会在内核 5.18 时结束,预计在今年 XNUMX 月。
有人提到 宏用于迭代链表的元素, 并且由于循环迭代器被传递给这个宏,它在循环本身之外定义并且在循环之后仍然可用。 使用 C99 标准将允许开发人员在 for() 块中为循环定义变量,这样可以在不发明变通方法的情况下解决问题。
不幸的是,内核中有多个位置列表
迭代器在这种更改中断的循环之后使用。 幸运的是
有脚本 use_after_iter.cocci 可用于识别此类
代码位置。 我不得不稍微调整一下脚本,因为它减少了错误
原始用例中的积极因素,但与此补丁相关。大量报告的代码位置仅使用列表迭代器后
如果有提前退出(break/goto)的循环,因此它们不是
相关的。
就其本身而言, Linus Torvalds 同意这个想法 为了能够实现对新规范的支持,并进一步建议在内核 5.18 上使用 11 年发布的 C2011 标准。
之后,在初步验证过程中,以新模式挂载到 GCC 和 Clang 没有偏差。 除非由于更广泛的测试而出现不可预见的问题,否则 5.18 内核构建脚本会将“–std=gnu89”选项更改为“–std=gnu11 -Wno-shift-negative-value”。
Linus Torvalds 不太喜欢这个补丁,也没有看到它与推测执行漏洞有什么关系。 然而,在 Koschel 进一步解释情况后,Torvalds 同意“这只是一个普通的 bug,简单明了”,并表示无论更大的系列如何,都应该修复它。 但后来他找到了问题的真正根源:传递给列表遍历宏的迭代器必须在循环本身之外的范围内声明:
发生这种类型的非推测性错误的主要原因是历史上我们没有 C99 风格的“在循环中声明变量”。 所以 list_for_each_entry() - 和所有其他的 - 从根本上总是将最后一个 HEAD 条目过滤出循环,这仅仅是因为我们无法在循环本身中声明迭代器变量。
还值得一提的是 考虑了使用 C17 标准的可能性, 但在这种情况下,有必要增加 GCC 的最低支持版本,因为包含对 C11 的支持符合 GCC 版本 (5.1) 的当前要求。
最后 如果您有兴趣了解更多有关它的信息,您可以在中查看详细信息 以下链接。