0

作業例として、次のコードを扱うことができます。

    #include <sys/socket.h>

    #define size_t   SOCKET

    int receive_socket_data(SOCKET sock,//socket representing remote connection
                            unsigned long& version_number,//validPtr->version #
                            unsigned long& message_size,//validPtr->sizeof packet
                            char*& buf // where to copy data from packet
                           )
    {
       int nlen = 0;
       buf = NULL;

       // Receive version_number from the packet
       nlen = recv(sock, (char*) &version_number, sizeof(version_number), 0);
       if (nlen == 0 || nlen == -1) return ERROR_RECEIVING;
       version_number = ntohl(version_number);

       // Receive message_size from the entire packet 
       // (ulong + ulong + sizeof data)
       nlen = recv(sock, (char*) &message_size, sizeof(message_size), 0);
       if (nlen == 0 || nlen == -1) return ERROR_RECEIVING;
       message_size = ntohl(message_size);
       // Allocate a buffer to copy the data part of the packet
       buf = new char[message_size + 1 - 2 * sizeof(unsigned long)];
       buf[message_size - 2 * sizeof(unsigned long)] = '\0';

      // Copy the data part from the packet to the buffer
      if (recv(sock, (char*) buf, message_size-2*sizeof(unsigned long), 0) == -1)
         return ERROR_RECEIVING;

      return SUCCESS_RECEIVING;
    }

たとえば、私が念頭に置いているのは、演算子newによってエラーがスローされる可能性です。
配列のインデックス計算も問題を引き起こす可能性があるかどうかはわかりません。

4

1 に答える 1

5

機能が安全であると判断するのに役立つ方法は、証明とテスト、および防御的なコーディングとレビューと経験です。

任意のコードは分析する価値がないため、防御的コーディング。コードを分析しやすくし、セキュリティを強化してから、問題を分析します。任意のプログラムを解析することはできません。そして、理論的に分析可能なものでも、難易度は大きく異なります。

関数が正しいという正式な証明のような証明。これには、コードがやり取りするすべてのものを完全に理解し、形式化する必要があります。防御的なコーディングとコードの簡素化により、これがある程度可能になることに注意してください。

テスト。なぜなら、コードが何をしていると思うかについての知識と同じようにしか証明が機能しないからです。あなたのコードのモデルは不完全かもしれません。モデルが不完全であることのばかげた例として、現在未知の物理学がコードを実行するすべてのハードウェアでビットを反転させる可能性があるというモデルはありません。コードのモデルが不完全であるというばかばかしさの少ない方法がほぼ確実に存在します。

考えもしなかったことがあるからです。より有能な人にあなたのコードが正しいと確信してもらうことで、全体として何かを見落としていない可能性を高めることができます。

どこに注意を向けるべきかを知ることが重要なので、経験してください。経験とは、過去にその失敗をどのように行ったか、または他の誰かがそれを行うのを目撃したことを思い出すことです。

セキュリティはどの程度安全でなければなりませんか? 一般に、安全なコードを書くのは簡単ではありません。これが、暗号化システムを作成する際の最初のルールが「禁止」である理由です。

  1. すべての手動バッファ管理を取り除きます。
  2. 静的アサート、動的アサート、およびコメントに、バッファー サイズの計算に問題がないことの正式な証明を含めます。
  3. 呼び出された各関数の機能の正式な説明を含め、正式な説明が正確である理由の証拠を含めます。呼び出された各関数の単体テストを含めて、関数が要求どおりに動作し、期待どおりに失敗することを確認します。
  4. チェックと整形式であることの正式な証明なしに、ポインターを逆参照したり、バッファーにインデックスを付けたりしないでください。
  5. プリプロセッサ マクロのような愚かなことはしないでください。あなたが書いているコードがコンパイルされたコードであることを確認する方法を見つけてください: あなたが書いているトークンが読み取られるものではない環境で証明をしなければならないことは、無意味に困難です.
  6. 関数が返す可能性のあるすべての値を検証します。つまり、recv -- 0 または -1 をチェックします。-2 または -(2^31) を返すとどうなりますか? 発生しないことが保証されていますか?それからそれを証明してください。
  7. そのテーマに関する実際の専門家を見つけて、やりたいと言ってもらうか、お金を払ってやってもらいましょう。(私はこのテーマの専門家ではありません)

これをすべて行った後、コードを攻撃して壊そうとするでしょう。

そして、あなたは他の誰かに同じことをしてもらいたいと思うでしょう。

于 2012-11-29T16:00:09.300 に答える