メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C: Rule POS54-C

POSIX ライブラリのエラーを検出および処理する

説明

ルール定義

POSIX ライブラリのエラーを検出および処理します。1

Polyspace 実装

ルール チェッカーは、"要注意の POSIX 関数の戻り値がチェックされていません" をチェックします。

すべて展開する

問題

"要注意の POSIX 関数の戻り値がチェックされていません" は、要注意の POSIX 関数を呼び出すときに、以下を行うと発生します。

  • 戻り値を無視。

  • 戻り値の妥当性をテストすることなく出力または戻り値を使用。

この欠陥では、"要注意""重要で要注意" という 2 つのタイプの関数が考慮されます。

"要注意" の関数とは、以下に遭遇する可能性のある標準関数です。

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

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

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

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

"重要で要注意" の関数とは、次の重要または脆弱なタスクのいずれかを実行する要注意関数です。

  • 権限の設定 (setuid など)

  • jail の作成 (chroot など)

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

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

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

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

リスク

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

修正方法

プログラムを続行する前に、"重要で要注意" の関数の戻り値をテストします。

"要注意の関数" の場合、関数を void にキャストすることで戻り値を明示的に無視することができます。Polyspace® では、要注意の関数が void をキャストしている場合、欠陥とは見なされません。"重要で要注意の関数" の場合、さらに脆弱なタスクが実行されるため、この解決策は許容されません。

例 - 要注意の関数の戻り値が無視される
#include <pthread.h>
#include <string.h>
#include <stddef.h>
#include <stdio.h>

void initialize() {
    pthread_attr_t attr;

    pthread_attr_init(&attr);//Noncompliant 
}
int read_file(int argc, char *argv[])
{
  FILE *in;
  if (argc != 2) {
    /* Handle error */
  }

  in = fmemopen (argv[1], strlen (argv[1]), "r");  
  return 0;  //Noncompliant

}

この例は、要注意の POSIX 関数 pthread_attr_init および fmemopen の呼び出しを示しています。それらの戻り値が無視され、欠陥の原因になっています。

修正 - 関数を (void) にキャスト

考えられる 1 つの修正方法として、関数を void にキャストします。この修正では Polyspace およびレビュー担当者に、要注意の関数の戻り値を明示的に無視していることを伝えます。

#include <pthread.h>
#include <string.h>
#include <stddef.h>
#include <stdio.h>

void initialize() {
    pthread_attr_t attr;

    (void)pthread_attr_init(&attr);//Compliant 
}
int read_file(int argc, char *argv[])
{
  FILE *in;
  if (argc != 2) {
    /* Handle error */
  }

  (void)fmemopen (argv[1], strlen (argv[1]), "r"); //Compliant
  
  return 0; 
}
修正 — 戻り値をテスト

1 つの修正方法として、pthread_attr_initfmemopen の戻り値をテストして、エラーをチェックします。

#include <pthread.h>
#include <string.h>
#include <stddef.h>
#include <stdio.h>

void initialize() {
    pthread_attr_t attr;

    int result = pthread_attr_init(&attr);//Compliant 
	if(result != 0){
		//Handle fatal error
	} 
}
int read_file(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; 
}
例 - 重要な関数の戻り値が無視される
#include <pthread.h>
extern void *start_routine(void *);

void returnnotchecked() {
    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
}

この例では、2 つの重要な関数 pthread_create および pthread_join を呼び出しています。pthread_create の戻り値は void にキャストすることで無視されますが、pthread_create は (要注意の関数であるだけでなく) 重要な関数であるため、Polyspace ではこの "要注意の関数の戻り値がチェックされていません" という欠陥が無視されません。他の重要な関数 pthread_join は暗黙的に無視される値を返します。pthread_join は、pthread_create の戻り値を使用しますが、この戻り値はチェックされていません。

修正 - 重要な関数の戻り値をテスト

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

#include <pthread.h>
#include <stdlib.h>
#define fatal_error() abort()

extern void *start_routine(void *);

void returnnotchecked() {
    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);
    if (result != 0) {
        /* Handle error */
        fatal_error();
    }

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

チェック情報

グループ: Rule 50.POSIX (POS)

バージョン履歴

R2019a で導入

すべて展開する


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.