ISO/IEC TS 17961 [libptr]
Forming invalid pointers by library function
説明
ルール定義
ライブラリ関数による無効なポインターの形成。1
Polyspace 実装
このチェッカーは以下の問題をチェックします。
最大バッファー サイズのチェックがないパス操作関数を使用しています。
標準ライブラリ メモリ ルーチンの無効な使用。
標準ライブラリ文字列ルーチンの無効な使用。
文字列操作で格納先バッファーがオーバーフローしています。
例
最大バッファー サイズのチェックがないパス操作関数を使用していますは、realpath
や getwd
のようなパス操作関数の格納先引数に PATH_MAX
バイトより小さいバッファー サイズが指定されている場合に発生します。
バッファーが PATH_MAX
バイトより小さいとオーバーフローすることがありますが、関数の戻り値をテストしても、オーバーフローが発生したかどうかは判別できません。オーバーフローが発生すると、関数呼び出しの後にバッファーの内容が未定義になります。
たとえば char *getwd(char *buf)
はその引数に、現在のフォルダーの絶対パス名をコピーします。絶対パス名の長さが PATH_MAX
バイトより大きい場合、getwd
は NULL
を返し、*buf
の内容は未定義になります。getwd
の戻り値を NULL
についてテストすることで、関数呼び出しが正常終了したかどうかを確認できます。
しかし、buf
に許可されているバッファーが PATH_MAX
バイトより小さい場合、絶対パス名が小さくてもエラーが発生することがあります。この場合、エラーが発生しても getwd
は NULL
を返しません。したがって、buf
に許可されるバッファーは、PATH_MAX
バイトの長さでなければなりません。
考えられる修正方法は次のとおりです。
PATH_MAX
バイトのバッファー サイズを使用する。不明なソースからバッファーを取得する場合は、バッファーを関数getwd
またはrealpath
の引数として使用する前に、サイズがPATH_MAX
バイトより小さいことを確認します。パス操作関数を使用して、バッファー サイズを指定できるようにする。
たとえば、
getwd
を使用して現在のフォルダーの絶対パス名を取得している場合、代わりにchar *getcwd(char *buf, size_t size);
を使用します。追加の引数size
により、PATH_MAX
以上のサイズを指定できるようになります。可能な場合は、関数が追加メモリを動的に割り当てられるようにする。
たとえば、
char *realpath(const char *path, char *resolved_path);
は、resolved_path
がNULL
の場合にメモリを動的に割り当てます。ただし、後で関数free
を使用してこのメモリの割り当てを解除する必要があります。
getwd
の使用で発生し得るバッファー オーバーフロー#include <unistd.h>
#include <linux/limits.h>
#include <stdio.h>
void func(void) {
char buf[PATH_MAX];
if (getwd(buf+1)!= NULL) {
printf("cwd is %s\n", buf);
}
}
この例では、配列 buf
が PATH_MAX
バイトであっても、getwd
の引数は buf + 1
であり、許可されるバッファーは PATH_MAX
バイトより小さくなります。
PATH_MAX
バイトの配列を使用1 つの修正方法として、サイズが PATH_MAX
バイトに等しい配列引数を使用します。
#include <unistd.h>
#include <linux/limits.h>
#include <stdio.h>
void func(void) {
char buf[PATH_MAX];
if (getwd(buf)!= NULL) {
printf("cwd is %s\n", buf);
}
}
標準ライブラリ メモリ ルーチンの無効な使用は、メモリ ライブラリ関数が無効な引数で呼び出された場合に発生します。たとえば、関数 memcpy
でコピー先の配列に格納できないバイト数をコピーする場合が該当します。
無効な引数でメモリ ライブラリ関数を使用すると、バッファー オーバーフローなどの問題が発生する可能性があります。
修正方法は欠陥の根本原因によって異なります。多くの場合、結果の詳細には欠陥につながる一連のイベントが表示されます。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して逆のトレースを行い、これまでの関連するイベントを確認できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈も参照してください。
以下の修正例を参照してください。
問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処 (Polyspace ユーザー インターフェイスで結果をレビューする場合)。
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access) (Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
#include <string.h>
#include <stdio.h>
char* Copy_First_Six_Letters(void)
{
char str1[10],str2[5];
printf("Enter string:\n");
scanf("%s",str1);
memcpy(str2,str1,6);
/* Defect: Arguments of memcpy invalid: str2 has size < 6 */
return str2;
}
文字列 str2
のサイズは 5 ですが、関数 memcpy
を使用して 6 文字の文字列 str1
が str2
にコピーされています。
1 つの修正方法として、関数 memcpy
でコピーされる文字が収まるように、str2
のサイズを調整するとします。
#include <string.h>
#include <stdio.h>
char* Copy_First_Six_Letters(void)
{
/* Fix: Declare str2 with size 6 */
char str1[10],str2[6];
printf("Enter string:\n");
scanf("%s",str1);
memcpy(str2,str1,6);
return str2;
}
標準ライブラリ文字列ルーチンの無効な使用は、文字列ライブラリ関数が無効な引数で呼び出された場合に発生します。
リスクは無効な引数のタイプによって異なります。たとえば、コピー先引数より大きいコピー元引数を指定して関数 strcpy
を使用すると、バッファー オーバーフローが発生する可能性があります。
修正方法は欠陥に関連する標準ライブラリ関数に依存します。場合によっては、関数呼び出しの前に関数の引数を制約することができます。たとえば、次の関数 strcpy
を考えます。
char * strcpy(char * destination, const char* source);
strcpy
を呼び出す前にコピー元引数を制約します。場合によっては、代替となる関数を使用してエラーを回避できます。たとえば、strcpy
の代わりに strncpy
を使用するとコピーされるバイト数を制御できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈も参照してください。以下の修正例を参照してください。
問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処 (Polyspace ユーザー インターフェイスで結果をレビューする場合)。
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access) (Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
#include <string.h>
#include <stdio.h>
char* Copy_String(void)
{
char *res;
char gbuffer[5],text[20]="ABCDEFGHIJKL";
res=strcpy(gbuffer,text);
/* Error: Size of text is less than gbuffer */
return(res);
}
文字列 text
はサイズが gbuffer
より大きくなっています。したがって、関数 strcpy
は text
を gbuffer
にコピーできません。
1 つの修正方法として、コピー先の文字列 gbuffer
をソース文字列 text
以上のサイズで宣言するとします。
#include <string.h>
#include <stdio.h>
char* Copy_String(void)
{
char *res;
/*Fix: gbuffer has equal or larger size than text */
char gbuffer[20],text[20]="ABCDEFGHIJKL";
res=strcpy(gbuffer,text);
return(res);
}
文字列操作で格納先バッファーがオーバーフローしていますは、特定の文字列操作関数が、その格納先バッファー引数にバッファー サイズより大きいオフセットで書き込む場合に発生します。
たとえば、関数 sprintf(char* buffer, const char* format)
を呼び出す際に、buffer
より大きいサイズの定数文字列 format
を使用する場合などです。
バッファー オーバーフローにより、メモリ破損やシステム停止といった予期しない動作を引き起こす可能性があります。また、バッファー オーバーフローは、コード インジェクションのリスクにもつながります。
1 つの解決策として、代替となる関数を使用して、書き込まれる文字の数を制限します。次に例を示します。
書式設定されたデータを文字列に書き込むのに
sprintf
を使用している場合は、代わりにsnprintf
、_snprintf
またはsprintf_s
を使用して長さを制御します。あるいは、asprintf
を使用して、格納先バッファーに必要なメモリを自動で割り当てます。書式設定されたデータを可変引数リストから文字列に書き込むのに
vsprintf
を使用している場合は、代わりにvsnprintf
またはvsprintf_s
を使用して長さを制御します。ワイド文字列をコピーするのに
wcscpy
を使用している場合は、代わりにwcsncpy
、wcslcpy
またはwcscpy_s
を使用して長さを制御します。
別の解決策として、バッファー サイズを増やします。
sprintf
の使用におけるバッファー オーバーフロー#include <stdio.h>
void func(void) {
char buffer[20];
char *fmt_string = "This is a very long string, it does not fit in the buffer";
sprintf(buffer, fmt_string);
}
この例では、buffer
は char
要素を 20 個格納できますが、fmt_string
はより大きいサイズとなっています。
snprintf
を sprintf
の代わりに使用1 つの修正方法として、関数 snprintf
を使用して長さを制御します。
#include <stdio.h>
void func(void) {
char buffer[20];
char *fmt_string = "This is a very long string, it does not fit in the buffer";
snprintf(buffer, 20, fmt_string);
}
チェック情報
決定可能性:決定不可能 |
バージョン履歴
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.
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)