MISRA C 2012とMISRA C2の比較 - どのように切り替えを行うか

2021年8月17日発行
でSecure Code Warrior
ケーススタディ

MISRA C 2012とMISRA C2の比較 - どのように切り替えを行うか

2021年8月17日発行
でSecure Code Warrior
リソースを見る
リソースを見る

Secure Code Warrior 、私たちは常にトレーニングの範囲を拡大しています。組込み開発者やセキュリティ管理者が安全な組込みシステムを構築できるようにするために、私たちは組込みシステムのセキュリティの世界を利用しています。今回の記事では、MISRA C 2012規格と、なぜ安全な組込みシステムを構築するためにMISRA C 2012規格への準拠が必要なのかについてご紹介します。

C言語でコードを書いていると、一見正しいように見えても、本質的には間違ったものを実装してしまうことがよくあります。あなたのコードは正常にコンパイルされ、ある一定期間は正常に動作するかもしれません。しかし、同じコードでも、入力サイズやメモリが大きくなると、クラッシュしたり、未定義の動作をしたりすることがあります。例えば、特定の入力数で整数がオーバーフローしたり、特定の文字列で配列がアウトオブバウンズになったりすることがあります。

ここで役立つのが、MISRA Cコーディングスタンダードです。この規格で定められたルール、ガイドライン、ベストプラクティスにより、開発者は安全で信頼性の高い組み込み開発用のCコードを書くことができます。 

最新版のMISRA C 2012では、新たなルールの追加や既存のルールの強化、いくつかの矛盾点の解消などが行われています。まだ旧バージョンをお使いの方は、ぜひこの機会に切り替えてみてはいかがでしょうか。 

MISRA Cのコーディング規格とは何ですか?

MISRA C規格は、C言語のコードの安全性、移植性、信頼性に関するガイドラインです。最初のガイドラインは1998年に発表され、C言語に特化したものでした。 

しかし、その後、MISRAコンソーシアムは、C++のコーディングスタンダードも策定しています。MISRA Cのドキュメントには、ルール、準拠していない例、そのルールの開発に貢献した背景情報などの詳細なセクションが含まれています。

CやC++は、組み込みソフトウェアの開発に最も広く使われている言語です。その主な理由の一つは、機械語に比べて1〜2段階の抽象度しかなく、高速であることです。しかし、このことは、特にC言語では、安全なコードを書くことが難しく、エラーが起こりやすいことを意味します。例えば、JavaやC#などの高級言語では、ガベージコレクションや動的型付けなどの些細なことを気にする必要はありません。 

つまり、データ構造のためにメモリを割り当てた場合、そのデータ構造を使い終わったら、自分で手動で解放しなければなりません。そうしないと、C言語は他の言語と違ってメモリを解放してくれないので、メモリリークが発生してしまいます。

MISRA C 2004(C2)とMISRA C 2012(C3)の比較 - 何が変わったのか?

MISRA C: 2012、通称C3は、2013年4月に発売されました。C3は、何千人もの人々や組織の活動から得られた知識をもとに、新しいルールを追加し、既存のルールの説明や背景を強化し、いくつかの抜け穴を解消しています。

C3は、C99バージョンの言語をサポートするとともに、古いISO C90のルールも維持しています。C3の主な目的は、ルールの実施にかかる通常のコストを削減するとともに、重要なシステムでのC言語の使用をより安全にすることでした。これらのことから、もしまだ切り替えていないのであれば、新しい規格に切り替えるのが賢明です。

