OSがメモリアクセス違反を検出する方法


12

オペレーティングシステム(Linuxが望ましい)は、許可されていないメモリロケーションにアクセスしたことをどのように認識しますか?

この質問は、それらのいまいましいポインターに触発されました!私の考えでは、コンピューターのすべては、速度、セキュリティ、整合性などの妥協点に関するものです。

Linuxのメモリマップはよく知っていますが、アクセスしようとしている場所がアクセスするたびにカーネルが有効な範囲内にあるかどうかをカーネルがチェックするのは少しばかげています。それは非常に多くの時間を無駄にし、より生産的な何かをすることに費やすことができるように聞こえます(しかし、おそらくチェックなしでは安全性は低下します!)。それとも、最近のすべてのアクセスを記憶し、すべてのハードウェアタイマーティックでチェックしますか?(しかし、それは安全ではないように思えますが、それでもまた遅いです。)

私はこの質問がどこでも答えられていないように見えることに驚いた。それは私がいつも疑問に思っていたものです。OSに代わってこれを行うハードウェアのセクションがあり、便利で便利な抽象化レベルにあると思うようになります。しかし、それでも、すべてのコンテキストスイッチで次のプロセスのメモリマップをロードする必要があり、これもまた遅いように聞こえます。

そう、とにかく、私は少し続けています:OSはどのようにメモリ違反を検出しますか?

ありがとう

回答:


11

(次の回答は、「最新の」デスクトップ、サーバー、または上位の組み込みプラットフォーム(スマートフォンなど)を想定しています。x86システムの場合、モダンとは386以上を意味します。ほとんどすべてのUNIXなどの「最新の」OS、または95以降のWindows。

これはOSでは発生せず、プロセッサ、特に MMUメモリ管理ユニット)で発生します。MMUは仮想アドレス指定をサポートしています。これにより、ポインターを構成するビットは、メモリ内のビットの物理的な位置を直接示しません。

典型的なMMUでは、ポインターが間接参照されると、MMUはビットを2つのグループに分解します。上位ビットがページ番号を構成し、下位ビットがページ内のアドレスを構成します。ほとんどのデスクトップおよびサーバーマシンは4kBページを使用します。MMUはTLBと呼ばれるテーブルで仮想ページ番号を検索します(これを「プロセスメモリマップ」と呼びます)。TLBは、この仮想ページに対応する物理ページの番号を示します。次に、MMUはメモリ内の物理ページからデータをフェッチします。

TLBにこの特定の仮想ページ番号のエントリが含まれていない場合、MMUはプロセッサに無効なアクセスが発生したことを通知します。これは通常、例外と呼ばれます。

これまでOSについて言及していません。これは、このすべての操作がOSから独立しているためです。OSは、次の2つの方法で物事を構成するため、機能します。

  • OSはタスクの切り替えを担当します。そのようにすると、疑いのとおり、現在のTLBが保存され、次のスケジュールされたタスクのために保存されたTLBに置き換えられます。このように、各プロセスにはTLBがあるため0x123456、プロセスXのアドレスは、プロセスYの同じアドレスと同じRAMの実際の場所を指していなかったり、単に無効だったりする場合があります。プロセスがアドレス空間外のポインターを逆参照しようとすると、別のプロセスの空間には到達せず、どこ到達しません

  • OSは、例外が発生したときに何が起こるかを決定します。無効なメモリアクセス(セグメンテーション違反、一般保護違反など)を行うプロセスを終了できます。これは、スワッピングの実装方法でもあります。例外ハンドラは、スワップスペースから一部のデータをフェッチし、それに応じてTLBを更新し、アクセスを再実行することを決定する場合があります。

プロセスが独自のTLBを変更できないため、MMUがセキュリティを提供することに注意してください。OSカーネルのみがTLBを変更できます。TLBのアクセス許可の変更方法は、この回答の範囲外です。


6

1)セグメンテーション違反は、メモリ管理ユニットによって検出されます。メモリを要求すると、OSはメモリ管理ユニットにハードウェアから一部を取得するように要求します。OSが提供するすべての大きなメモリブロックを追跡するものが必要です。OSの種類は、MMUに渡されます。それはあなたに与えたすべてのメモリを知っているので、あなたが割り当てから得られなかったメモリの場所にアクセスしようとすると、それはあなたにも伝えることができます。最終的に、OSがアプリを強制終了し、セグメンテーション違反または他のOSで同等のものをトリガーします。

すべてのOSがこの保護を備えているわけではありません。MMUはこれをサポートしていましたが、9までのMacOSにはこれがありませんでした。どちらも勝ちません3.1。Win95には保護がありませんでしたが、その後、いくつかの保護が追加されました。

2)OSはこれ以外の詳細を知りません。割り当てたことのないメモリにアクセスする浮遊ポインタがある場合、それは認識しています。アプリケーションの別の部分に入るものがある場合、それはもちろんわかりません。これを破壊できます。これは、アプリからの浮遊ポインターがアプリの他の部分を上書きして、破損したスタックを取得する場所です。

それで、はい、あなたはあなた自身のデータを台無しにすることができます。独自のアプリを上書きする浮遊ポインタがある場合、スタックに戻ることを試みるときに別の違反が発生する可能性があるため、スタックにヒットすることを期待しますが、独自のデータにヒットすると、あなたは決して知りません。

「保護なし」よりも厳密にしようとすることができます。MMUをもう少し動作させ、さらに検出させるためのElectric Fence(http://perens.com/FreeSoftware/ElectricFence/)と呼ばれるツールがあります。障害。


さて、あなたはそれがどのように機能するかについてより具体的にすることができますか?同様に、特定のプロセスが特定の場所にアクセスできないことをどのように知るのでしょうか?どのプロセスがどこにアクセスできるのか?どのように区別しますか?ありがとう
ドディ

1
@panic-ウィキペディアでMemory_management_unitとそのページからのリンクを検索します。プロセス状態にはMMUステータスが含まれることに注意してください。MMUの設計、機能、統合に学期を費やすことができます。
mpez0
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.