Tainted kernels

https://www.kernel.org/doc/html/latest/admin-guide/tainted-kernels.html


# Tainted kernels

> The kernel will mark itself as ‘tainted’ when something occurs that might be relevant later when investigating problems. Don’t worry too much about this, most of the time it’s not a problem to run a tainted kernel; the information is mainly of interest once someone wants to investigate some problem, as its real cause might be the event that got the kernel tainted. That’s why bug reports from tainted kernels will often be ignored by developers, hence try to reproduce problems with an untainted kernel.

kernelは、何かしらの問題を調査するときに関連する可能性がある何かが発生したら、"tainted(汚染された)"とマークをします。このことを深刻に考える必要はありません、多くの場合はtainted kernelを動かす事は問題にはなりません。kernelがtraintedであることが真因である可能性があるため、情報は何かの問題を調査するときに興味深いものです。そのため、tainted kernelのバグレポートは開発者によって無視されることが多いため、taintedではないkernelで問題を再現してみてください。

> Note the kernel will remain tainted even after you undo what caused the taint (i.e. unload a proprietary kernel module), to indicate the kernel remains not trustworthy. That’s also why the kernel will print the tainted state when it notices an internal problem (a ‘kernel bug’), a recoverable error (‘kernel oops’) or a non-recoverable error (‘kernel panic’) and writes debug information about this to the logs dmesg outputs. It’s also possible to check the tainted state at runtime through a file in /proc/.

taintedの原因を元に戻した後でも、kernelはtaintedのままになることに注意してください(例えば、proprietaryなkernel moduleをunload) 、これはkernelが信頼できないままであることを表しています。これはまた、kernelが何故tainted stateであるかを内部の問題（kernel bug)、回復可能なエラー（kernel oops)、回復不可能なエラー（kernel panic) そして、dmesg outputにlogを残すデブg情報の書き出しが発生したときに表現するのにもつかわれます。tainted stateは実行中には/proc内のファイルで確認することもできます。

# Tainted flag in bugs, oops or panics messages

> You find the tainted state near the top in a line starting with ‘CPU:’; if or why the kernel was tainted is shown after the Process ID (‘PID:’) and a shortened name of the command (‘Comm:’) that triggered the event:

上部の「CPU：」で始まる行のtainted stateを見つけることができます。kernelがtaintedかどうか、または理由がプロセスID('PID：')と、イベントをトリガーしたコマンドの短縮名('Comm：')の後に表示されます。


```
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
Oops: 0002 [#1] SMP PTI
CPU: 0 PID: 4424 Comm: insmod Tainted: P        W  O      4.20.0-0.rc6.fc30 #1
Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
RIP: 0010:my_oops_init+0x13/0x1000 [kpanic]
[...]
```

> You’ll find a ‘Not tainted: ‘ there if the kernel was not tainted at the time of the event; if it was, then it will print ‘Tainted: ‘ and characters either letters or blanks. In above example it looks like this:

eventが発生したときにkernelがtaintedでない場合には、ここが"Not tainted:  "になります。もしkernelがtaintedであった場合、個々には"Tainted:  "と、文字やブランクの文字列が表示されます。この例では以下のようになります。

` Tainted: P        W  O `

> The meaning of those characters is explained in the table below. In tis case the kernel got tainted earlier because a proprietary Module (P) was loaded, a warning occurred (W), and an externally-built module was loaded (O). To decode other letters use the table below.

これらの文字の意味については、後述のTableで示します。このケースでは、proprietary Moduleがロードされ(P)、warningが発生し(W)、外部でビルドされたmoduleがロードされ(O)た事前条件で、kernelがtaintedされていました。これらの文字列をTableを用いてdecodeする方法は後述します。

# Decoding tainted state at runtime

> At runtime, you can query the tainted state by reading cat /proc/sys/kernel/tainted. If that returns 0, the kernel is not tainted; any other number indicates the reasons why it is. The easiest way to decode that number is the script tools/debugging/kernel-chktaint, which your distribution might ship as part of a package called linux-tools or kernel-tools; if it doesn’t you can download the script from git.kernel.org and execute it with sh kernel-chktaint, which would print something like this on the machine that had the statements in the logs that were quoted earlier:

実行時において、tainted stateを読み出す方法は、cat /proc/sys/kernel/tainted です。もし0が戻ってきた場合、kernelはtaintedではありません。そうではない場合には、何の理由であるかを示しています。decodeする簡単な方法は、script tools/debugging/kerne-chktaintを使うことです、これは、linux-tools やkernel-toolsのパッケージの一部として手に入れることができます。もしない場合にも、git.kernel.orgや外部から、sh kernel-chktaintをによってダウンロードする事ができます。これは、前述したlogでstatementがあった,machineにおいて、下記のようなログを出力します。

```
Kernel is Tainted for following reasons:
 * Proprietary module was loaded (#0)
 * Kernel issued warning (#9)
 * Externally-built ('out-of-tree') module was loaded  (#12)
See Documentation/admin-guide/tainted-kernels.rst in the the Linux kernel or
 https://www.kernel.org/doc/html/latest/admin-guide/tainted-kernels.html for
 a more details explanation of the various taint flags.
Raw taint value as int/string: 4609/'P        W  O     '
```

> You can try to decode the number yourself. That’s easy if there was only one reason that got your kernel tainted, as in this case you can find the number with the table below. If there were multiple reasons you need to decode the number, as it is a bitfield, where each bit indicates the absence or presence of a particular type of taint. It’s best to leave that to the aforementioned script, but if you need something quick you can use this shell command to check which bits are set:

数字を自力でdecodeしてみてください。もし単一の原因でtaintedしている場合には、下記のテーブルから数字を探すことができる。もし複数の原因があった場合には、数字をdecodeする必要があります、この場合、bitfieldになっています。それぞれのbitは、それぞれのtypeのtaintの有無を示しています。これは前述のスクリプトに任せるのが最善ですが、簡単に実行したい場合、以下のシェルコマンドを使用して、どのビットが設定されているかを確認できます。

`$ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done `

# Table for decoding tainted state

> Note: The character _ is representing a blank in this table to make reading easier.

注：文字_は、この表では読みやすくするためにブランクを表しています。

|Bit|Log|Number	|Reason that got the kernel tainted                        | |
|--:|:-:|--:|:--|:--|                                                      | |
|0	|G/P|1	    |proprietary module was loaded                             |proprietary modulがLoadされた。 |
|1	|_/F|2   	|module was force loaded                                   |moduleが強制的にLoadされた |
|2	|_/S|4   	|SMP kernel oops on an officially SMP incapable processor  |公式にSMP に対応していないprocessorでSMP Kernelを動かしている |
|3	|_/R|8		|module was force unloaded                                 |moduleが強制的にunloadされた |
|4	|_/M|16		|processor reported a Machine Check Exception (MCE)        |processorがMachine Check Exception(MCE)を報告した |
|5	|_/B|32		|bad page referenced or some unexpected page flags         |不正なpage参照や予期せぬpage flag|
|6	|_/U|64		|taint requested by userspace application                  |user applicationでtainteが要求された |
|7	|_/D|128	|kernel died recently, i.e. there was an OOPS or BUG       |kernelが停止した、例えば、OOPSあるいはBUG |
|8	|_/A|256	|ACPI table overridden by user                             |ACPI Tableがユーザーによって更新された |
|9	|_/W|512	|kernel issued warning                                     |kernelでwarningが発生した |
|10	|_/C|1024	|staging driver was loaded                                 |staging driverがloadされた |
|11	|_/I|2048	|workaround for bug in platform firmware applied           |platform firmwareに適用されたbug向けのworkaround |
|12	|_/O|4096	|externally-built (“out-of-tree”) module was loaded      | 外部でbuildされた(out-of-tree) moduleがloadされた |
|13	|_/E|8192	|unsigned module was loaded                                |未署名のmoduleがloadされた |
|14	|_/L|16384	|soft lockup occurred                                      |soft lockup が発生した |
|15	|_/K|32768	|kernel has been live patched                              |kernelにlivepatchが適用された |
|16	|_/X|65536	|auxiliary taint, defined for and used by distros          |ディストリビューション用に定義され、使用される補助的なtainted|
|17	|_/T|131072	|kernel was built with the struct randomization plugin     | struct randomization pluginを用いてkernelがbuildされた|

> More detailed explanation for tainting

taintingの更なる詳細については以下になります。