全体的に見て、最も大きな変更点は以下の通りです。

  • 2004年版にあった問題点を修正。
  • decidable(決定可能)なルール の数を大幅に増やします。解析ツールがそのルールへの適合性を判断するのに役立つ場合、そのルールは決定可能 である。
  • ルールは「必須」「助言」「義務」に分類されます。必須ルールは、どのような状況でも絶対に破ってはいけません。必須ルールと助言ルールは、正当な理由があれば、特別なシナリオで違反することができます。
  • 自動生成されたコードにルールを適用する方法に関するガイダンスを追加しました。人間が書いたコードと同じガイドラインが、ツールで生成されたコードにも適用されるとは限らないため、この点は非常に重要です。
  • ユーザーの合理的な行動を禁じる、過度に一般化されたルールを削除しました。例えば、以前は、マクロは様々な困難や混乱を引き起こす可能性があるため、マクロを一切使用しないことが推奨されていました(マクロのデバッグができない、マクロには名前空間がない、など)。これにより、マクロがエレガントで安全で便利なソリューションを提供できる状況であっても、マクロを使用することができなくなりました。MISRA C: 2012では、マクロに関する新しいルールが導入され、いつでも慎重にマクロを使用できるようになりました。以下は、MISRA Cのドキュメントから抜粋したもので、関数よりもマクロの使用を推奨しています。

MISRA Cルールの運用

さて、ここからはMISRA Cのルールとその適用例を紹介していきます。

memcpy, memmove, memcmp のポインタ引数に互換性のある型を使用する。

標準ライブラリ関数のmemcpy、memmove、 memcmp は、指定されたバイト数のバイトバイバイトの移動や比較を行います。MISRA C 2012規格のルール21.15では、2つの関数パラメータは同じ型のポインタでなければならないと定められています。互換性のないポインタ型の関数呼び出しは、間違いを示す可能性があります。 

MISRAの公式コンプライアンスドキュメントから引用した次の画像を考えてみましょう。このルールは必須であり、決定可能であり、 C90とC99の両方に適用されます。

MISRA Cルール21.15のスクリーンショット

ルールの説明の後に例を示します。

非準拠のソリューションのスクリーンショット。

ご覧のように、オブジェクトの型が異なる(uint8_tとuint16_t)ため、これは非準拠のソリューションとなります。

入力として長さを取らない文字列処理関数は、境界外のアクセスになってはならない。

String handling functions from <string.h> that don’t take the length as an input, shouldn’t result in out-of-bound access. The relevant functions are: strcat, strchr, strcmp, strcoll, strcpy, strcspn, strlen, strpbrk, strrchr, strspn, strrstr, and strtok. The rule is mandatory, meaning it can never be breached, under any circumstances. It applies to both C90 and C99, and is undecidable.

MISRA Cルール21.17のスクリーンショット。

対応する例は

文字列処理機能の正しい例のスクリーンショット

ご覧のように、関数f1のstrcpy は、5文字しか入らない文字列の長さを超えてコピーしてしまいます。また、strcpyを準拠して安全に使用しており、strの内容が収まる場合にのみ文字列がコピーされます。

外部からの受信データの検証

Dir 4.14では、「外部」から受信したデータの有効性をチェックすることを推奨しています。外部入力は以下のようなものがあります。

  • ファイルからの読み込み。
  • 環境変数から読み取る。
  • 任意のユーザー入力。
  • 通信チャネルを介して受信したもの。例:TCP接続やHTTP APIなど。

この指令は、必須 項目に該当し、C90とC99の両方に適用されます。その理由は、プログラムは外部ソースから受け取ったデータを制御できないため、そのデータが無効であったり、悪意のあるものであったりする可能性があるからです。例えば、プログラムはユーザが数字を入力することを期待していますが、ユーザは文字列を入力しました。入力を処理する前に、プログラムはそれが本当に数字であるかどうかを確認しなければなりません。

外部からの数値の妥当性を確認すること。

MISRA C 2012への切り替え方法

MISRA C 2012に切り替えると、コーディングガイドラインのドキュメントを更新する必要があります。また、静的解析ツールを使用している場合は、そのツールの新しいバージョンを入手する必要があります。ここでは、MISRA C 2012への準拠をチェックする3つのツールをご紹介します。

  1. Cppcheckはオープンソースのツールで、MISRAのルールをチェックしたり、様々な種類のバグを検出することができます。
  2. PC-lint Plusは、30日間の評価期間がついた有料ツールです。MISRA Cに準拠しているかどうかをチェックするだけでなく、潜在的なバグや脆弱性を特定することができます。
  3. CodeSonarは、MISRA CとC++の両方に準拠しているかどうかをチェックする別のツールです。

