
CVE-2023-6931 カーネルパニック PoC
CVE-2023-6931 向けカーネルパニック PoC
CVE-2023-6931 は、perf_event における脆弱性であり、グループの read_size の整数オーバーフローによって発生するヒープバッファオーバーフローにつながります。
perf_events は、Linux カーネルが提供するパフォーマンス監視および分析フレームワークです。このフレームワークにより、ハードウェアおよびソフトウェアコンポーネントによって生成されるさまざまなパフォーマンス関連データの追跡が可能になります。
perf_event_open システムコール
ユーザースペースがカーネル内のパフォーマンスイベントを設定および制御できるようにするインターフェースです。
イベントの作成、グループ化、制御、データの読み取りに使用されます。/proc/sys/kernel/perf_event_paranoid の値が 1 以下である必要があります。ulimit -n コマンドを使用して確認および変更できます。CONFIG_PERF_EVENTS が設定されている必要があります。この脆弱性は、グループの read_size における整数オーバーフローに起因します。関数 perf_event_validate_size は read_size の検証を行います。しかし、read_size が検証される方法は、現在のイベントの read_size のみをチェックします。
重要な点は、各検証中に現在のイベントのみが検証され、以前のイベントは検証されないことです。グループリーダーに PERF_FORMAT_GROUP が設定されている場合、現在のイベントを追加するだけでグループリーダーの read_size が増加する可能性があります。
これにより、最終的に perf_read_group で問題が発生します。event->read_size の計算は、グループリーダーの read_format に nr_siblings を乗じたものに基づいています。read_size 変数は 2 バイトの u16 であるため、保持できる最大値は 0xffff です。
これを悪用するために、攻撃者はまず、すべての可能な read_format オプションが設定されたグループリーダーイベントを作成します。次に、多数の兄弟イベントが作成されます。これらの兄弟イベントは、perf_event_validate_size での検証問題を防ぐために、read_format に PERF_FORMAT_TOTAL_TIME_RUNNING のみを設定します。その結果、nr_siblings の値は非常に大きくなりますが、各兄弟イベントは個別に検証を通過するため、この段階では問題はありません。
この状態で perf_read_group が呼び出されると、PERF_FORMAT_GROUP が設定されているため、グループリーダーの read_size が増加し続けます。最終的に整数オーバーフローが発生し、kzalloc は非常に小さなバッファを割り当てます。しかし、実際のイベント数は非常に多いため、ヒープバッファオーバーフローが発生し、カーネルパニックを引き起こします。