理論的には、システム上のすべての未使用メモリを割り当てるプログラムを構築し、他のアプリケーションが不要になったメモリを解放するにつれて、ますます多くのメモリを要求し続けると、最近解放されたメモリを別のアプリケーションから読み取ることができます。 ?または、これはどういうわけか最新のオペレーティングシステムによって保護されていますか?
これには実用的なアプリケーションはありません。興味があるだけです。実際に「利用可能なすべてのメモリ」を割り当てることにはいくつか問題があることに気づきました。
編集:明確にするために、私は「解放された」メモリについて具体的に尋ねています。現在、別のアプリケーションによって割り当てられているメモリにはアクセスしていません。
いいえ、適切なカーネルはプロセスに発行される前にメモリの内容をワイプして、提案された種類の攻撃から正確に保護します。
Unixyシステムでは、メモリはプロセスに割り当てられますプログラムブレークと呼ばれるものを拡張することにより、これはプロセスが使用できる仮想アドレス可能なスペースの制限です。プロセスは、アドレス可能なスペースを拡張することをカーネルに通知し、メモリが利用可能な場合はカーネルがそれを許可し、そうでない場合は呼び出しが失敗します。 (brk()
システムコールの名前は、この概念に由来しています。)
実際には、解放されたメモリの大きなブロックがプログラムブレークにぶつかることはあまりありません。これは、プロセスがプログラムブレークを縮小してカーネルにメモリを返すために必要なものです。もちろん、これはシステムのmalloc()
およびfree()
の実装に依存します。利用可能なソースがある場合、メモリが返されるかどうかが通知されます。
malloc()
を介して取得したものはすべてスクラブされ、以前のbrk()
dは同じプロセスによって書き込まれたため、メモリを初期化しないfree()
のセキュリティへの影響はありません。 。
はい、別のプロセスが解放したメモリを読み取ることは理論的には可能です。これは、当時の多くの特権昇格攻撃の元でした。そのため、オペレーティングシステムは、以前に別のプロセスによって割り当てられていた場合、今日では効果的にメモリをゼロにしています。常にメモリがゼロになっているとは限らないのは、以前に同じプロセスによって割り当てられたメモリをゼロにしないほうが効率的だからです。 OSは、可能であればメモリページを同じプロセスに返そうとします。
ここには、回答に影響を与えるいくつかの層があります。
最新の仮想メモリオペレーティングシステムを想定している場合は、割り当てたページで別のプロセスデータの残りを確認できません。
プロセスが最初に読み込まれると、ページテーブルが読み込まれ、実際のメモリのフレームがそれらのページに割り当てられる可能性があります。少なくとも、ページテーブルまたはその補足テーブルには、プロセスが割り当てることができるすべてのメモリのマップが含まれます。これは、上記の最初のプロセスブレークが設定される場所でもあります。
Malloc()は、プロセスが許可されている場合、プロセスブレークを変更させ、要求を満たすためにプロセスページ(補足ページ)テーブルにページを追加しますが、あるプロセスが「別のプロセスを取得」してデータを処理する場所は下の実メモリー層。
これらのシナリオの両方で、デマンドページングまたは遅延割り当てを使用する最新のオペレーティングシステムは、まだ物理メモリ(フレーム)を割り当てていません。オペレーティングシステムは、そのプロセスのどの仮想メモリが有効であると見なされるかについて単に「メモ」を作成しています。実際のメモリは、必要な場合にのみ割り当てられます。
物理メモリまたはフレームは、仮想ページが実現され、プロセスページテーブルにマップされると、プロセスに割り当てられます。これは、データ漏洩の可能性が存在する場所です。これは、ページ不在時に発生します。以前のプロセスが同じフレームを使用していた可能性があり、現在の物理メモリ要求のためのスペースを空けるために、そのデータが破棄またはスワップアウトされたためです。オペレーティングシステムは、プロセスを再開する前に、要求しているプロセスデータが適切にスワップインされるか、フレームがクリア(ゼロ)されるように注意する必要があります。これは、「古いが解決された」問題として上記でも説明されています。
これにより、他のプロセスのメモリが「解放」されたかどうかに関係なくなります。別のプロセスの「解放された」メモリは、そのプロセスに割り当てられたページにまだ存在し、メモリが少なくなったとき、または他の方法で追い出されたときにスワップアウトされるため、プロセスが終了するまで、通常はマップ解除されません。 malloc()およびfree()は、(ユーザー)レベルでプロセスに割り当てられた仮想メモリを管理します。
あなたの質問では、あなたのプロセスは理論的にはますます多くのメモリを要求し続け、他のすべてのプロセスをメモリから押し出します。実際には、グローバルおよびローカルのフレーム割り当て戦略があり、これらも回答に影響を与える可能性があります。オペレーティングシステムと他のすべてのプロセスのオーバーランが許可される前に、プロセスが自身のページをメモリから強制的に解放する可能性があります。これはあなたの最初の質問を超えていますが。
これはすべて、MS-DOSのようなシステムでは意味がありません。 MS-DOS(およびその他のより単純なシステム)は仮想メモリを(それ自体で)使用しないため、別の「プロセス」データを簡単に突くことができます。
Linuxのソースコードよりも理解しやすいいくつかの優れたリファレンスは、優れたオペレーティングシステムのテキストブック、Silberscatz、Gavin、およびGangeによるオペレーティングシステムコンセプト、またはAndrew Tanenbaumによるオペレーティングシステムデザインです。また、BerkeleyのNachosやStanfordのPintosのようなものは、学習用に構築された小さなオペレーティングシステムであり、その中に同じ考え方があります。
私はこれをUbuntu 16.04か月前に試しました。 0xACEと同じように、malloc()を呼び出すと、最新のOSはすべてゼロの仮想ページを割り当てます。ただし、割り当てられたバッファに何も書き込まない場合、それは物理メモリにマップされません(つまり、コピーオンライトの原則)。したがって、「初期化されていない」ブロックから常にゼロを読み取ります。パフォーマンスを向上させるために「CONFIG_MMAP_ALLOW_UNITIALIZED」オプションを使用してコンパイルされた一部の組み込みOSが存在する場合があります。この場合は、期待どおりの結果が得られます。