私はコンピューター/暗号などに関する本を読んでいます。そして、ライターは私にとってあまり意味がないようなものを使用することがstrncpy(dest, src, strlen(src));
よくstrcpy(dest, src);
あります。まあ、私はプロのプログラマーです。
問題は、それは本当に本当の違いを生むのかということです。実際のアプリケーションはこのようなものを使用しますか?
私はコンピューター/暗号などに関する本を読んでいます。そして、ライターは私にとってあまり意味がないようなものを使用することがstrncpy(dest, src, strlen(src));
よくstrcpy(dest, src);
あります。まあ、私はプロのプログラマーです。
問題は、それは本当に本当の違いを生むのかということです。実際のアプリケーションはこのようなものを使用しますか?
作者はほぼ間違いなくstrn*
機能を悪用しています。strn*
残念ながら、関数は実際には必要なことを実行しないため、関数を使用する正当な理由はほとんどありません。
strcpy
見てみましょうstrncpy
:
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
関数は、末尾を含めてにstrcpy
コピーsrc
します。それはめったに役に立ちません:dest
\0
ソース文字列が宛先バッファに収まることがわかっていない限り、バッファオーバーフローが発生します。バッファオーバーフローはセキュリティ上の問題であり、プログラムをクラッシュさせ、プログラムが正しく動作しない原因となる可能性があります。
ソース文字列と宛先バッファのサイズがわかっている場合は、を使用することをお勧めしますmemcpy
。
比較すると、最大でのバイトをstrncpy
コピーし、残りを。で埋めます。それはめったに役に立ちません:n
src
dest
\0
ソース文字列がデスティネーションバッファよりも小さいことがわかっていない限り、結果のバッファがヌル文字で終了するかどうかを確認することはできません。結果がヌル終了であると想定した場合、これによりプログラムの他の場所でエラーが発生する可能性があります。
ソース文字列が小さいことがわかっている場合は、ここでも。を使用することをお勧めしますmemcpy
。
を呼び出した後、文字列を終了するだけで済みますがstrncpy
、結果を黙って切り捨ててもよろしいですか?ほとんどの場合、エラーメッセージが表示されると思います。
このstrcpy
機能は便利な場合もありますが、ほとんどの場合、入力の検証にあまり関心がなかった時代の遺物です。大きすぎる文字列をプログラムにフィードするとクラッシュする可能性があり、アドバイスは「そうしないでください」でした。
このstrncpy
関数は、固定サイズのフィールドでデータを送信したい場合や、フィールドの残りの部分にガベージを入れたくない場合に便利です。これは主に、人々が固定サイズのフィールドを使用していた時代の遺物です。
strcat
そのため、strncpy
最近のCソフトウェアではめったに表示されません。
ただし、あなたの例は両方の世界の最悪のものを組み合わせています。このソースコードを調べてみましょう。
strncpy(dest, src, strlen(src));
これは、ターミネータなしで、境界チェックなしで、にコピーsrc
されます。これは、 (境界チェックなし)の最悪の側面と(ターミネーターなし)の最悪の側面を組み合わせたものです。このようなコードが表示された場合は、逃げてください。dest
\0
strcpy
strncpy
優れたCコードは通常、文字列を操作するためのいくつかのオプションの1つを使用します。
snprintf
固定バッファを気にしない限り、固定バッファとを使用してください。
strlcpy
およびのような有界文字列関数を使用しstrlcat
ます。これらはBSD拡張機能です。
文字列の長さを追跡するカスタム文字列ポイントを使用し、とを使用して独自の関数を記述しmemcpy
ますmalloc
。
そのコードが本から逐語的にコピーされている場合、作成者はCを知らないか、セキュリティスペシャリストではないか、またはその両方です。
また、彼が誤って構成されたコンパイラーを使用していて、潜在的に危険であることがわかっている特定の関数の使用を明示的に禁止している可能性もあります。そして、コンパイラーが安全なものと安全でないものと潜在的に危険なものを区別できず、常に邪魔をしている場合、それは疑わしい慣行です。
strcpyに対するstrncpyの使用は、その実行速度とはほとんど関係ありませんが、strncpyは、バッファオーバーフロー攻撃の可能性を大幅に低下させます。Cでは、ポインターは最も強力ですが、システムを脆弱にします。
優れたハックプルーフの本からの抜粋に従うと、役立つ場合があります。
多くのオーバーフローバグは、不適切な文字列操作の結果です。strcpy()などの呼び出しは、文字列をコピーする前に文字列の長さをチェックしません。その結果、バッファオーバーフローが発生する可能性があります。NULLターミネータが存在することが予想されます。ある意味では、攻撃者はマシンを悪用するためにこのバグに依存しています。ただし、攻撃者が挿入したバッファにもNULL文字が含まれていてはならないことも意味します。攻撃者がNULL文字を挿入すると、ペイロード全体を挿入する前に文字列のコピーが終了します。
strnファミリの理由は、バッファがオーバーフローしないようにするためです。呼び出し元からデータが渡され、データが適切にnullで終了し、コピー先のバッファをオーバーフローしないことを盲目的に信頼している場合、バッファオーバーラン攻撃によって所有されることになります。
効率の違いはごくわずかです。strnファミリは、オーバーフローしていないことを確認し続ける必要があるため、少し遅くなる可能性があります。
strncpy(dest、src、strlen(src)); strcpy(dest、src);と同じです。ですから、ここでは違いはありませんが..
文字列の長さがわからないため、Strcpyはセキュリティホールにつながる可能性があります。賢い人がこれを使ってサーバー上の何かを上書きすることができます。