web-dev-qa-db-ja.com

符号なし整数を使用すると、整数オーバーフロー攻撃からどのように保護されますか?

CまたはC++での整数オーバーフローの問題を回避するために、一部の人々は符号なし整数を使用することを提案しています。これにより、オーバーフロー攻撃の可能性からどのように保護できますか?符号なし整数は、その最大値を超えてインクリメントされると、最終的にはオーバーフローしませんか?

4
Fumerian Gaming

符号なし整数を使用しても、オーバーフローは防止されません。あ kビット変数は2のみを表すことができますk 異なる値。ビットをどのように解釈しても。

おそらくあなたが参照しているのは、CおよびC++でのsigned整数オーバーフローが であるという事実です。未定義の動作 。つまり、CまたはC++の国際標準では、このようなオーバーフローをトリガーするプログラムの動作は指定されていません。値をラップするか、ランタイム例外を発生させることは、エクスプロイトシェルを開くのと同じくらい有効なオプションです。 (もちろん、正しい実装は後者を選択しません。しかし、悪用はさらなる結果を通じて可能になる可能性があります。)さらに、コンパイラーは、符号付きオーバーフローが発生しないという仮定に基づいて最適化でき、たとえば、 if (x + 3 < x)などの見当違いのオーバーフローチェック。

一方、unsigned整数の場合、CおよびC++の国際標準では、あたかも算術演算のように値をラップする必要があります。 kビット符号なし整数は2を法として行われましたk。これは、プログラムがラップアラウンドを信頼して、その利益のために使用できることを意味します。 (または自分自身を足に撃つために。)

Javaのような他の言語は、符号付き整数に対しても信頼できるラップアラウンドを要求します(Javaには符号なし整数型さえありません。)

ただし、セキュリティについて言えば、オーバーフローによって引き起こされる最大の脅威は、アプリケーションロジックがラップアラウンドを予測しないことです。そして、これは、符号付き整数型と符号なし整数型のどちらを使用しているかに関係なく問題です。アプリケーションロジックが、  バイト、それはのバッファを割り当てる必要があります メートル バイト(小さな定数の場合 メートル たとえば、簿記に使用される)および  たまたま メートル 整数が保持できる最大値を下回ると、ラップアラウンドによってプログラムが小さすぎるバッファーを割り当て、その結果、オーバーランが発生します。悪用があります。

安全にしたい場合は、全体で符号なし整数演算を使用する代わりに、正反対のことを行うことをお勧めします:signed整数演算を使用し、-でコンパイルします UbSan 。アプリケーションの計算が重い場合を除き、実行時のオーバーヘッドはわずかですが、予期しないイベントが発生してアプリケーションが整数をオーバーフローした場合、サニタイザーによって追加された追加のコードは、攻撃者がアプリケーションを悪用する前にアプリケーションを強制終了します。オーバーフローunsigned整数型に対する同様のサニタイザは、標準がそうするために明確に定義された動作を必要とし、プログラムが合法的にそれに依存するため、作成できません。これは実際には、言語の未定義の動作がアプリケーションmoreを安全にするのに役立つ可能性がある1つのケースです。

9
5gon12eder