18

私は最近、Microsoftが安全なプログラミングショップでの機能を禁止していると主張する記事に出くわしました。memcpy()関数に固有の脆弱性は理解していますが、その使用を完全に禁止する必要がありますか?

私が書いたプログラムはmemcpy()完全に回避するべきですか、それとも単に安全に使用されることを保証するべきですか?同様であるがより安全な機能を提供する代替案は何ですか?

4

10 に答える 10

31

Microsoft は、パラメーターを検証する memcpy および wmemcpyの代替手段を提供しています。

memcpy_s は次のように述べています。宛先の要求されたサイズにコピーするように要求されました;呼び出しがこれらすべてのテストに合格した場合にのみ、コピーを実行します。」

memcpy は、「宛先をレジスターに詰め込み、ソースをレジスターに詰め込み、カウントをレジスターに詰め込み、MOVSB または MOVSW を実行する」と言います。(ジオシティーズの例、この世界では長くない: http://www.geocities.com/siliconvalley/park/3230/x86asm/asml1013.html )

編集: memcpy へのYour Wish Is My Commandアプローチのワイルドな例として、OpenSolaris を検討してください。ここで、memcpy は (一部の構成では) bcopy で定義されbcopy (一部の構成では) は ... です。

void
     33 bcopy(from, to, count)
     34 #ifdef vax
     35     unsigned char *from, *to;
     36     int count;
     37 {
     38 
     39     asm("   movc3   12(ap),*4(ap),*8(ap)");
     40 }
     41 #else
     42 #ifdef u3b      /* movblkb only works with register args */
     43     unsigned char *from, *to;
     44     int count;
     45 {
     46     asm("   movblkb %r6, %r8, %r7");
     47 }
     48 #else
     49     unsigned char *from, *to;
     50     int count;
     51 {
     52     while ((count--) > 0)
     53         *to++ = *from++;
     54 }
     55 #endif

編集:ありがとう、ミリー・スミス!上でリンクした geocities ページの内容は次のとおりです。

MOVS

命令 movs は、ソース文字列を宛先にコピーするために使用されます (はい、移動ではなくコピー)。この命令には、movsb と movsw の 2 つのバリアントがあります。movsb (「move string byte」) は一度に 1 バイトを移動しますが、movsw は一度に 2 バイトを移動します。

一度に数バイトを移動したいので、これらの movs 命令は、rep プレフィックスを使用してバッチで実行されます。移動回数は CX レジスタで指定します。以下の例を参照してください。

:
lds   si, [src]
les   di, [dest]
cld
mov   cx, 100
rep   movsb
:

この例では、src から dest に 100 バイトをコピーします。movsb を movsw に置き換えると、代わりに 200 バイトがコピーされます。rep プレフィックスを削除すると、CX レジスタは無効になります。1 バイト移動します (movsb の場合は 1 バイト、movsw の場合は 2 バイト)。

于 2009-05-15T17:57:27.383 に答える
9

気にしないでください。マイクロソフトの代替品は、それほど優れているわけではありません。主な値は、これらによりコードが Linux に移植できなくなることです。Microsoft は、あなたが購入した Visual C++ のコピーよりも、顧客に販売する OS ではるかに多くの利益を上げています。

于 2009-10-15T12:14:48.780 に答える
8

チェーンソーは正しく使えば安全です。memcpy() でも同じです。しかし、どちらの場合も、釘を打つと飛んで怪我をする可能性があります。

要するに、低レベルのコンピューティングには memcpy() が必要であり、なくなることはありませんが、高レベルのプログラミングには必要ありません。Python には memcpy() はありません。

于 2009-05-15T17:54:58.713 に答える
6

この記事自体では、より安全な代替手段として、ターゲットの最大長を指定する必要がある memcpy_s について説明しています。コピーするバイト数とは無関係にその数値が提供されると、バッファ オーバーフローを防ぐためのバリアとして機能します。もちろん、両方に同じ番号を与えることで、それを悪用することができます。

于 2009-05-15T17:55:37.497 に答える
3

コードで memcpy() を禁止すると、より優れたプログラマーになり、アプリケーションがより安全になりますか、それとも互換性がなくなりますか? MS が本当に何かを変更したいのか、それとも単に新しい C コードを他のコンパイラと互換性のないものにしたいのか、私にはわかりません。ところで。MS は多くの関数でこのトリックを実行しますが、これは非常に面倒です。strcpy -> strcpy_s -> StringCchCopy.

于 2009-06-14T15:47:32.360 に答える
2

私は、C は自分の足を撃つオプションをプログラマーに任せるべきだと思います。手動のメモリ管理は、適切に行えば安全です。

于 2009-05-15T18:42:56.320 に答える
2

あなたは自分で言った:「マイクロソフトは安全なプログラミングショップで memcpy() 関数を禁止しています。私は関数に固有の脆弱性を理解しています。」

memcpy() やその他の多くの標準関数が脆弱性を引き起こすことが知られているのに、(漸進的ではあるが) 改善が取るに足らないものであるのに、セキュアなプログラミング ショップがそれらの使用を許可するのはなぜでしょうか?

自社製品のセキュリティを向上させる取り組みにおいて、コード レビューは、これらの関数が脆弱性やバッファ オーバーフローなどの大部分の原因であることを明確に示しました。内部使用専用のラッパーを作成するのではなく、それらを標準ライブラリに導入しました。すべての利益のために、コンパイラの警告 (禁止ではありません) を追加しました。

于 2009-10-15T12:05:19.797 に答える
-1

別の方法はmemcpy_sを呼び出すことです

于 2009-05-15T17:55:53.797 に答える
-2

代わりに memcpy_s() を使用することになっています。安全でないと見なされる他のさまざまな関数に対して、同じ種類の _s バージョンが存在します。

于 2009-05-15T17:56:16.183 に答える