メインコンテンツ

MISRA C:2012 Dir 4.7

If a function returns error information, then that error information shall be tested

説明

命令の定義

If a function returns error information, then that error information shall be tested 1 .

根拠

戻り値でエラー情報を示す関数の戻り値をチェックしない場合、プログラムが予期しない動作をする可能性があります。これらの関数のエラーはプログラム全体に伝播し、不適切な出力、セキュリティの脆弱性およびシステム障害の原因となる可能性があります。

Polyspace 実装

チェッカーは、可能性のあるエラーに関する情報を返す要注意の標準関数を呼び出して、以下のいずれかを行った場合に違反を発生させます。

  • 戻り値を無視。

    戻り値を変数に単純に代入することも、戻り値を明示的に void にキャストすることもしていない。

  • エラーの戻り値をテストすることなく関数の出力 (戻り値または引数の参照渡し) を使用。

以下のような理由で関数呼び出しで障害を発生する可能性が高い場合、チェッカーはその関数を要注意と見なします。

  • システム リソースが使い尽くされた状態 (リソースを割り当てるときなど)。

  • 権限またはアクセス許可が変更された状態。

  • 外部ソースからのデータを読み取り、書き込みまたは変換する際にソースが汚染された状態。

  • 既存の API があってもサポートされない機能。

チェッカーは、関数がエラーなしで終了したかどうかを "戻り値" が示す関数のみを考慮します。

このような関数の一部では、以下のような重要なタスクを実行する可能性があります。

  • 権限の設定 (setuid など)

  • jail の作成 (chroot など)

  • プロセスの作成 (fork など)

  • スレッドの作成 (pthread_create など)

  • ミューテックスのロックまたはロック解除 (pthread_mutex_lock など)

  • メモリ セグメントのロックまたはロック解除 (mlock など)

重要ではない関数では、チェッカーは関数戻り値を void にキャストすることを許可します。

この命令は部分的にのみサポートされます。

トラブルシューティング

ルール違反を想定していてもその違反が表示されない場合、コーディング規約違反が想定どおりに表示されない理由の診断を参照します。

すべて展開する

#include <pthread.h>
#include <string.h>
#include <stddef.h>
#include <stdio.h>
#include <cstdlib>
#define fatal_error() abort()

void initialize_1() {
    pthread_attr_t attr;
    pthread_attr_init(&attr); //Noncompliant
}

void initialize_2() {
    pthread_attr_t attr;
   (void)pthread_attr_init(&attr); //Compliant
}

void initialize_3() {
    pthread_attr_t attr;
    int result;
    result = pthread_attr_init(&attr); //Compliant
    if (result != 0) {
        /* Handle error */
        fatal_error();
    }
}

int read_file_1(int argc, char *argv[])
{
  FILE *in;
  if (argc != 2) {
    /* Handle error */
  }

  in = fmemopen (argv[1], strlen (argv[1]), "r");   
  return 0; //Noncompliant
 
}
int read_file_2(int argc, char *argv[])
{
  FILE *in;
  if (argc != 2) {
    /* Handle error */
  }

  in = fmemopen (argv[1], strlen (argv[1]), "r"); //Compliant
  if (in==NULL){
	  // Handle error
  }
  return 0; 
}

この例は、要注意の関数 pthread_attr_init および fmemopen の呼び出しを示しています。Polyspace® は、次の場合にフラグを設定します。

  • 要注意の関数の戻り値を暗黙的に無視している。要注意の関数の出力を明示的に無視している場合、フラグは設定されません。

  • 要注意の関数の戻り値を取得しているが、関連するスコープを抜ける前に戻り値をテストしていない。終了ステートメントに対して違反が報告されます。

準拠するには、関数の戻り値を void に明示的にキャストするか、戻り値をテストしてエラーがないかチェックします。

#include <pthread.h>
extern void *start_routine(void *);

void returnnotchecked_1() {
    pthread_t thread_id;
    pthread_attr_t attr;
    void *res;

    (void)pthread_attr_init(&attr);
    (void)pthread_create(&thread_id, &attr, &start_routine, ((void *)0)); //Noncompliant
    pthread_join(thread_id,  &res); //Noncompliant
}

void returnnotchecked_2() {
    pthread_t thread_id;
    pthread_attr_t attr;
    void *res;
    int result;

    (void)pthread_attr_init(&attr);
    result = pthread_create(&thread_id, &attr, &start_routine, NULL); //Compliant
    if (result != 0) {
        /* Handle error */
        fatal_error();
    }

    result = pthread_join(thread_id,  &res); //Compliant
    if (result != 0) {
        /* Handle error */
        fatal_error();
    }
}

この例では、2 つの重要な関数 pthread_create および pthread_join を呼び出しています。pthread_create の戻り値は void にキャストすることで無視されますが、pthread_create は (要注意の関数であるだけでなく) 重要な関数であるため、ルール チェッカーはやはり違反を報告します。他の重要な関数 pthread_join は暗黙的に無視される値を返します。

準拠するには、これらの重要な関数の戻り値をチェックして、関数が想定どおりに実行されることを検証します。

チェック情報

グループ: Code design
カテゴリ: 必要
AGC カテゴリ: 必要

バージョン履歴

R2017a で導入

すべて展開する


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.