0

私はこれがスタックオーバーフローに対して脆弱であると言った本の以下のコードを読みました。fgets()を使用しましたが、理解できませんでしたが、なぜ脆弱なのですか?

私の理解では、gets()の代わりにfgets()を使用すると、通常、最後にnullを配置することで、バッファオーバーフローを取り除くことができます。私は何かが足りないのですか?スタックオーバーフローを修正するには、fgets()の代わりに何を使用する必要がありますか?

void getinp(char *inp, int siz)
{
   puts("Input value: ");
   fgets(inp, siz, stdin);
   printf("buffer3 getinp read %s\n", inp);
}

void display(char * val)
{
   char tmp[16];
   sprintf(tmp, "read val: %s\n", val);
   puts(tmp);
}

int main(int argc, char *argv[])
{
   char buf[16];
   getinp(buf, sizeof(buf));
   display(buf);
   printf("buffer3 done\n");
}
4

2 に答える 2

1

Indisplay tmpは 16char秒の長さと宣言されていますが、( 16 文字以下であることが保証されているsprintf) そこだけでなく、最後の) も書いています。val"read val: "\n

これは、ユーザーが 16-11=5 文字を超える文字を挿入すると、 でバッファ オーバーフローが発生することを意味しますdisplay

1 つの解決策は、両方と追加のテキストを格納するのに十分な大きさであると宣言bufすることです。ただし、現実の世界では、(中間バッファーなしで)を使用して書き込むだけです。displayvalstdoutprintf

また、通常、sprintfバッファオーバーフローの潜在的なリスクがある場合はsnprintf、代わりに使用します(実際、私は常に使用しています)。snprintf、バッファーをオーバーフローさせる代わりに、出力が長すぎる場合は切り捨て、出力バッファーが十分に大きい場合に書き込まれた文字数を返します。

于 2012-11-05T01:43:57.363 に答える
0

表示では、val+12バイトが16文字のバッファーに収まるかどうかを確認する方法はありません。

于 2012-11-05T01:42:44.053 に答える