Linux を実行する組み込みシステムには、UIO のカーネルドライバを利用するユーザ空間に PCI ドライバがあります。アプリケーションは__uio_register_device()
カーネルから呼び出されたデバイス登録をトリガーできますuio.c
。その後、アプリケーションはデバイスファイル(/dev/uio0
)を開きます。その後、デバイス情報を保持しているいくつかのカーネルメモリを解放するために、デバイスの登録をキャンセルすることでuio_unregister_device()
正しく動作しません。その後、アプリケーションはファイルを閉じて解放されたポインタにアクセスしているため、カーネルはパニック状態になります。
アプリケーションを修正するだけでなく、どのようにLinuxカーネルを堅牢にすることができますか?
uio_open()
uio_release()
キー割り当てメモリ(in)へのファイルポインタを取得しますprivate_data
。ところで、uio_unregister_device()
このような情報がないので、どうすればいいのか分かりません。または、アプリでファイルを強制的に閉じる方法はありますか?何が起こっているのか、他の提案や説明がありますか?
編集:以下のように簡単に再現でき、ユーザースペースの視点を表示します。
# replace '1234 abcd' by vendor id and device id
echo '1234 abcd' > /sys/bus/pci/drivers/uio_pci_generic/new_id
echo '0000:00:01.0' > /sys/bus/pci/drivers/uio_pci_generic/bind
# 'bind' may not even be needed. /dev/uio0 is created
cat /dev/uio0 &
# now be bad
echo '0000:00:01.0' > /sys/bus/pci/drivers/uio_pci_generic/unbind
kill <cat process ID>
# kernel panic...
衝突の原因はUnable to handle kernel paging request at virtual address
3つの異なるスタイルです。idev
あるいは、無効なポインタ(必ずしもNULLである必要はなく、任意のデータです)idev->info
。idev->owner