0

Windows/Microsoft の世界で memcpy() がいかに安全でないかについて多くの議論があることは知っていますが、それは Mac OS X コード (Cocoa) にも当てはまりますか? もしそうなら、最大の安全性のために Cocoa でどの機能を使用する必要がありますか? memcpy_s() はプラットフォームに存在しないようです。

ありがとう。

更新: Windows でも memcpy() について話すことはグレーゾーンのようなものだと認識しています(安全なプログラミングの Memcpy() を参照してください? )。Mac OS X に「安全な」バージョンの memcpy() が含まれていないという事実だけでも、Apple はそれほど悪くないと感じているようです。

4

4 に答える 4

3

メモリ領域が重複する可能性がある場合は、 memcpyの代わりにmemmoveを使用する必要があります。

防御的にプログラムし、実際に何をしているかを認識していれば、それらは本質的に安全ではありません。

于 2012-04-16T12:59:31.390 に答える
2

バッファ オーバーフロー (memcpy、strcpy などのセキュリティ上の問題) は OS に依存しません。基本的に、これらは C 言語に固有の問題です。これは、自動境界チェックが提供されていないためです。

十分な注意を払って適切に使用すれば、memcpy は安全です。たとえば、パラメーターを自分で検証する場合や、コンパイル時にサイズがわかっている場合などです。しかし、誰もが間違いを犯します。

memcpy を禁止し、独自の memcpy_s を使用する MS のアプローチは、プログラマーにどこでも追加の安全性チェックを強制することでバグを減らすことです。必要に応じて、独自の memcpy_s を作成できます。難しいことではありません。MSDN ページで説明されている動作を実装するだけです。

...これは、Apple が状況はそれほど悪くないと感じていることを暗示しているようです。

当然のことながら、マイクロソフトは事態がそれほど悪いものだと感じています。ただし、企業が問題について感じていることは、その問題の存在には影響しません。つまり、memcpy への入力を検証しないことは、ある種の脆弱性の原因となります。

于 2012-04-16T13:01:34.193 に答える
2

これは非常に新しいAFAIKであり、完璧ではありませんが、GCCは__memcpy_chk可能な場合に宛先のサイズをチェックするというラッパーを提供しています。こちらをご覧ください。その使用法(同じリソースから):

 #undef memcpy
 #define bos0(dest) __builtin_object_size (dest, 0)
 #define memcpy(dest, src, n) \
   __builtin___memcpy_chk (dest, src, n, bos0 (dest))

 char *volatile p;
 char buf[10];
 /* It is unknown what object p points to, so this is optimized
    into plain memcpy - no checking is possible.  */
 memcpy (p, "abcde", n);
 /* Destination is known and length too.  It is known at compile
    time there will be no overflow.  */
 memcpy (&buf[5], "abcde", 5);
 /* Destination is known, but the length is not known at compile time.
    This will result in __memcpy_chk call that can check for overflow
    at runtime.  */
 memcpy (&buf[5], "abcde", n);
 /* Destination is known and it is known at compile time there will
    be overflow.  There will be a warning and __memcpy_chk call that
    will abort the program at runtime.  */
 memcpy (&buf[6], "abcde", 5);
于 2012-04-16T12:53:48.463 に答える
1

Microsoft には感銘を受けませんmemcpy_s()。送信先のバッファー サイズを指定するのは呼び出し元次第だからです。(ソース バッファと宛先バッファがオーバーラップする場合を除いて)うまくいかない主なmemcpy()原因は、宛先バッファが実際にどれだけ大きいかを知らないことです。

次の例に示すエラーのクラスが 1 つあると思います。

  char anArray[10]
  char* foo = anArray;
  memcpy_s(foo, sizeof foo, somewhereElse, 10);
  // or
  memcpy_s(foo, sizeof *foo, somewhereElse, 10);

ただし、これらは両方とも C ポインターの基本的な誤解を示しており、コードに関する唯一の問題ではない可能性があります。

また、目的地が小さすぎる場合はどうしますか? 切り捨てられたデータを続行しますか? 「警告: プログラマーはばかです」というエラー メッセージを出しますか? いいえ、コピーを開始する前に、宛先バッファーが十分に大きいことを知っておくことをお勧めします。

memcpy_s()また、質問のリンクでは、ヌル ポインター チェックについて説明しています。繰り返しますが、あなたは何をするつもりですか?プログラムをクラッシュさせることは、正常に実行できるすべてのことです。null ではないはずのポインターが null の場合、プログラムの実行環境のどの部分も信頼できないからです。また、最新の PC オペレーティング システムではmemcpy()、ヌル ポインターを逆参照しようとするとすぐにプログラムがクラッシュします。

于 2012-04-16T14:23:02.537 に答える