また、MISRAに準拠しているかどうかをテストできるコンパイラもいくつかあります。ルール違反が検出された場合は、それに応じて警告や例外が発生します。例えば、Green Hills Software 社は、32ビットと64ビットの両方のアーキテクチャで、すべてのMISRA規格に対応したコンパイラを提供しています。

Secure Code Warrior を利用した MISRA C の開発者のスキルアップ

Secure Code Warrior の主力製品であるlearning platform には、開発者が安全な C/C++ コードを書くためのトレーニングに役立つ、数多くのインタラクティブな課題、courses 、および評価が用意されています。このプラットフォームのコンテンツは、フレームワークに特化しており、非常に魅力的なものとなっています。私たちのC/C++:Embedコーディングチャレンジは、MISRA C、AUTOSAR C++(MISRA C++)、IECの両方からインスピレーションを得ています。

開発者は、C/C++特有の脆弱性を発見し、さらにそのバグを修正する方法を学ぶという、個人的な学習の旅に出ることができます。この過程で、開発者は自分の進捗状況を把握して弱点を見つけたり、仲間と一緒にコーディングコンテストを楽しんだりすることもできます。当社のソリューションがどのように自動車・輸送業界を支援しているか、詳しくはこちらをご覧ください。

C/C++:Embedの課題がどれほどインタラクティブで、組込みに特化しているかを知りたいですか?learning platform でC/C++:Embed の課題をお試しください。

リソースを見る
リソースを見る

著者

Secure Code Warrior

Secure Code Warrior は、セキュアなコードを書くためのスキルを開発者に提供することで、セキュリ ティを重視する開発者文化を構築する。当社の主力製品であるアジャイルLearning Platform は、開発者がセキュアなコードを記述するためのスキルを短期間で習得し、構築し、適用できるように、適切なスキルに基づくパスウェイ、実践的なmissions 、状況に応じたツールを提供します。

もっと知りたい?

セキュアコーディングに関する最新の知見をブログでご紹介しています。

当社の豊富なリソースライブラリは、安全なコーディングアップスキルに対する人間的なアプローチを強化することを目的としています。

ブログを見る
もっと知りたい?

開発者主導のセキュリティに関する最新の研究成果を入手する

ホワイトペーパーからウェビナーまで、開発者主導のセキュアコーディングを始めるために役立つリソースが満載のリソースライブラリです。今すぐご覧ください。

リソース・ハブ

MISRA C 2012とMISRA C2の比較 - どのように切り替えを行うか

2021年8月17日発行
BySecure Code Warrior

Secure Code Warrior 、私たちは常にトレーニングの範囲を拡大しています。組込み開発者やセキュリティ管理者が安全な組込みシステムを構築できるようにするために、私たちは組込みシステムのセキュリティの世界を利用しています。今回の記事では、MISRA C 2012規格と、なぜ安全な組込みシステムを構築するためにMISRA C 2012規格への準拠が必要なのかについてご紹介します。

C言語でコードを書いていると、一見正しいように見えても、本質的には間違ったものを実装してしまうことがよくあります。あなたのコードは正常にコンパイルされ、ある一定期間は正常に動作するかもしれません。しかし、同じコードでも、入力サイズやメモリが大きくなると、クラッシュしたり、未定義の動作をしたりすることがあります。例えば、特定の入力数で整数がオーバーフローしたり、特定の文字列で配列がアウトオブバウンズになったりすることがあります。

ここで役立つのが、MISRA Cコーディングスタンダードです。この規格で定められたルール、ガイドライン、ベストプラクティスにより、開発者は安全で信頼性の高い組み込み開発用のCコードを書くことができます。 

最新版のMISRA C 2012では、新たなルールの追加や既存のルールの強化、いくつかの矛盾点の解消などが行われています。まだ旧バージョンをお使いの方は、ぜひこの機会に切り替えてみてはいかがでしょうか。 

MISRA Cのコーディング規格とは何ですか?

MISRA C規格は、C言語のコードの安全性、移植性、信頼性に関するガイドラインです。最初のガイドラインは1998年に発表され、C言語に特化したものでした。 

