のプロセス中に 開発者ディスカッション Linuxカーネルの についてとlセットのテーマ 脆弱性を修正するパッチ リンクリストを操作するためのコード内のSpectreの 明らかになりました 多くの開発者にとって、問題は ならもっと簡単に解決できます カーネルコードで許可されました C queは新しいバージョンの規格に準拠しています。
また、現在Linuxカーネルに追加されているコードは、89年に作成されたANSI C(C1989)仕様に準拠している必要があります。
それが理由です スペクターに関連する問題 コード内の理由はeイテレータを使い続けた ループの後に個別に定義されます。
一般的に高速な性質にもかかわらず、カーネルプロジェクトは多くの古いツールに依存しています。 批評家はコミュニティでの電子メールの広範な使用に焦点を当てることを好みますが、おそらくより重要な時代錯誤は、カーネルプロジェクトが1989年以上前に開始される前にコード化されたカーネルコードのC言語標準の30バージョンの使用です。 今年の5.18月に予定されているカーネルXNUMXで、長年の慣行はすぐに終了する可能性があるようです。
と言われています マクロは、リンクリストの要素を反復処理するために使用されます。 ループイテレータはこのマクロに渡されるため、ループ自体の外部で定義され、ループ後も使用できます。 C99標準を使用すると、開発者はfor()ブロックでループの変数を定義できるようになり、回避策を考案することなく問題を解決できます。
残念ながら、カーネルにはリストが存在する場所が複数あります
イテレータは、そのような変更で中断するループの後に使用されます。 幸運なことに
そのようなものを識別するために使用できるスクリプトuse_after_iter.cocciがあります
コードの場所。 falseを減らすため、スクリプトを少し調整する必要がありました
元のユースケースではポジティブですが、これらはこのパッチに関連しています。報告されたさまざまなコードの場所では、リストイテレータは後にのみ使用されます
早期終了(break / goto)があったため、そうではない場合のサイクル
関連。
その部分については、 リーナス・トーバルズはその考えに同意しました 新しい仕様のサポートを実装できるようにするため、さらに、5.18年にリリースされたC11標準を使用するためにカーネル2011に移行することを提案しました。
その後、予備検証中に、新しいモードでのGCCとClangへのマウントが逸脱することなく通過しました。 より広範なテストによって予期しない問題が発生しない限り、5.18カーネルビルドスクリプトは「–std = gnu89」オプションを「–std = gnu11-Wno-shift-negative-value」に変更します。
Linus Torvaldsはパッチをあまり好きではなく、投機的実行の脆弱性とどのように関連しているかを知りませんでした。 しかし、Koschelが状況をさらに説明した後、Torvaldsは「これは単なる通常のバグであり、単純で単純なものです」と同意し、より大きなシリーズに関係なく修正する必要があると述べました。 しかし、彼は問題の本当の原因にたどり着きました。リストトラバーサルマクロに渡されたイテレータは、ループ自体の外側のスコープで宣言する必要があるということです。
このタイプの非投機的エラーが発生する可能性がある主な理由は、歴史的にC99スタイルの「ループ内の変数の宣言」がなかったためです。 したがって、list_for_each_entry()(および他のすべて)は、ループ自体でイテレータ変数を宣言できなかったという理由だけで、基本的に常に最後のHEADエントリをループから除外します。
また、言及する価値があります C17規格を使用する可能性が検討されました。 ただし、この場合、C11のサポートを含めることは、GCCバージョン(5.1)の現在の要件に準拠しているため、サポートされるGCCの最小バージョンを増やす必要があります。
最後に あなたがそれについてもっと知りたいなら、詳細はで確認できます 次のリンク。