>　0. G if all modules loaded have a GPL or compatible license, P if any proprietary module has been loaded. Modules without a MODULE_LICENSE or with a MODULE_LICENSE that is not recognised by insmod as GPL compatible are assumed to be proprietary.
　1. F if any module was force loaded by insmod -f, ' ' if all modules were loaded normally.
　2. S if the oops occurred on an SMP kernel running on hardware that hasn’t been certified as safe to run multiprocessor. Currently this occurs only on various Athlons that are not SMP capable.
　3. R if a module was force unloaded by rmmod -f, ' ' if all modules were unloaded normally.
　4. M if any processor has reported a Machine Check Exception, ' ' if no Machine Check Exceptions have occurred.

　0. もし全てのloadしたmoduleがGP+あるいは互換性のあるライセンスであれば"G"、もしproprietary moduleがあれば"P"になります。MODULE_LICENSEがない、あるいは、insmodする際にGPLとの互換性のあるMODULE_LICENSEであると判別できなかった場合には、proprietaryと判断されます。
　1. insmod -fによって強制的にmoduleがloadされたら"F"になります。すべてのmoduleが普通にloadされていれば、" "になります。
　2. マルチプロセッサの実行が安全であると認定されていないハードウェアで実行されているSMPカーネルでoopが発生した場合、"S"になります。現在、これはSMPに対応していないさまざまなAthlonでのみ発生します。
　3. rmmod -fによって強制的にmoduleがunloadされたら"R"になります。すべてのmoduleが普通にunloadされていれば、" "になります。
　4. いずれかのprocessorでもMachine Check Exceptionが報知されていれば"M"になります。Machine Check Exceptionが発生していなければ" "になります。

>　5. B If a page-release function has found a bad page reference or some unexpected page flags. This indicates a hardware problem or a kernel bug; there should be other information in the log indicating why this tainting occured.
　6. U if a user or user application specifically requested that the Tainted flag be set, ' ' otherwise.
　7. D if the kernel has died recently, i.e. there was an OOPS or BUG.
　8. A if an ACPI table has been overridden.
　9. W if a warning has previously been issued by the kernel. (Though some warnings may set more specific taint flags.)

　5. page-release gunctionで不正なpage参照や、予期せぬpage flagを発見した場合に"B"になります。これは、hardwareの問題あるいはkernelのbugを意味します。ログには、なぜこのtainteingが発生したのかを示す他の情報が含まれているはずです。
　6. userもしくはuser applicationが、Train flagをセットする事を要求した場合"U"になります。そうでない場合には" "です。
　7. kernelが停止してしまった場合"D"になります。例えば、OOPSやBUGです。
　8. ACPI Tableが上書きされた場合"A"になります。
　9. kernelによって問題が発生し、warninが事前に起きた場合に"W"になります（ただし、一部の警告では、より具体的な汚染フラグが設定される場合があります。）


>　10. C if a staging driver has been loaded.
　11. I if the kernel is working around a severe bug in the platform firmware (BIOS or similar).
　12. O if an externally-built (“out-of-tree”) module has been loaded.
　13. E if an unsigned module has been loaded in a kernel supporting module signature.
　14. L if a soft lockup has previously occurred on the system.

　10. staging driverがloadされた場合"C"になります。
　11. platform firmware内で何らかのbugのwork aroundを実行した場合"I"になります(BIOSもしくはそれと類似したもの）
　12. 外部でbuildされた(out-of-tree) moduleがloadされた場合"O"になります。
　13. kernelがモジュールの署名を有効にしている場合に、未署名のモジュールがloadされた場合に"E"になります。
　14. systemで以前にsoft lockupが発生した場合は"L"になります。

>　15. K if the kernel has been live patched.
　16. X Auxiliary taint, defined for and used by Linux distributors.
　17. T Kernel was build with the randstruct plugin, which can intentionally produce extremely unusual kernel structure layouts (even performance pathological ones), which is important to know when debugging. Set at build time.

　15. kernelにlive patchが適用された場合"K"になります
　16. 補助的なtaintedであって、ディストリビューション用に定義され、使用されたものが"X"になります。
　17. Kernelがrandstuct pluginを使ってbuildされました。これにより、非常に珍しいカーネル構造レイアウトを意図的に作成できます（パフォーマンスに異常がある場合でも）デバッグ時に把握しておくことが重要です。これは、buildしたタイミングでsetされます。

---
もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる（はずの認識）。

> https://www.kernel.org/doc/html/latest/index.html
> 
> Licensing documentation
> 
> The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.
> 
> https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing