このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
CWE Rule 253
説明
ルールの説明
The software incorrectly checks a return value from a function, which prevents the software from detecting errors or exceptional conditions.
Polyspace 実装
ルール チェッカーは以下の問題をチェックします。
errno がリセットされていません
保護されていない動的メモリ割り当て
例
この問題は、エラー状態を示すように errno
を設定する関数を呼び出す前に、errno
をリセットしなかった場合に発生します。ただし、関数呼び出し後には、errno
でエラー状態をチェックしています。
errno
はクリーンではなく、前の呼び出しの値を保持している可能性があります。この errno
でエラーをチェックすると、エラーが発生したという誤った印象を与える可能性があります。
errno
はプログラム起動時にゼロに設定されますが、その後 C 標準ライブラリ関数では errno
がリセットされません。必要に応じて、errno
にゼロを明示的に設定しなければなりません。
エラー状態を示すために errno
を設定する関数を呼び出す前に、errno
を明示的にゼロにリセットします。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>
#define fatal_error() abort()
double func(const char *s1, const char *s2)
{
double f1;
f1 = strtod (s1, NULL); //Noncompliant
if (0 == errno) {
double f2 = strtod (s2, NULL);
if (0 == errno) {
long double result = (long double)f1 + f2;
if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX))
{
return (double)result;
}
}
}
fatal_error();
return 0.0;
}
この例では、strtod
呼び出しの前に errno
をゼロにリセットしていません。この errno
がゼロかどうかをチェックすると、誤検知につながる可能性があります。
errno
をリセット1 つの修正方法として、strtod
を呼び出す前に errno
をゼロにリセットします。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>
#define fatal_error() abort()
double func(const char *s1, const char *s2)
{
double f1;
errno = 0;
f1 = strtod (s1, NULL);
if (0 == errno) {
double f2 = strtod (s2, NULL);
if (0 == errno) {
long double result = (long double)f1 + f2;
if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX))
{
return (double)result;
}
}
}
fatal_error();
return 0.0;
}
この問題は、前回のメモリ割り当てが成功したかどうかを初めにチェックせずに、動的に割り当てられたメモリにアクセスしたときに発生します。
malloc
、calloc
または realloc
を使用してメモリを動的に割り当てる際、要求されたメモリが使用可能でない場合は値 NULL
が返されます。割り当ての後、コードでこの NULL
値をチェックせずにメモリ ブロックにアクセスした場合、このアクセスの成功は保証されません。
割り当てられたメモリ位置にアクセスする前に、malloc
、calloc
、または realloc
の戻り値が NULL かどうかをチェックします。
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; //Noncompliant
/* Defect: p is not checked for NULL value */
free(p);
}
メモリ割り当てが失敗した場合、関数 calloc
は NULL
を p
に返します。p
を使用してメモリにアクセスする前に、コードでは p
が 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);
}
#include <stdlib.h>
#include<string.h>
typedef struct recordType {
const char* id;
const char* data;
} RECORD;
RECORD* MakerecordType(const char *id,unsigned int size){
RECORD *rec = (RECORD *)calloc(1, sizeof(RECORD));
rec->id = strdup(id); //Noncompliant
const char *newData = (char *)calloc(1, size);
rec->data = newData;
return rec;
}
この例では、前回の動的メモリ割り当てからの NULL
値をチェックせずにポインター rec
がデリファレンスされたときに、チェッカーが欠陥を報告します。
同様の問題がポインター newData
でも発生します。ただし、ポインターはデリファレンスされませんが、rec->data
にコピーされるだけなので、欠陥は報告されません。null の可能性があるポインターにコピーするだけでは問題になりません。たとえば、関数 recordType_new
の呼び出し元がデリファレンスの前に rec->data
の NULL
値をチェックすれば、null ポインターのデリファレンスは回避されます。
チェック情報
カテゴリ: Error Conditions, Return Values, Status Codes |
バージョン履歴
R2023a で導入
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)