履歴があると思いますが、スタックが下向きに成長するのはなぜですか?
スタックが上向きに成長した場合、バッファオーバーフローはlotを利用するのが難しくなるようです...
I believeこれは、メモリが非常に限られていた、コンピューティングのごく初期の段階から来ており、スタックで排他的に使用するためにメモリの大きなチャンクを事前に割り当てることは賢明ではありませんでした。したがって、アドレス0から上にヒープメモリを割り当て、メモリの終わりから下にスタックメモリを割り当てることにより、ヒープとスタックの両方が同じメモリ領域を共有するようにすることができます。
もう少しヒープが必要な場合は、スタックの使用に注意する必要があります。さらにスタックが必要な場合は、ヒープメモリを解放してみてください。もちろん、その結果、スタックがヒープを上書きすることがあり、その逆の場合もあるので、その結果、ほとんどが見事なクラッシュでした。
当時、interwebzはなかったため、バッファオーバーランの悪用の問題はありませんでした。 (または、少なくともinterwebzが存在する範囲で、それはすべて米国国防総省の高セキュリティ施設内にあったため、悪意のあるデータの可能性をあまり考慮する必要はありませんでした。)
その後、ほとんどのアーキテクチャでは、同じアーキテクチャの以前のバージョンとの互換性を維持することがすべての問題でした。そのため、今日も逆さまのスタックが残っています。
プログラムメモリは伝統的に次のように設定されています
code
constants
heap (growing up)
...
stack (growing down)
ヒープとスタックを交換できます
しかし、スタックが逆方向に進んだ場合、バッファオーバーフローは引き続き悪用される可能性があります
古典的なstrcpy
を例にとります
foo(char* in){
char[100] buff;
strcpy(buff,in);
}
スタックメモリとして
ret foo
arg in
buff array
ret strcpy
buf pointer
in
これは、コピーが行われるとき、strcpy
の戻りアドレスは(foo
の戻りアドレスではなく)バッファーの後ろにあり、in
にあるもので上書きできることを意味します
一部のハードウェアは、ヒープがハイメモリから始まり、成長していきますが、スタックはローメモリから始まり、成長します。
特にHPのPA-RISCハードウェアがこれを行います: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php
由緒あるMulticsオペレーティングシステムは、スタック(おそらく多くの1つ)が成長するハードウェア上で実行されました。参照 http://www.acsac.org/2002/papers/classic-multics.pdf セクション2.3.2:
3番目に、Multicsプロセッサのスタックは、負の方向ではなく正の方向に成長しました。これは、実際にバッファオーバーフローを達成した場合、独自のリターンポインターではなく、未使用のスタックフレームを上書きして、悪用をさらに困難にすることを意味します。
それはかなり興味深い発言です。バッファオーバーフローは、「通常の」プロシージャコールスタックフレームの配置のためだけに、それほど大きな問題になりましたか?また、Totally InvulnerableとしてのMulticsの評判は、ハードウェア設計の突発的なものでしたか?