データを格納するために使用される固定サイズのバイナリバッファがいくつかあります。 そして、memcpyは、バッファを別のバッファにコピーするために使用されます。ソースバッファは宛先バッファよりも大きい可能性があるためです。バッファオーバーフローがあるかどうかをどのように検出できますか?memcpyのバッファオーバーフローを防ぐには?
答えて
ソースバッファにどれくらいのデータがあり、ターゲットバッファでどれだけの空き容量があるかを知る必要があります。
ソースバッファからコピーするすべてのデータのターゲットバッファに十分な領域がない場合は、memcpy()
を呼び出しないでください。 (ソースがターゲットよりも大きい場合は、データを切り捨ててもよいかどうかを判断する必要があります)。
わからない場合は、コードを書き換えて十分なスペースがあることを確認します。それ以外の場合は、安全ではありません。
ソースバッファとターゲットバッファが重複する可能性がある場合は、memcpy()
ではなくmemmove()
を使用する必要があります。
C++では、最初にmemcpy()
を使用してください。これはC++ではなくCスタイルの操作です。
ありがとう。 C++でメモリコピーを行う正しい方法は何ですか? –
@MichaelD:データを 'std :: vector <>'に格納し、単に 'vector2 = vector1'を使用してください。 – MSalters
ベクターにデータを挿入するにはどうしたらいいですか? push_backを使用してバイトごとに日付を挿入しますか? –
srcとdestのバッファサイズは常に把握してください。
void *memcpy(void *dest, const void *src, size_t n);
n
src
またはdest
サイズよりも最大になることはありません。
場合たとえば、あなたが持っている:
先4つのバイトサイズ
ソース5つのバイトサイズ
あなたは最大で、4つのバイト先のバッファにコピーすることを確認することができます
size_t getCopySize(size_t sourceSize, size_t destSize)
{
return (destSize <= sourceSize ? destSize : sourceSize);
}
memcpy(destination, source, getCopySize(sizeof(source),sizeof(destination)));
アプリケーションでは、残りのデータが後でコピーされることを確認したり、一部のデータを無視できる場合はスキップすることもできます。
バッファオーバーフローが存在するかどうかを検出するにはどうすればよいですか?
私はあなたに3つまたは4つの選択肢があると思います。
第1の選択肢は、memcpy
に対して「安全な」機能を提供することです。これは私の所持するコードの中で私が必要とするものであり、私は定期的にそれを監査します。また、すべてのパラメータが検証され、すべてのパラメータがアサートされている必要があります。
アサーションは自己デバッグコードを作成します。私は開発者にコードを書くことを望みます。私は彼らがデバッグ時間を浪費することを望んでいません。だから私は彼らにデバッグするコードを書く必要があります。 ASSERTはまた、物事をうまく文書化するので、ドキュメンテーションを吟味することもできます。リリースビルドでは、ASSERTはプリプロセッサマクロによって削除されます。
errno_t safe_memcpy(void* dest, size_t dsize, void* src, size_t ssize, size_t cnt)
{
ASSERT(dest != NULL);
ASSERT(src != NULL);
ASSERT(dsize != 0);
ASSERT(ssize != 0);
ASSERT(cnt != 0);
// What was the point of this call?
if(cnt == 0)
retrn 0;
if(dest == NULL || src == NULL)
return EINVALID;
if(dsize == 0 || ssize == 0)
return EINVALID;
ASSERT(dsize <= RSIZE_MAX);
ASSERT(ssize <= RSIZE_MAX);
ASSERT(cnt <= RSIZE_MAX);
if(dsize > RSIZE_MAX || ssize > RSIZE_MAX || cnt > RSIZE_MAX)
return EINVALID;
size_t cc = min(min(dsize, ssize), cnt);
memmove(dest, src, cc);
if(cc != cnt)
return ETRUNCATE;
return 0;
}
あなたsafe_memcpy
戻っ非0の場合、不正なパラメータまたは潜在的なバッファオーバーフローのようなエラーが発生しました。
第2の選択肢は、Cスタンダードによって提供される「より安全な」機能を使用することです。 CはISO/IEC TR 24731-1, Bounds Checking Interfacesを介してより安全な機能を備えています。適合プラットフォームでは、gets_s
とsprintf_s
と呼ぶことができます。 (文字列が常にNULL
であることを保証するなど)一貫性のある戻り値(成功した場合は0、errno_t
など)を提供します。
errno_t err = memcpy_s(dest, dsize, src, cnt);
...
残念ながら、gccとglibcはC標準に準拠していません。境界検査インターフェイスと呼ばれるUlrich Drepper(glibcの管理者の1人)は、"horribly inefficient BSD crap"の境界チェックインターフェイスと呼ばれ、決して追加されませんでした。
第3の選択肢は、プラットフォームの「より安全な」インタフェースが存在する場合はそのインタフェースを使用することです。 Windowsでは、ISO/IEC TR 24731-1, Bounds Checking Interfacesの場合と同じです。また、String Safeライブラリもあります。
アップルとBSDでは、memcpy
の「より安全な」機能はありません。しかし、あなたはstrlcpy
,strlcat
、お友達のようなより安全な文字列関数を持っています。
Linuxでは、4番目の選択肢はFORTIFY_SOURCEです。 FORTIFY_SOURCEは、memcpy
,strcpy
、gets
などのリスクの高い機能の「より安全な」バリアントを使用します。コンパイラは、宛先バッファサイズを推測できるときに、より安全なバリアントを使用します。コピーが宛先バッファ・サイズを超える場合、プログラムはabort()
を呼び出します。コンパイラが宛先バッファサイズを推測できない場合、「より安全な」バリアントは使用されません。
テストのためにFORTIFY_SOURCEを無効にするには、プログラムを-U_FORTIFY_SOURCE
または-D_FORTIFY_SOURCE=0
でコンパイルする必要があります。
- 1. を防ぐページスクロール
- 2. ルーピングを防ぐ
- 3. デッドロックを防ぐ
- 4. フレックスデータグリッドのデータバインディングを防ぐには?
- 5. jsファイルのリダイレクトを防ぐには?
- 6. アンドロイドアプリのデコードを防ぐには?
- 7. クエリのタイムアウトを防ぐには?
- 8. NativeScript - CSSの縮小を防ぐには?
- 9. Javaの断片化を防ぐには?
- 10. ホスティングのファイル編集を防ぐには?
- 11. StaticAnnotationの型チェックを防ぐには?
- 12. Rails:レコードの削除を防ぐには?
- 13. 軸の自動スケーリングを防ぐには?
- 14. imgのオーバーフローを防ぐには?
- 15. htmlテーブルの伸びを防ぐには
- 16. イベントハンドラの実行を防ぐには?
- 17. SlidingDrawerはonTouchEventを防ぐ
- 18. HSTSを防ぐ方法は?
- 19. 防ぐC#のexeファイルは
- 20. クリック時にブートストラップモーダルクローズを防ぐ
- 21. 防ぐには、データグリッドのDevExtreme jsのデータグリッド
- 22. MVC3防ぐエディタテンプレート
- 23. SQLインジェクションを防ぐ
- 24. 孤児を防ぐ
- 25. 防ぐWindowsのシャットダウン
- 26. 防ぐ親のアクション
- 27. 防ぐページのリロードモーダル
- 28. ゼロ除算を防ぐには?
- 29. リアクタ・ルータv4 - リダイレクト・ループを防ぐには?
- 30. - を防ぐには、 "親" 要素
検出?あなたは目的地のバッファーサイズを知っていますか?このmemcpy(src、dst、sizeof(dst))のようなコードを書いてください – BSen
ソースバッファとデスティネーションバッファのサイズを比較し、どちらが大きいかを確認してください。 – SingerOfTheFall
@BSen '' sizeof''はポインタのサイズを与えるだけです。 – juanchopanza