赞
踩
LWN.net需要你! 没有订阅者,LWN就根本不存在。 请考虑注册订阅,帮助LWN继续出版。 |
警告是通过WARN()和WARN_ON_ONCE()等宏发出的。 默认情况下,警告文本被发送到内核日志,然后继续执行,就像警告没有发生一样。 有一个sysctl钮(kernel/panic_on_warn),可以在警告发出时导致系统恐慌,但对于系统管理员来说,在忽略问题和使系统完全停止之间缺乏选择。
Popov的补丁集以kernel/pkill_on_warn旋钮的形式增加了另一个选项。 如果设置为非零值,这个参数会指示内核在警告发生时杀死所有正在运行的进程的线程。 波波夫说,这种行为比什么都不做增加了系统的安全和保障,同时又不像直接杀死系统那样具有破坏性。 它可能会杀死试图利用系统的进程,并且在一般情况下,防止一个进程在已知出错的情况下运行。
有一些人反对这个方案,首先是Linus Torvalds,他指出,当警告发出时正在运行的进程可能与警告本身没有任何关系。 例如,问题可能发生在一个中断处理程序中,或者在其他一些情况下。"向一个随机的进程发送信号只是巫术编程,和其他任何事情一样可能导致其他非常奇怪的故障
",他说。
Torvalds建议,一个更好的方法可能是创建一个新的/proc文件,当一个影响系统的事件(如警告)发生时,它将提供信息。 一个用户空间的守护进程可以轮询该文件,在发出警告时读取相关信息,然后自己着手杀死进程,如果这看起来是正确的事情的话。 Marco Elver补充说,有一个跟踪点可以提供相关信息,只需做一点工作。 Kees Cook提出了一个实现方案,但Popov不喜欢;他说,这种方法会让一个进程在警告发生后继续执行,而当用户空间对这种情况采取行动时,可能已经太晚。
James Bottomley认为,到目前为止讨论的所有方法都是不正确的。 他说,如果警告发生,内核就不再处于已知状态,任何事情都可能发生:
WARN的意思是发生了一个意外的状况,这意味着内核本身处于一个未知的状态。 你不能通过杀死和重启随机的东西来恢复,你必须重新初始化到一个已知的状态(即重置系统)。 我们做WARN而不是BUG的一些原因是,我们相信状态污染是有限的,如果你很小心,系统可以继续处于退化的状态,如果用户愿意接受这种风险。
因此,他说,唯一合理的政策是继续(接受可能发生坏事的风险)或杀死系统并重新开始--这是内核现在提供的选项。
波波夫曾建议 ELISA项目,该项目正在努力将Linux部署到安全关键的应用中,可能会支持增加pkill_on_warning。 但在该项目工作的Lukas Bulwahn(但他很谨慎地表示他不代表ELISA)不同意。 他说,正确的解决方案是在警告时杀死系统,但也要确保警告只在事情真正脱离轨道的情况下发出:
只有当某些东西没有按照开发者的期望配置,或者内核被置于通常是意料之外的状态,并且很少被暴露在开发者的批判性思维中,被测试和在其他系统中使用时,才应该发出警告。警告不应该被用于一些信息性的东西,这仍然允许内核在一般预期的环境中以适当的方式继续运行。
他补充说,真正的安全还需要确保对panic()的调用在所有情况下都能真正停止系统--这一点并不像人们想象的那么容易证明。 例如,一个panic()的调用可能会在试图获得一个锁时挂起。
Christoph Leroy说,警告应该在内核内处理,以便系统能够尽可能地保持运行。 鉴于此,他继续说:"pkill_on_warning似乎很危险,而且不相关,可能比什么都不做更危险,特别是WARN可能因为与运行中的线程无关的原因而触发
"。 然而,Popov不同意这样的观点,即我们可以期望所有的警告都在内核中得到正确的处理:
有一种非常强烈的反对在内核源代码中加入BUG*()的力量。所以有很多情况下,WARN*()被用来处理严重的问题,因为内核开发者没有其他选择。
事实上,他的补丁在启用新选项时,警告的行为几乎与BUG()调用相同,BUG()调用默认会使运行中的进程立即结束。 正如他所指出的,开发人员在试图增加这些调用时遇到了阻力,因为他们的效果被认为是太严重了。
现在还不清楚增加一个选项使警告也变得更严重是解决这个问题的最好办法。 不过,这次讨论可能会产生一个好的结果,那就是对警告的含义和产生警告时应该发生什么进行更好的定义。 像内核中的许多机制一样,警告宏只是在没有任何整体设计的情况下发展起来的。 现在有了很多关于开发者如何使用警告的经验,参与一些设计可能会使内核整体上更加强大。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。