CVE-2026-90000 in Linux情報

要約

〜によって VulDB • 2026年09月16日

Linuxカーネルにおいて、以下の脆弱性が修正されました:

HID: rmi - 小サイズのRMIレポートによるOOB(配列外)アクセスの修正

hid-rmiドライバは、writeReport/readReportバッファのサイズを、デバイスから提供されるreport descriptorに基づいてのみ決定しており、最小値の下限がありません。具体的には以下の通りです:

data->input_report_size = hid_report_len(input_report); data->output_report_size = hid_report_len(output_report); alloc_size = data->output_report_size + data->input_report_size; data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL); data->readReport = data->writeReport + data->output_report_size;

しかし、その後固定されたオフセットに対して読み書きを行います。出力レポートと入力レポートがともに1バイトであると宣言するデバイスでは、hid_report_len()はそれぞれ2を返すため、alloc_sizeは4になります。一方、rmi_set_page()(probe時にrmi_input_configured()を通じて無条件に到達します)はwriteReport[4]への書き込みを行い、rmi_hid_read_block()はwriteReport[0..5]への書き込みを行います。readReportは writeReport + output_report_size の位置にあるため、これらの書き込み操作は次の応答が解析されるウィンドウも破損させます。

読み取りパスの方がさらに深刻です:コピー長は readReport[1] から取得され、これはデバイスによって埋め込まれ最大255になり得ますが、コピーの開始位置は &readReport[2] であり、input_report_sizeを考慮していません。そのため、割り当て領域の末尾を超えて隣接するslabオブジェクトに及んでしまいます。これには嘘をつくデバイスは必要ありません。rmi_f01_probe() は固定された21バイトのレジスタ読み取りを実行するため、入力レポートが23バイト未満であると宣言しているデバイスであれば、正直に応答した場合でも境界外アクセスが発生します。これらのバイトはRMIコアが処理するレジスタ値となります:rmi_f01_probe() はこれらをカーネルログに製品IDとして出力し、同じ名前のモード 0444 のsysfs属性を通じてエクスポートします。また、rmi_driver_set_irq_bits() はこれを割り込みマスクとしてデバイスへ送信するため、小サイズのreport descriptorによりヒープの内容が特権のないユーザー空間およびデバイス自体の両方に漏洩する可能性があります。

書き取りパスにも上限がありません:rmi_hid_write_block() は無制限な len を &writeReport[4] に対してコピーします。probe時にデバイスが駆動できる最大の呼び出し元は rmi_driver_set_irq_bits() で、その長さはデバイスがPage Description Tableで宣言する割り込みソースの数に基づいています。

最後に、読み取りループはゼロ長さの応答では終了できません:そのような応答は何もコピーせず、bytes_read および bytes_needed のいずれも進めません。また、応答が届いたため wait_event_timeout() による1秒待機も発生しないため、常に0を返すデバイスは page_mutex を保持した状態で probe worker内でループを実行し続けます。franktaskd(kernelのハング検出スレッド)はこれを認識しません。なぜなら、すべての応答がタスクをウェイクアップさせるからです。

ドライバが必要とする最小サイズ未満のレポート — 書き取り用には6バイトの出力、読み取りハンドシェイクには3バイトの入力 — をprobe時に拒否し、書き込みおよび読み取りのコピーをデバイスが宣言したreport sizeに制限(clamp)します。また、ゼロ長さの応答をエラーとして扱います。このようにして拒否されたデバイスは、RMIレポートIDを持たない通常のHIDデバイスと同様に起動されます。

そのパスにおいて RMI_DEVICE が device_flags に設定されたままにならないよう注意が必要です。なぜなら、rmi_input_configured() はその後でRMIセットアップを実行し rmi_set_page() に到達するためです。この関数は、拒否処理によって割り当てがスキップされた writeReport バッファへの書き込みを行います。このビットは設定されて到着する可能性があります:rmi_probe() はレポートチェックの前に id->driver_data を device_flags にコピーしており、新しい_id sysfs属性を通じたバインドでは driver_data に RMI_DEVICE (BIT(0)) が設定された状態で提供されることがあります。driver_dataがコピーされる箇所でこのビットを解除し、RMI_DEVICE が「このprobeはレポートを検証した」という意味のみを持つようにします。これより前に存在する3つのジャンプ先もカバーされます。

エラーパスでは、ループ上部の待機条件となるフラグである RMI_READ_DATA_PENDING もクリアされます。これを設定したままにしておくと、後続のすべての wait_event_timeout() が古い応答に対して即時返却し、デバイスの存命中ずっと読み取りパスを停止させてしまいます。

制限(clamping)は正常動作するハードウェアにおいて回帰を引き起こしません:読み取りループはすでに以下のケース --- 省略 ---

Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.

責任者

Linux

予約する

2026年09月11日

モデレーション

承諾済み

エントリ

VDB-405799

EPSS

0.00000

アクティビティ

非常低い

ソース

Do you need the next level of professionalism?

Upgrade your account now!