メインコンテンツ

ISO/IEC TS 17961 [liberr]

Failing to detect and handle standard library errors

説明

ルール定義

標準ライブラリのエラーを検出および処理しない。1

Polyspace 実装

このチェッカーは以下の問題をチェックします。

  • 要注意の関数の戻り値がチェックされていません

  • 保護されていない動的メモリ割り当て

すべて展開する

問題

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

  • 戻り値を無視。

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

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

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

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

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

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

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

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

  • 権限の設定 (setuid など)

  • jail の作成 (chroot など)

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

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

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

リスク

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

修正方法

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

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

例 - 要注意の関数の戻り値が無視される
#include<stdio.h>
#include <wchar.h>
#include <locale.h>
void initialize(size_t n, size_t* size, wchar_t *wcs, const char *utf8) {

	scanf("%d",&n); //Noncompliant
	setlocale (LC_CTYPE, "en_US.UTF-8");   //Noncompliant
	*size = mbstowcs (wcs, utf8, n);
}

この例は、要注意関数 scanf() の呼び出しを示します。scanf() の戻り値が無視され、欠陥の原因になっています。同様に、setlocale から返されるポインターもチェックされません。setlocal から NULL ポインターが返されると、mbstowcs の呼び出しが失敗するか、または予期しない結果が生じる可能性があります。Polyspace は、要注意の関数の戻り値がチェックされない場合、これらの関数の呼び出しにフラグを設定します。

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

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

#include<stdio.h>
#include <wchar.h>
#include <locale.h>
void initialize(size_t n, size_t* size, wchar_t *wcs, const char *utf8) {

	(void)scanf("%d",&n); //Compliant
	(void)setlocale (LC_CTYPE, "en_US.UTF-8");   //Compliant
	*size = mbstowcs (wcs, utf8, n);
}
修正 — 戻り値をテスト

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

#include<stdio.h>
#include <wchar.h>
#include <locale.h>
void initialize(size_t n, size_t* size, wchar_t *wcs, const char *utf8) {

	int flag = scanf("%d",&n); 
	if(flag>0){ //Compliant
		// action
	}
	char* status = setlocale (LC_CTYPE, "en_US.UTF-8");   
	if(status!=NULL){//Compliant
		*size = mbstowcs (wcs, utf8, n);
	}
	
}
例 - 重要な関数の戻り値が無視される
#include <threads.h>
int thrd_func(void);
void initialize() {
    thrd_t thr;
	int n = 1;

    (void) thrd_create(&thr,thrd_func,&n); 
}

この例では、重要な関数 thrd_create が呼び出され、その戻り値が void にキャストされることで無視されますが、thrd_create は重要な関数であるため、Polyspace はこの "要注意の関数の戻り値がチェックされていません" という欠陥を無視しません。

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

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

 #include <threads.h>
int thrd_func(void);
void initialize() {
	thrd_t thr;
	int n = 1;
	if( thrd_success!= thrd_create(&thr,thrd_func,&n) ){
		// handle error
		
	}
}
問題

保護されていない動的メモリ割り当ては、動的メモリ割り当ての後にメモリ割り当てが成功したかどうかをチェックしていない場合に発生します。

リスク

malloccalloc または realloc を使用してメモリを動的に割り当てる際、要求されたメモリが使用可能でない場合は値 NULL が返されます。割り当ての後、コードでこの NULL 値をチェックせずにメモリ ブロックにアクセスした場合、このアクセスの成功は保証されません。

修正方法

割り当てられたメモリ位置にアクセスする前に、malloccalloc、または realloc の戻り値が NULL かどうかをチェックします。

#define SIZE 10
//...
int *ptr = malloc(SIZE * sizeof(int));

if(ptr) /* Check for NULL */ 
{
   /* Memory access through ptr */
}

例 - 保護されていない動的メモリ割り当てエラー
#include <stdlib.h>

void Assign_Value(void) 
{
  int* p = (int*)calloc(5, sizeof(int));

  *p = 2;  
  /* Defect: p is not checked for NULL value */

  free(p);
}

メモリ割り当てが失敗した場合、関数 callocNULLp に返します。p を使用してメモリにアクセスする前に、コードでは pNULL かどうかのチェックを行っていません。

修正 — null 値をチェック

1 つの修正方法として、デリファレンスの前に p の値が NULL かどうかをチェックすることができます。

#include <stdlib.h>

void Assign_Value(void)
 {
   int* p = (int*)calloc(5, sizeof(int));

   /* Fix: Check if p is NULL */
   if(p!=NULL) *p = 2; 

   free(p);
 }

チェック情報

決定可能性:決定不可能

バージョン履歴

R2019a で導入

すべて展開する


1 Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.