对于那些对本周末阅读的一些有见地的Linux内核邮件列表感兴趣的人来说,有一场关于Linux内核缓解意外算术溢出/下溢/重写的能力的激烈讨论。
谷歌的Kees Cook一直在研究如何更好地处理Linux内核的C源代码中意外的算术溢出错误。他希望看到一种系统化的方法,让Linux内核能够处理这样的算术上溢/下溢/环绕问题。最初的想法是更好地使用基于编译器的清理程序,或者最近的C语言建议,在不破坏名称的情况下进行运算符重载。在后一种方案中,作为一种潜在的解决方案,C运算符重载可以允许在助手中任意处理溢出。
Kee最初的想法是寻求基于消毒剂的缓解措施,并在邮件列表帖子中总结道:
“我正在就采取上述第一种方法寻求一些普遍共识。任何真正为我们带来有意义的覆盖范围的解决方案都需要对Linux的类型进行相当广泛的更改,所以这是一个普遍的痛点。但我已经敲响了“让Linux更安全”的鼓很长一段时间了,我希望我能说服人们,我们需要真正做出改变。现状还不够好,我们可以做得更好。我只需要找到一个我们可以达成一致并在未来几年实际应用的共同解决方案。”。
我现在去拿我的石棉服。。。你有什么想法、建议和备选方案?"
Linus Torvalds很快分享了他对该提案的看法:
“我还是完全不相信。
问题是,环绕不仅定义明确,而且是“常见的”和“预期的”。
实例
静态内联u32 __hash_32_generic(u32 val)
{
返回val*GOLDEN_RATIO_32;
}
该死,我绝对不认为我们应该把它注释为某种“特殊乘法”。
我不知道其中有多少。但我100%相信,让人类对此进行注释并使源代码变得更糟绝对是错误的做法。
基本上,无符号算术被定义为环绕,这是有充分理由的。
所以我有一个硬性要求,任何编译器的抱怨都必须非常理智。他们需要检测人们何时故意做这样的事情,他们需要关闭^&;%关于包裹发生的事实。
任何愚蠢到在上面抱怨包裹的工具都是需要忽略的破损工具。
真正地这是不可谈判的。
这与整体相似
无符号整数a,b;
如果(a+b
一种模式:上面抱怨包绕的工具是绝对坏的,需要忽略。
所以我认为你需要限制你的抱怨,并真正考虑如何限制它们。如果你把“绕错了”当作某种概括;规则,我要忽略你,我要告诉人们忽略你,拒绝任何由这种愚蠢规则导致的愚蠢补丁。
换言之,你应该首先考虑的是确保工具不会抱怨理智的行为。
在你做到这一点并认真对待这一点之前,这次讨论永远不会产生任何成果。
Linus”
莱纳斯·托瓦尔德斯的一些明确的沟通。他后来补充道:
任何无意识的“这一切都可以结束”都是不可原谅的。
它需要比这更聪明。是的,这意味着要准确地考虑到可能的环绕结果是如何实际使用的。
如果将其用作大小或数组索引,则可能会出现问题。但是,如果它用于屏蔽,然后将*masked*版本用于索引,那么这显然不是问题。
IOW,与“a+b”完全相同
一个不考虑结果如何使用的工具,只是盲目地说“绕过错误”,我认为这是一个非常有害的工具。
不,答案是绝对不要通过添加更多的随机助手类型和/或函数来增加内核开发人员的认知负荷。
我们已经期待了很多内核开发人员。我们不应该因为你的宠物项目而增加负担。
换言之:我让你有责任确保你的宠物项目是宠物项目中的“瑜伽熊”——比普通熊更聪明。
只要你是从“这会把责任推给别人”的角度来处理这个问题,那么问题就出在你身上。
成为解决方案,而不是问题。
Linus”
As another follow-up he suggested taking more baby steps toward a potential solution. The discussions remain ongoing so we'll see how the discussion evolves and ultimately what code ends up being proposed for trying to better deal with the Linux kernel's C code for mitigating potential unexpected arithmetic overflows/wrap-arounds.