什么是被污染的Linux内核?

在某些情况下,Linux内核可能会变得“有瑕疵”。例如,将专有的视频驱动程序加载到内核中会使内核变得有瑕疵。这种情况可能会在系统日志、内核错误消息(oops和panics)以及诸如lsmod之类的工具中可见,并且会一直存在,直到系统重新启动。
这意味着什么?它会影响我使用系统的能力吗?它可能如何影响我的支持选项?

可能是lsmod输出:未污染的重复问题。 - Gilles 'SO- stop being evil'
@Gilles,我认为你链接的问题应该合并到这个问题中。而且,并不明显哪一个问题是另一个问题的重复。 - bwDraco
1我希望将这个版本作为问题的最权威版本;请参考问题的最新编辑。 - bwDraco
@DragonLord 为什么你要发布一个新问题并试图关闭现有的问题呢?为什么不将那个问题作为规范版本呢? - Michael Mrozek
15@MichaelMrozek:1)我没有看到已有的问题,因为用户询问“‘tainted’是什么意思”并不明显。2)这个问题的措辞相当特定于一个命令lsmod。我写了这个问题和答案,使其更加通用,以便那些问“‘tainted’是什么意思”的人能够轻松找到它。 - bwDraco
内核也会被污染,即使使用开源驱动程序,但如果代码签名生效却缺失。还可以参考Stack Overflow上的e1000e驱动程序从源代码构建导致内核污染 - user56041
1他们本可以使用一个比“受污染”更中性的词语。 - Roger Dahl
1

An error occurred:

marked(): input parameter is undefined or null
Please report this to https://github.com/markedjs/marked.
- undefined
2个回答

一个受污染的内核是指那些由于无法保证其正常运行而处于不受支持状态的内核。大多数内核开发人员会忽略与受污染内核相关的错误报告,并且社区成员可能要求您在诊断与内核相关的问题之前先纠正污染条件。此外,当内核被污染时,一些调试功能和API调用可能会被禁用。
污染状态通过一系列标志来表示,这些标志代表了内核无法被信任正常工作的各种原因。导致内核被污染最常见的原因是加载来自NVIDIA或AMD的专有图形驱动程序,在这种情况下,通常可以安全地忽略该条件。然而,导致内核被污染的一些情况可能暗示了更严重的问题,如硬件故障。检查系统日志和设置的特定污染标志以确定问题的根本原因是个不错的主意。
此功能旨在识别可能使正确排除内核问题变得困难的条件。例如,专有驱动程序可能会引发无法可靠调试的问题,因为其源代码不可用且其效果无法确定。同样,如果之前发生了严重的内核或硬件错误,内核空间的完整性可能已被破坏,这意味着内核生成的任何后续调试消息可能不可靠。
请注意,仅纠正污染条件本身并不能消除污染状态,因为这样做并不改变内核无法可靠地正常工作或产生准确的调试信息的事实。系统必须重新启动以清除污染标志。
有关更多信息,请参阅Linux内核文档,其中包括每个污染标志的含义以及如何在报告错误之前对受污染的内核进行故障排除。
以下是可能导致内核被污染的部分条件列表,每个条件都有自己的标志。请注意,一些Linux供应商(例如SUSE)会添加额外的污染标志,以指示加载由第三方而非供应商直接支持的模块等条件。
  • 加载专有(或非GPL兼容)内核模块。如上所述,这是内核变得被污染的最常见原因。
  • 使用staging驱动程序,这些驱动程序是内核源代码的一部分,但是它们是实验性的并且没有完全测试过。
  • 使用不包含在Linux内核源代码中的out-of-tree模块。
  • 强制加载或卸载模块。如果尝试使用一个不适用于当前版本内核的模块,则可能发生这种情况。(Linux内核模块ABI在不同版本甚至相同版本的不同配置构建之间不稳定。)
  • 在特定不支持的硬件配置上运行内核,例如不支持SMP操作的早期AMD Athlon处理器上运行SMP(多处理器)内核。
  • 在内核中覆盖ACPI DSDT。有时需要这样做以纠正固件功耗管理错误;请参阅此Arch Linux wiki文章了解详细信息。
  • 某些关键错误条件,例如机器检查异常内核oopse
  • BIOS、UEFI或其他系统固件中的某些严重错误,内核必须解决这些错误。

1这个答案缺少了很多由这个问题所替代的重要信息。 - user56041
4我会增加至少一个“未签名模块”场景的重要可能性——内核根工具包被加载到内核中,或者刚刚执行了内核漏洞利用。 - kravietz
我经过一系列的编辑对答案进行了彻底修订,使其更准确易读,并删除了不必要的污点标志列表(读者可以直接通过内核文档链接进行查看)。 - bwDraco

加载专有或非GPL兼容模块或未签名模块将在运行中的内核中设置一个“污点”标志。
要在内核日志中检查内核的污点状态:
journalctl -k | grep taint

运行时检查内核污损状态:
cat /proc/sys/kernel/tainted      // if 0 then kernel is not tainted, else it is.

返回的值是一个位字段;您可以在这个表格中找到位的含义。
在内核恐慌消息中,寻找以‘CPU:’开头的行。
如果内核在kp事件发生时没有被污染,则会打印‘Not tainted:’;如果被污染,则会打印‘Tainted:’。
参考资料:关于被污染内核的Linux内核文档