CWE Rule 242
説明
ルールの説明
The program calls a function that can never be guaranteed to work safely.
Polyspace 実装
ルール チェッカーは以下の問題をチェックします。
危険な標準関数を使用しています
旧式の標準関数が使用されています
例
この問題は、コードで、バッファー オーバーフローになる可能性があるやり方でデータをバッファーに書き込む標準関数が使用されている場合に発生します。
次の表に、危険な標準関数、各関数を使用した場合のリスク、および代用する関数を示します。チェッカーは以下にフラグを設定します。
本質的に危険な関数の使用。
コンパイル時にデータが書き込まれるバッファーのサイズを決定可能な場合にのみ、危険な可能性のある関数を使用する。チェッカーは、バッファーが動的に割り当てられるこのような関数の使用にフラグを設定しません。
| 危険な関数 | リスク レベル | より安全な関数 |
|---|---|---|
gets | 本質的に危険 — コンソールからは入力の長さを制御できない。 | fgets |
std::cin::operator>> および std::wcin::operator>> | 本質的に危険 — コンソールからは入力の長さを制御できない。 | 入力長を制御するには、 バッファー オーバーフローと入力切り捨てが発生しないようにするには、 |
strcpy | 潜在的に危険 — 格納先バッファーのサイズが小さすぎて、ソース バッファーと null 終端が収まらない場合は、バッファー オーバーフローが発生する可能性がある。 | 関数 strlen() を使用してソース バッファーのサイズを決定し、格納先バッファーがソース バッファーと null 終端を収められるように十分なメモリを割り当てます。strcpy の代わりに、関数 strncpy を使用します。 |
stpcpy | 潜在的に危険 — ソースの長さがコピー先より大きいと、バッファー オーバーフローが発生する可能性がある。 | stpncpy |
lstrcpy または StrCpy | 潜在的に危険 — ソースの長さがコピー先より大きいと、バッファー オーバーフローが発生する可能性がある。 | StringCbCopy、StringCchCopy、strncpy、strcpy_s または strlcpy |
strcat | 潜在的に危険 — 連結された結果が作成先より大きいと、バッファー オーバーフローが発生する可能性がある。 | strncat、strlcat または strcat_s |
lstrcat または StrCat | 潜在的に危険 — 連結された結果が作成先より大きいと、バッファー オーバーフローが発生する可能性がある。 | StringCbCat、StringCchCat、strncay、strcat_s または strlcat |
wcpcpy | 潜在的に危険 — ソースの長さがコピー先より大きいと、バッファー オーバーフローが発生する可能性がある。 | wcpncpy |
wcscat | 潜在的に危険 — 連結された結果が作成先より大きいと、バッファー オーバーフローが発生する可能性がある。 | wcsncat、wcslcat または wcncat_s |
wcscpy | 潜在的に危険 — ソースの長さがコピー先より大きいと、バッファー オーバーフローが発生する可能性がある。 | wcsncpy |
sprintf | 潜在的に危険 — 出力の長さが不明な長さや値に依存していると、バッファー オーバーフローが発生する可能性がある。 | snprintf |
vsprintf | 潜在的に危険 — 出力の長さが不明な長さや値に依存していると、バッファー オーバーフローが発生する可能性がある。 | vsnprintf |
これらの関数はバッファー オーバーフローの原因となることがあり、攻撃者はこれを利用してプログラムに侵入できます。
修正方法は欠陥の根本原因によって異なります。上の表に記載されている修正と以下の修正付きのコード例を参照してください。
問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処 (Polyspace ユーザー インターフェイスで結果をレビューする場合)。
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access) (Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
#include <stdio.h>
#include <string.h>
#include <iostream>
#define BUFF_SIZE 128
int dangerous_func(char *str)
{
char dst[BUFF_SIZE];
int r = 0;
if (sprintf(dst, "%s", str) == 1) //Noncompliant
{
r += 1;
dst[BUFF_SIZE-1] = '\0';
}
return r;
}この関数例では、sprintf を使用して文字列 str を dst にコピーしています。しかし、str がバッファーより大きいと、sprintf がバッファー オーバーフローの原因となる場合があります。
snprintf を使用1 つの修正方法として、snprintf を代わりに使用し、バッファー サイズを指定します。
#include <stdio.h>
#include <string.h>
#include <iostream>
#define BUFF_SIZE 128
int dangerous_func(char *str)
{
char dst[BUFF_SIZE];
int r = 0;
if (snprintf(dst, sizeof(dst), "%s", str) == 1)
{
r += 1;
dst[BUFF_SIZE-1] = '\0';
}
return r;
}この問題は、C/C++ コーディング規約でレガシ、削除済み、非推奨、または旧式とされている標準関数ルーチンが使用された場合に発生します。
| 旧式の関数 | 規格 | リスク | 置換関数 |
|---|---|---|---|
asctime | POSIX.1-2008 で使用終了 | スレッドセーフでない。 | strftime または asctime_s |
asctime_r | POSIX.1-2008 で使用終了 | 安全でない関数 sprintf に基づく実装。 | strftime または asctime_s |
bcmp | 4.3BSD で使用終了 POSIX.1–2001 でレガシとマークされている。 | 最初の異なるバイトを見つけたら関数から戻るため、タイミング攻撃に対して脆弱になる。 | memcmp |
bcopy | 4.3BSD で使用終了 POSIX.1–2001 でレガシとマークされている。 | 最初の異なるバイトを見つけたら関数から戻るため、タイミング攻撃に対して脆弱になる。 | memcpy または memmove |
brk および sbrk | SUSv2 および POSIX.1-2001 でレガシとマークされている。 | malloc | |
bsd_signal | POSIX.1–2008 で削除済み | sigaction | |
bzero | POSIX.1–2001 でレガシとマークされている。POSIX.1–2008 で削除済み。 | memset | |
ctime | POSIX.1-2008 で使用終了 | スレッドセーフでない。 | strftime または asctime_s |
ctime_r | POSIX.1-2008 で使用終了 | 安全でない関数 sprintf に基づく実装。 | strftime または asctime_s |
cuserid | POSIX.1–2001 で削除済み。 | 再呼び出し可能でない。正確な機能が標準化されておらず、移植性の問題の原因となる。 | getpwuid |
ecvt および fcvt | POSIX.1–2001 でレガシとマークされている。POSIX.1–2008 で削除済み | 再呼び出し可能でない | snprintf |
ecvt_r および fcvt_r | POSIX.1–2001 でレガシとマークされている。POSIX.1–2008 で削除済み | snprintf | |
ftime | POSIX.1–2008 で削除済み | time, gettimeofday, clock_gettime | |
gamma, gammaf, gammal | 履歴が錯綜しているため、関数はどの規格でも指定されていない | 移植性の問題。 | tgamma, lgamma |
gcvt | POSIX.1–2001 でレガシとマークされている。POSIX.1–2008 で削除済み。 | snprintf | |
getcontext | POSIX.1–2008 で削除済み。 | 移植性の問題。 | POSIX スレッドを代わりに使用。 |
getdtablesize | BSD API 関数が POSIX.1-2001 に含まれていない | 移植性の問題。 | sysconf( _SC_OPEN_MAX ) |
gethostbyaddr | POSIX.1–2008 で削除済み | 再呼び出し可能でない | getaddrinfo |
gethostbyname | POSIX.1–2008 で削除済み | 再呼び出し可能でない | getnameinfo |
getpagesize | BSD API 関数が POSIX.1-2001 に含まれていない | 移植性の問題。 | sysconf( _SC_PAGESIZE ) |
getpass | POSIX.1–2001 で削除済み。 | 再呼び出し可能でない。 | getpwuid |
getw | POSIX.1-2001 に存在しない。 | fread | |
getwd | POSIX.1-2001 でレガシとマークされている。POSIX.1–2008 で削除済み。 | getcwd | |
index | POSIX.1–2001 でレガシとマークされている。POSIX.1–2008 で削除済み。 | strchr | |
makecontext | POSIX.1–2008 で削除済み。 | 移植性の問題。 | POSIX スレッドを代わりに使用。 |
memalign | SunOS 4.1.3 で登場。4.4 BSD または POSIX.1-2001 にはなし | posix_memalign | |
mktemp | POSIX.1–2008 で削除済み。 | 生成された名前が予測可能であり、競合状態の原因となることがある。 | mkstemp は競合リスクを除去 |
pthread_attr_getstackaddr および pthread_attr_setstackaddr | stackaddr 属性の仕様にあいまいさがあり、移植性の問題の原因となる | pthread_attr_getstack および pthread_attr_setstack | |
putw | POSIX.1-2001 に存在しない。 | 移植性の問題。 | fwrite |
qecvt および qfcvt | POSIX.1-2001 でレガシとマークされ、POSIX.1-2008 で削除済み | snprintf | |
qecvt_r および qfcvt_r | POSIX.1-2001 でレガシとマークされ、POSIX.1-2008 で削除済み | snprintf | |
rand_r | POSIX.1-2008 で旧式とマークされている | ||
re_comp | BSD API 関数 | 移植性の問題 | regcomp |
re_exes | BSD API 関数 | 移植性の問題 | regexec |
rindex | POSIX.1–2001 でレガシとマークされている。POSIX.1–2008 で削除済み。 | strrchr | |
scalb | POSIX.1–2008 で削除済み | scalbln、scalblnf または scalblnl | |
sigblock | 出典が不明な 4.3BSD シグナル API | sigprocmask | |
sigmask | 出典が不明な 4.3BSD シグナル API | sigprocmask | |
sigsetmask | 出典が不明な 4.3BSD シグナル API | sigprocmask | |
sigstack | インターフェイスが旧式であり、ほとんどのプラットフォームで実装されていない。 | 移植性の問題。 | sigaltstack |
sigvec | 出典が不明な 4.3BSD シグナル API | sigaction | |
swapcontext | POSIX.1–2008 で削除済み | 移植性の問題。 | POSIX スレッドを使用。 |
tmpnam および tmpnam_r | POSIX.1–2008 で旧式とマークされている。 | この関数は、呼び出されるたびに TMP_MAX 回目まで異なる文字列を生成。呼び出される回数が TMP_MAX 回を超えると、動作が処理系定義になる。 | mkstemp, tmpfile |
ttyslot | POSIX.1–2001 で削除済み。 | ||
ualarm | POSIX.1–2001 でレガシとマークされている。POSIX.1–2008 で削除済み。 | エラーの指定が不十分。 | setitimer または POSIX timer_create |
usleep | POSIX.1–2008 で削除済み。 | nanosleep | |
utime | SVr4、POSIX.1-2001。POSIX.1-2008 で旧式とマークされている。 | ||
valloc | 4.3BSD で旧式とマークされている。 SUSv2 でレガシとマークされている。 POSIX.1-2001 から削除済み | posix_memalign | |
vfork | POSIX.1-2008 から削除済み | 以前の規格で指定が不十分。 | fork |
wcswcs | この関数は最終的な ISO/IEC 9899:1990/Amendment 1:1995 (E) に含まれていなかった。 | wcsstr | |
WinExec | WinAPI ではこの関数を 16 ビット Windows 互換でのみ提供。 | CreateProcess | |
LoadModule | WinAPI ではこの関数を 16 ビット Windows 互換でのみ提供。 | CreateProcess |
修正方法は欠陥の根本原因によって異なります。上の表に記載されている修正と以下の修正付きのコード例を参照してください。
問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処 (Polyspace ユーザー インターフェイスで結果をレビューする場合)。
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access) (Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
#include <stdio.h>
#include <time.h>
void timecheck_bad(int argc, char *argv[])
{
time_t ticks;
ticks = time(NULL);
printf("%.24s\r\n", ctime(&ticks)); //Noncompliant
}この例では、関数 ctime が現在の時刻を書式設定して出力します。しかし、ctime はマルチスレッド プログラムで機能しないため、C99 以降で削除されています。
1 つの修正方法として、strftime を代わりに使用します。この関数は一定のバッファー サイズを使用するためです。
#include <stdio.h>
#include <string.h>
#include <time.h>
void timecheck_good(int argc, char *argv[])
{
char outBuff[1025];
time_t ticks;
struct tm * timeinfo;
memset(outBuff, 0, sizeof(outBuff));
ticks = time(NULL);
timeinfo = localtime(&ticks);
strftime(outBuff,sizeof(outBuff),"%I:%M%p.",timeinfo);
fprintf(stdout, outBuff);
}チェック情報
| カテゴリ: API / Function Errors |
バージョン履歴
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)