しかし、その後、MISRAコンソーシアムは、C++のコーディングスタンダードも策定しています。MISRA Cのドキュメントには、ルール、準拠していない例、そのルールの開発に貢献した背景情報などの詳細なセクションが含まれています。

CやC++は、組み込みソフトウェアの開発に最も広く使われている言語です。その主な理由の一つは、機械語に比べて1〜2段階の抽象度しかなく、高速であることです。しかし、このことは、特にC言語では、安全なコードを書くことが難しく、エラーが起こりやすいことを意味します。例えば、JavaやC#などの高級言語では、ガベージコレクションや動的型付けなどの些細なことを気にする必要はありません。 

つまり、データ構造のためにメモリを割り当てた場合、そのデータ構造を使い終わったら、自分で手動で解放しなければなりません。そうしないと、C言語は他の言語と違ってメモリを解放してくれないので、メモリリークが発生してしまいます。

MISRA C 2004(C2)とMISRA C 2012(C3)の比較 - 何が変わったのか?

MISRA C: 2012、通称C3は、2013年4月に発売されました。C3は、何千人もの人々や組織の活動から得られた知識をもとに、新しいルールを追加し、既存のルールの説明や背景を強化し、いくつかの抜け穴を解消しています。

C3は、C99バージョンの言語をサポートするとともに、古いISO C90のルールも維持しています。C3の主な目的は、ルールの実施にかかる通常のコストを削減するとともに、重要なシステムでのC言語の使用をより安全にすることでした。これらのことから、もしまだ切り替えていないのであれば、新しい規格に切り替えるのが賢明です。

全体的に見て、最も大きな変更点は以下の通りです。

  • 2004年版にあった問題点を修正。
  • decidable(決定可能)なルール の数を大幅に増やします。解析ツールがそのルールへの適合性を判断するのに役立つ場合、そのルールは決定可能 である。
  • ルールは「必須」「助言」「義務」に分類されます。必須ルールは、どのような状況でも絶対に破ってはいけません。必須ルールと助言ルールは、正当な理由があれば、特別なシナリオで違反することができます。
  • 自動生成されたコードにルールを適用する方法に関するガイダンスを追加しました。人間が書いたコードと同じガイドラインが、ツールで生成されたコードにも適用されるとは限らないため、この点は非常に重要です。
  • ユーザーの合理的な行動を禁じる、過度に一般化されたルールを削除しました。例えば、以前は、マクロは様々な困難や混乱を引き起こす可能性があるため、マクロを一切使用しないことが推奨されていました(マクロのデバッグができない、マクロには名前空間がない、など)。これにより、マクロがエレガントで安全で便利なソリューションを提供できる状況であっても、マクロを使用することができなくなりました。MISRA C: 2012では、マクロに関する新しいルールが導入され、いつでも慎重にマクロを使用できるようになりました。以下は、MISRA Cのドキュメントから抜粋したもので、関数よりもマクロの使用を推奨しています。

MISRA Cルールの運用

さて、ここからはMISRA Cのルールとその適用例を紹介していきます。

memcpy, memmove, memcmp のポインタ引数に互換性のある型を使用する。

標準ライブラリ関数のmemcpy、memmove、 memcmp は、指定されたバイト数のバイトバイバイトの移動や比較を行います。MISRA C 2012規格のルール21.15では、2つの関数パラメータは同じ型のポインタでなければならないと定められています。互換性のないポインタ型の関数呼び出しは、間違いを示す可能性があります。 

MISRAの公式コンプライアンスドキュメントから引用した次の画像を考えてみましょう。このルールは必須であり、決定可能であり、 C90とC99の両方に適用されます。

MISRA Cルール21.15のスクリーンショット

ルールの説明の後に例を示します。

非準拠のソリューションのスクリーンショット。

ご覧のように、オブジェクトの型が異なる(uint8_tとuint16_t)ため、これは非準拠のソリューションとなります。

入力として長さを取らない文字列処理関数は、境界外のアクセスになってはならない。

