Secure C と大学 - バッファ オーバーフローの訓練を受けています

StackOverflow https://stackoverflow.com/questions/483018

  •  20-08-2019
  •  | 
  •  

質問

私は最近大学の C コースを修了しました。なので当然経験不足です。

一部の大学は学生に安全なプログラミングを教える傾向がありますが、 または少なくともいくつかの要素. 。あるよ ビデオでも (から抜粋 ここ).

C で文字列をコピーするには、私の知る限り、strcpy または string.h 関数が必要です。日常のプログラミングで安全に使用するにはどうすればよいでしょうか?バッファオーバーフローを防ぐために割り当てを処理する関数はありますか?そこにあるのは、 C の CERT セキュア コーディング標準. 。例と準拠したソリューションを提供しています。

int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[128];
  strcpy(prog_name, argv[0]);
  /* ... */
}

そして、その代替案は次のとおりです。

int main(int argc, char *argv[]) {
  /* ... */
  char *prog_name = (char *)malloc(strlen(argv[0])+1);
  if (prog_name != NULL) {
    strcpy(prog_name, argv[0]);
  }
  else {
    /* Couldn't get the memory - recover */
  }
  /* ... */
}

ここから引用すると、 2番目の例.

しかし、私が理解する限り、それは単により困難で、より多くのコードとより多くの作業を伴うだけです。なぜ誰もライブラリ自体を変更しないのでしょうか?あるいは少なくとも、これを適切な方法で処理する安全な代替ライブラリや関数をなぜ誰も提供しないのでしょうか?

読んでくれてありがとう、wishi

役に立ちましたか?

解決

このための Posix 関数 (ほぼすべてのシステムで利用可能) は次のとおりです。 strdup(). strcpy() 新しいメモリを割り当てたくないが、使用したいバッファがすでにあるが、そのバッファの大きさと文字列がバッファに収まるかどうかをよりよく知っている場合に使用します。文字列が合うかどうかわからない場合は、 strncpy() 指定された数の文字をコピーするだけです。したがって、コピー量をバッファサイズに制限できます。

それに加えて、文字列サイズをさまざまな方法で管理するスティング ライブラリがたくさんあります。

そして、C++ のタグを付けたので、次のようになります。がある std::string これはメモリ管理をすべて行ってくれるので、こうした問題は発生しません。

他のヒント

(strlcpy、strlcat) 関数から OpenBSD 通常はより優れています n これらの機能は高速で安全に使用するのが簡単ですが、標準ではありません。ただし、BSD ライセンスが付与されているため、既知の適切な実装を任意のプログラムに含めることができるため、クロスプラットフォームと安全性の両方を実現できます。

Windows の場合、移植性を気にしない場合は、*_s 関数を使用できます。

使用 strncpy:

#define BUFSIZE 127
int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[BUFSIZE + 1];
  strncpy(prog_name, argv[0], BUFSIZE);
  progname[BUFSIZE]= '\0';
  /* ... */
}

がある *n* ほとんどのバージョン str* 機能。

私の理解が正しければ、あなたの本当の質問は、なぜ API 関数の安全性を高めないのかということです。

理由の 1 つは、C ライブラリがレガシーである (今変更するには遅すぎる) ことです。

ただし、主な理由は、ライブラリが最小限の機能を実行するように設計されており、ライブラリが正しく呼び出されることを確認するのはユーザーの責任であるためです。過剰なチェックを行っていた場合、たとえユーザーが別の理由で問題が起こらないと保証できたとしても、呼び出されるたびに料金が支払われることになります。これは多くの API で非常に一般的です。

そうは言っても、より安全な代替手段を提供するライブラリは十分にありますが、それらは標準ライブラリの一部ではないだけです。また、より高レベルの作業を行う人の多くは、C++ を使用して作業します。C++ には、それらの作業の多くに対応する標準クラス ライブラリがあります。

実際、Microsoft は CRT 機能に代わる安全な機能を提供していました。しかし、私が知っている人は皆、古い機能を嫌っていて、古い機能を使用すべきではないという警告を無効にしています。安全なものが必要な場合は、C++ を使用する必要があるかもしれません。次に、STL 文字列または Qt のようなものです。

あるいは、.NET や Java などのプラットフォームを使用する場合、これらの問題は通常は発生しません (アプリがクラッシュする可能性はありますが、バッファ オーバーフローを通じてアプリにコードを挿入する方法はありません)。

編集:データ実行防止/NX が有効になっている場合 (Vista および .NET のデフォルト)、これは従来のプラットフォームでも問題になりません。

int main
(
    int argc, 
    char *argV[]
) 
{
   char prog_name[128];
   if (strlen(argV[0]) < sizeof(prog_name))
   {
       strcpy(prog_name, argV[0]);
   }
   else
   {
       printf("%s is too large for the internal buffer\n", argV[0]);
   }

   return 0;
}

もしかしたら、役に立つ読書の答えが見つかるかもしれません この質問

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top