2013-03-13 50 views
5

どちらもバッファオーバーフローの可能性があります。しかし、私はgets()を使うことは絶対に勧められませんが、scanf()を使うことを勧めました。gets()がscanf()よりも危険なのはなぜですか?

これは、scanf()で許可されている書式設定の引数が原因か、それ以外の理由はありますか?

+0

gets()はエンドラインをフィルタしません – noMAD

+3

おそらくgets()が絶望的ですが、scanfを使うと、入力の長さを制限するという苦痛に遭うと、バッファオーバーフローを避けることができます。 every ** ** single ** ** time ** – loreb

+0

IIRC 'gets()'は '\ n 'がなくても' EOF'を返します。 – pampeho

答えて

8

gets関数は、バッファオーバーフローから保護されていません。

フォーマット文字列scanfを使用すると、標準入力から読み込んで指定のメモリバッファに格納する文字列の最大長を定義できます。たとえば、scanf("%10s\n", str);の場合、最大10文字が読み取られます。 strバッファはNULL終端文字を格納するために11バイトでなければなりません。

パフォーマンス面では、scanfを使用して、バッファオーバーフローの問題がgetsの場合のみ、代わりにfgets関数を使用することをお勧めします。

+0

私もことがわかったいくつかの研究行う:どのような文字を指定する 機能など** は のscanf()、 あなたが複数のフィールドを入力することができ が、それはまた、あなたが**構造 を入力することができますだけでなく、データフィールド間には が表示されます。 私はそれがまた心に留めておもしろいと思います。 出典:Head First C、Daivid&Dawnグリフィス。 –

+0

あなたは正しいです、 'scanf'と' gets'(または 'fgets')は同じユースケースをカバーしていません。 'fgets'を使って入力ストリームから1行を読み込みます。入力ストリームからデータを解析するのに 'scanf'を使います。これは、あなたが 'fgets'で行うように' scanf'を使って入力ストリームから1行を読むことができると言っていますが、パフォーマンスが低下します。 – greydet

1

バッファオーバーフローを防ぐ方法がないためです。 fgetsは最大バッファ長が指定されているので安全です。

+4

質問は本当に '取得'と 'scanf'です。 –

2

バッファのサイズよりも多くの文字を入力できるので、gets()はうれしくそれを許可します。さらに、gets()は廃止されました(C11)。したがって、scanf()との比較はもはや有効ではありません。 scanf()には、フォーマットされていないデータを扱うときには独自の問題があります。

したがって、より良いオプションはfgets()であり、必要に応じて処理してください。

1

getsの場合、不正な入力があった場合にバッファオーバーフローを防止することはできません。 scanfは、読み取ったデータの量を制御することができます。まだscanf関数を(使用することをお勧め

How to prevent scanf causing a buffer overflow in C?

1

)。

「scanf security」をすばやく検索すると、〜212k件の検索結果が表示されます。最初は、長さ指示子なしの%sプレースホルダの

用途は本質的に安全でないとバッファオーバーフローのために悪用されていると述べWikipedia、です。

ウェブ上にはscanfのセキュリティに関する十分な情報があります。 getsとの違いは、getsを使用している間は、実際には常に悪い考えであり、scanfは安全な使用を持つということです。

1

gets()の名目上のタスクは、ストリームから文字列を読み込むことです。発信者は、着信文字をどこに置くかを指示します。しかし、gets()はバッファ領域をチェックしません。呼び出し側がスタックへのポインタを提供し、バッファ空間より多くの入力を与えた場合、gets()はスタックを上書きします。ほとんどのシステムでは、スタックの中央にある既存のエントリを上書きすることに脆弱です。大きなエントリでは、隣接するエントリも上書きされます。悪意のある人は、正しいバイナリパターンを引数文字列に隠すことによって、スタック上のプロシージャアクティベーションレコードの戻りアドレスを修正できます。これは実行の流れを元の位置に戻さず、execv()を呼び出して実行中のイメージをシェルで置き換える特別な命令シーケンスに振り向けます。このシェルは、ウイルスのコピーをシステムにドラッグするコマンドを発行することができます。だからgets()は安全ではありません。

+0

これは 'scanf'がより安全な理由を説明していません。 – jamesdlin

関連する問題