整数オーバーフローの場合の結果は(unsigned int) * (int)
? unsigned
またはint
?operator[]
配列インデックス演算子 ( ) は、char*
:int
などにどのような型をとりunsigned int
ますか?
私は次の関数を監査していましたが、突然この質問が発生しました。この関数には 17 行目に脆弱性があります。
// Create a character array and initialize it with init[]
// repeatedly. The size of this character array is specified by
// w*h.
char *function4(unsigned int w, unsigned int h, char *init)
{
char *buf;
int i;
if (w*h > 4096)
return (NULL);
buf = (char *)malloc(4096+1);
if (!buf)
return (NULL);
for (i=0; i<h; i++)
memcpy(&buf[i*w], init, w); // line 17
buf[4096] = '\0';
return buf;
}
w
と の両方を考慮してくださいh
。非常に大きな符号なし整数です。9 行目の乗算は、検証に合格する可能性があります。
問題は 17 行目です。掛け算: 結果が の場合int i
、積が負になる可能性があり、結果として の前の位置にアクセスすることになります。結果が の場合、積は常に正になり、 の後の位置にアクセスすることになります。unsigned int w
int
buf
unsigned int
buf
これを正当化するコードを書くのは難しいです:int
は大きすぎます。誰かがこれについてアイデアを持っていますか?
製品のタイプを特定するドキュメントはありますか? 私はそれを検索しましたが、これまでのところ何も見つかりませんでした。
コンパイルされたオブジェクトファイルでは、それらは単なるバイトであるため、脆弱性に関する限り、(unsigned int) * (int)
生成するunsigned int
かどうかは問題ではないと思います。int
次のコードは、製品のタイプに関係なく同じように機能します。
unsigned int x = 10;
int y = -10;
printf("%d\n", x * y); // print x * y in signed integer
printf("%u\n", x * y); // print x * y in unsigned integer
したがって、乗算が返す型は問題ではありません。int
消費者関数が取るかどうかが重要ですunsigned
。
ここでの問題は、その機能がどれほど悪いか、または機能を改善するためにどのように機能を改善するかではありません。この機能には間違いなく脆弱性があります。問題は、標準から規定された動作に基づいた、関数の正確な動作に関するものです。