このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
CWE Rule 369
説明
ルールの説明
The product divides a value by zero.
Polyspace 実装
ルール チェッカーは以下の問題をチェックします。
浮動小数点数のゼロ除算
整数のゼロ除算
汚染された除算演算子
汚染されたモジュロ演算子
例
この問題は、除算演算の分母がゼロ値の浮動小数点数になる可能性がある場合に発生します。
ゼロ除算はプログラムをクラッシュさせる可能性があります。
修正方法は欠陥の根本原因によって異なります。多くの場合、結果の詳細 (または Polyspace as You Code のソース コード ツールヒント) には欠陥につながる一連のイベントが表示されます。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して、欠陥に関連する変数のこれまでの参照を検索し、関連するイベントを検出できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈またはPolyspace Access Web インターフェイスでの Bug Finder の結果の解釈 (Polyspace Access)も参照してください。
除算の前に分母がゼロ値かどうかをチェックしてエラーを処理することをお勧めします。次のように除算を直接実行するのは避けます。
res = num/den;
res = div(num, den);
以下の修正例を参照してください。
問題を修正しない場合、たとえば、コード内で無限大を処理する場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処(Polyspace ユーザー インターフェイスで結果をレビューする場合)
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access)(Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
既定では、Bug Finder 解析は無限大と NaNs
を認識しません。結果が無限大および NaNs
になる演算には、欠陥としてフラグが設定される可能性があります。コードで無限大および NaN
の値を処理するには、オプション [非有限の浮動小数点を検討] (-allow-non-finite-floats)
を使用します。
入力値が不明であり、入力のサブセットのみがエラーの原因となっている場合、既定の Bug Finder 解析ではこの欠陥が報告されない可能性があります。特定のシステム入力値を原因とする欠陥の有無をチェックするには、より厳密な Bug Finder 解析を実行してください。特定のシステム入力値から欠陥を見つけるための Bug Finder チェッカーの拡張を参照してください。
float fraction(float num)
{
float denom = 0.0;
float result = 0.0;
result = num/denom; //Noncompliant
return result;
}
denom
がゼロであるため、num
/
denom
でゼロ除算エラーが発生します。
float fraction(float num)
{
float denom = 0.0;
float result = 0.0;
if( ((int)denom) != 0)
result = num/denom;
return result;
}
除算の前に、分母がゼロかどうかを確認するためのテストを追加して、除算が実行される前にチェックします。denom
が常にゼロである場合は、この修正により Polyspace® の結果にデッド コードの欠陥が報告される可能性があります。
1 つの修正方法として、denom
がゼロでなくなるように分母の値を変更することができます。
float fraction(float num)
{
float denom = 2.0;
float result = 0.0;
result = num/denom;
return result;
}
この問題は、除算演算またはモジュロ演算の分母がゼロ値の整数になる可能性がある場合に発生します。
ゼロ除算はプログラムをクラッシュさせる可能性があります。
修正方法は欠陥の根本原因によって異なります。多くの場合、結果の詳細 (または Polyspace as You Code のソース コード ツールヒント) には欠陥につながる一連のイベントが表示されます。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して、欠陥に関連する変数のこれまでの参照を検索し、関連するイベントを検出できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈またはPolyspace Access Web インターフェイスでの Bug Finder の結果の解釈 (Polyspace Access)も参照してください。
除算の前に分母がゼロ値かどうかをチェックしてエラーを処理することをお勧めします。次のように除算を直接実行するのは避けます。
res = num/den;
res = div(num, den);
以下の修正例を参照してください。
問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処(Polyspace ユーザー インターフェイスで結果をレビューする場合)
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access)(Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
入力値が不明であり、入力のサブセットのみがエラーの原因となっている場合、既定の Bug Finder 解析ではこの欠陥が報告されない可能性があります。特定のシステム入力値を原因とする欠陥の有無をチェックするには、より厳密な Bug Finder 解析を実行してください。特定のシステム入力値から欠陥を見つけるための Bug Finder チェッカーの拡張を参照してください。
int fraction(int num)
{
int denom = 0;
int result = 0;
result = num/denom; //Noncompliant
return result;
}
denom
がゼロであるため、num
/
denom
でゼロ除算エラーが発生します。
int fraction(int num)
{
int denom = 0;
int result = 0;
if (denom != 0)
result = num/denom;
return result;
}
除算の前に、分母がゼロかどうかを確認するためのテストを追加して、除算が実行される前にチェックします。denom
が常にゼロである場合は、この修正により Polyspace の結果にデッド コードの欠陥が報告される可能性があります。
1 つの修正方法として、denom
がゼロでなくなるように分母の値を変更することができます。
int fraction(int num)
{
int denom = 2;
int result = 0;
result = num/denom;
return result;
}
int mod_arr(int input)
{
int arr[5];
for(int i = 0; i < 5; i++)
{
arr[i] = input % i; //Noncompliant
}
return arr[0]+arr[1]+arr[2]+arr[3]+arr[4];
}
この例では、Polyspace がモジュロ演算にゼロ除算のフラグを立てます。モジュロは本質として除算演算であるため、除数 (右辺引数) をゼロにすることはできません。このモジュロ演算では、除数として for
ループのインデックスを使用しています。しかし、for
ループはゼロから開始されるので、反復子にはできません。
1 つの修正方法として、モジュロ演算の前に除数をチェックします。この例では、モジュロ演算の前に指数 i
がゼロかどうかを確認します。
int mod_arr(int input)
{
int arr[5];
for(int i = 0; i < 5; i++)
{
if(i != 0)
{
arr[i] = input % i;
}
else
{
arr[i] = input;
}
}
return arr[0]+arr[1]+arr[2]+arr[3]+arr[4];
}
別の修正方法として、除数を非ゼロの整数に変更します。この例では、%
演算の前に指数に 1 を加算して、ゼロ除算を回避しています。
int mod_arr(int input)
{
int arr[5];
for(int i = 0; i < 5; i++)
{
arr[i] = input % (i+1);
}
return arr[0]+arr[1]+arr[2]+arr[3]+arr[4];
}
この問題は、除算演算内の整数オペランドの一方または両方がセキュリティで保護されていないソースから取得された場合に発生します。
分子 (被除数) が可能な限りの最小値であり、分母 (除数) が
-1
である場合、除算演算は結果が現在の変数のサイズでは表現できないためオーバーフローします。分母がゼロである場合、除算演算は失敗し、プログラムがクラッシュがする可能性があります。
こうしたリスクは、恣意的なコードの実行に利用される可能性があります。このようなコードは通例において、プログラムの暗黙的なセキュリティ ポリシーの範囲外です。
除算を実行する前に、オペランドの値を検証します。0
または -1
の分母や、最小の整数値の分子についてチェックします。
既定では、Polyspace は外部ソースからのデータは汚染されていると仮定します。Polyspace 解析での汚染のソースを参照してください。Polyspace 解析の現在のスコープ以外から発生したすべてのデータを汚染されたものと見なすには、コマンド ライン オプション [-consider-analysis-perimeter-as-trust-boundary]
を使用します。
#include <limits.h>
#include <stdio.h>
extern void print_int(int);
int taintedintdivision(void) {
long num, denum;
scanf("%lf %lf", &num, &denum);
int r = num/denum; //Noncompliant //Noncompliant
print_int(r);
return r;
}
この関数例では、2 つの引数変数の除算を行い、それを表示して結果を返します。その引数値は不明であり、ゼロ除算や整数オーバーフローの原因となることがあります。
1 つの修正方法として、除算を実行する前に分子と分母の値をチェックします。
#include <limits.h>
#include <stdio.h>
extern void print_long(long);
int taintedintdivision(void) {
long num, denum;
scanf("%lf %lf", &num, &denum);
long res= 0;
if (denum!=0 && !(num==INT_MIN && denum==-1)) {
res = num/denum;
}
print_long(res);
return res;
}
この問題は、残余演算 (%
) 内の整数オペランドの一方または両方がセキュリティで保護されていないソースから取得された場合に発生します。
2 番目の残余オペランドが 0 である場合、残余演算は失敗し、プログラムはクラッシュします。
2 番目の残余オペランドが
-1
である場合、オーバーフローし得る除算演算を基に残余演算が実装されていると、その残余演算はオーバーフローする可能性があります。オペランドの 1 つが負である場合、演算の結果は不確定になります。C89 ではモジュロ演算は標準化されていないため、負のオペランドによる結果は処理系定義となります。
こうしたリスクは、攻撃者によってプログラムあるいはターゲット一般へのアクセスに利用される場合があります。
モジュロ演算を実行する前に、オペランドの値を検証します。2 番目のオペランドの値が 0
や -1
かどうかをチェックします。両方のオペランドの値が負の値かどうかをチェックします。
既定では、Polyspace は外部ソースからのデータは汚染されていると仮定します。Polyspace 解析での汚染のソースを参照してください。Polyspace 解析の現在のスコープ以外から発生したすべてのデータを汚染されたものと見なすには、コマンド ライン オプション [-consider-analysis-perimeter-as-trust-boundary]
を使用します。
#include <stdio.h>
extern void print_int(int);
int taintedintmod(void) {
int userden;
scanf("%d", &userden);
int rem = 128%userden; //Noncompliant //Noncompliant
print_int(rem);
return rem;
}
この例では、関数がユーザー入力を使用してモジュロ演算を実行します。残余を計算する前に、プログラムをクラッシュさせる可能性のある 0 や -1 などの値に対して入力がチェックされていません。
1 つの修正方法として、モジュロ演算を実行する前にオペランドの値をチェックします。次に示す修正例では、モジュロ演算は 2 番目のオペランドが 0 より大きい場合にのみ続行します。
#include<stdio.h>
extern void print_int(int);
int taintedintmod(void) {
int userden;
scanf("%d", &userden);
int rem = 0;
if (userden > 0 ) {
rem = 128 % userden;
}
print_int(rem);
return rem;
}
チェック情報
カテゴリ: Numeric 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)