String handling functions from <string.h> that don’t take the length as an input, shouldn’t result in out-of-bound access. The relevant functions are: strcat, strchr, strcmp, strcoll, strcpy, strcspn, strlen, strpbrk, strrchr, strspn, strrstr, and strtok. The rule is mandatory, meaning it can never be breached, under any circumstances. It applies to both C90 and C99, and is undecidable.

MISRA Cルール21.17のスクリーンショット。

対応する例は

文字列処理機能の正しい例のスクリーンショット

ご覧のように、関数f1のstrcpy は、5文字しか入らない文字列の長さを超えてコピーしてしまいます。また、strcpyを準拠して安全に使用しており、strの内容が収まる場合にのみ文字列がコピーされます。

外部からの受信データの検証

Dir 4.14では、「外部」から受信したデータの有効性をチェックすることを推奨しています。外部入力は以下のようなものがあります。

  • ファイルからの読み込み。
  • 環境変数から読み取る。
  • 任意のユーザー入力。
  • 通信チャネルを介して受信したもの。例:TCP接続やHTTP APIなど。

この指令は、必須 項目に該当し、C90とC99の両方に適用されます。その理由は、プログラムは外部ソースから受け取ったデータを制御できないため、そのデータが無効であったり、悪意のあるものであったりする可能性があるからです。例えば、プログラムはユーザが数字を入力することを期待していますが、ユーザは文字列を入力しました。入力を処理する前に、プログラムはそれが本当に数字であるかどうかを確認しなければなりません。

外部からの数値の妥当性を確認すること。

MISRA C 2012への切り替え方法

MISRA C 2012に切り替えると、コーディングガイドラインのドキュメントを更新する必要があります。また、静的解析ツールを使用している場合は、そのツールの新しいバージョンを入手する必要があります。ここでは、MISRA C 2012への準拠をチェックする3つのツールをご紹介します。

  1. Cppcheckはオープンソースのツールで、MISRAのルールをチェックしたり、様々な種類のバグを検出することができます。
  2. PC-lint Plusは、30日間の評価期間がついた有料ツールです。MISRA Cに準拠しているかどうかをチェックするだけでなく、潜在的なバグや脆弱性を特定することができます。
  3. CodeSonarは、MISRA CとC++の両方に準拠しているかどうかをチェックする別のツールです。

また、MISRAに準拠しているかどうかをテストできるコンパイラもいくつかあります。ルール違反が検出された場合は、それに応じて警告や例外が発生します。例えば、Green Hills Software 社は、32ビットと64ビットの両方のアーキテクチャで、すべてのMISRA規格に対応したコンパイラを提供しています。

Secure Code Warrior を利用した MISRA C の開発者のスキルアップ

Secure Code Warrior の主力製品であるlearning platform には、開発者が安全な C/C++ コードを書くためのトレーニングに役立つ、数多くのインタラクティブな課題、courses 、および評価が用意されています。このプラットフォームのコンテンツは、フレームワークに特化しており、非常に魅力的なものとなっています。私たちのC/C++:Embedコーディングチャレンジは、MISRA C、AUTOSAR C++(MISRA C++)、IECの両方からインスピレーションを得ています。

開発者は、C/C++特有の脆弱性を発見し、さらにそのバグを修正する方法を学ぶという、個人的な学習の旅に出ることができます。この過程で、開発者は自分の進捗状況を把握して弱点を見つけたり、仲間と一緒にコーディングコンテストを楽しんだりすることもできます。当社のソリューションがどのように自動車・輸送業界を支援しているか、詳しくはこちらをご覧ください。

C/C++:Embedの課題がどれほどインタラクティブで、組込みに特化しているかを知りたいですか?learning platform でC/C++:Embed の課題をお試しください。

弊社製品や関連するセキュアコーディングのトピックに関する情報をお送りする許可をお願いします。当社は、お客様の個人情報を細心の注意を払って取り扱い、マーケティング目的で他社に販売することは決してありません。

送信
フォームを送信するには、「Analytics」のCookieを有効にしてください。完了したら、再度無効にしてください。