* OSECPUが検出できる脆弱性 -(by [[K]], 2012.09.25) ** 一覧 -(以下の記述は仕様に基づいている。実装にバグがあって抜け穴ができている可能性はある。) --もしそんなものがあったら、それはもちろん直さなければいけない。 -任意のx86コードを実行できるか? --アプリにはできない。特権レベル3の命令も含めてできない。OSにはできる。 --試みてOSに検出されて止まるのではなく、そもそも方法がない。 ---以下これくらいにできないことを単に「できない」と書く。 --なお、任意のOSECPU命令を実行することはできる。しかしもちろん不正な命令については害を及ぼす前に実行を差し止められる。 -任意のアドレスに分岐できるか?(jmpやcallやretなど) --できない。これも試みてOSに検出されて止まるのではなく、そもそも方法がない。 --原理を説明すると、まずOSECPUではラベルにしかjmpできない。 --callやret命令はない。 ---callに相当することをしたいときは、リターンアドレスを自分でスタックなどに積んだ上で、jmpすればよい。このリターンアドレスは当然ラベルになっていなければいけないので(そうでないと値が取れない)、OSECPUアプリはかなりたくさんのラベル文が必要になる。 ---retについても、スタックから値を持ってきてそこにjmpすることで代用できる。 ---[2014.06.20追記] 結局リターンアドレスはP30で渡すことになりました。したがってret命令の代わりにJMP(P30);を実行しています。 --ラベルはポインタ型のレジスタもしくはポインタ型のメモリ上にしか代入できない。ポインタ型に対してできる演算は非常に限定されていて、任意の値を入れることができない。C言語の常識とは異なり、ラベル(コードのアドレス)が格納されているポインタ型レジスタに対してはインクリメントもデクリメントも加算も減算もできない。メモリに対してはどのみち同型のレジスタへの読み書きしかできず、値を変化させるような演算の命令は命令セット上に存在しない。 ---ちなみに、データの配列をポイントしている場合も、配列の外に出るようなポインタ操作をすれば(そのポインタを使わなくても)即座に脆弱性検出例外になる。この例外はアプリで例外処理することができず、必ずOSによって停止処分か強制終了にされる。 ---[2014.06.20追記] 結局ポインタは自由に加算も減算もできるようになりました。しかし不正な場所を指した状態でアクセスしようとすれば、その時点でセキュリティ例外になります。 -freeした後でそのオブジェクトにアクセスしたらどうなるか? --脆弱性検出例外になる。 --これは試みることができるタイプ。そういうことをしようとするコードを書くことはできる。しかしこれをやろうとすると即座に脆弱性検出例外になる。 -32bit整数のメモリ域を8bit整数で読み書きしたらどうなるか?(エンディアンは?) --読み書きできない。直ちに脆弱性検出例外になる。 --したがってOSECPUにおいてエンディアンが問題になることはない。上位8bitの値が知りたいのなら、32bitでメモリアクセスしてレジスタに格納した後で、24bitの右シフトをすればいいだろう。下位8bitの値がほしいのであればリードした後にマスクすればいい。 --要するに不可分なオブジェクトの一部だけを読み書きすることはできない。unionに相当する機能もない。 --要するに分割不能なオブジェクトの一部だけを読み書きすることはできない。unionに相当する機能もない。 ** こめんと欄 -このページにこめんと欄はありません。このページの内容にコメントしたいときは[[impressions]]にお願いします。