CWE Rule 822
説明
ルールの説明
The program obtains a value from an untrusted source, converts this value to a pointer, and dereferences the resulting pointer.
Polyspace 実装
ルール チェッカーは以下の問題をチェックします。
汚染された NULL 文字列または非 NULL 終端文字列
汚染されたポインターの使用
例
この問題は、strcpy や sprintf などの文字列バッファーを暗黙的にデリファレンスする文字列操作ルーチンで、セキュリティで保護されていないソースからの文字列が使用された場合に発生します。
汚染された NULL 文字列または非 NULL 終端文字列では、scanf ファミリの可変個引数関数の呼び出しから返された文字列に関する欠陥が報告されません。同様に、文字列と一緒に %s 指定子を printf ファミリの可変個引数関数に渡した場合も欠陥は報告されません。
文字列がセキュリティで保護されないソースに由来している場合、攻撃者により文字列が操作されている可能性や、文字列ポインターが異なるメモリ位置に向けられている可能性があります。
文字列が NULL である場合、文字列ルーチンは文字列をデリファレンスできず、プログラムがクラッシュする原因となります。文字列が null で終了しない場合、文字列ルーチンでは文字列がいつ終了するかわからない可能性があります。このエラーは範囲外への書き込みの原因となり、バッファー オーバーフローを引き起こします。
文字列は、使用する前に検証します。以下についてチェックします。
文字列が NULL でない。
文字列が null で終了している。
文字列のサイズが、必要なサイズと一致している。
既定では、Polyspace® は外部ソースからのデータは汚染されていると仮定します。Polyspace 解析での汚染のソースを参照してください。Polyspace 解析の現在のスコープ以外から発生したすべてのデータを汚染されたものと見なすには、コマンド ライン オプション [-consider-analysis-perimeter-as-trust-boundary] を使用します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SIZE128 128
#define MAX 40
extern void print_str(const char*);
void warningMsg(void)
{
char userstr[MAX];
read(0,userstr,MAX);
char str[SIZE128] = "Warning: ";
strncat(str, userstr, SIZE128-(strlen(str)+1));//Noncompliant //Noncompliant
print_str(str);
}
この例では、文字列 str は引数 userstr と連結しています。userstr の値は不明です。userstr のサイズが使用可能なスペースより大きい場合、この連結はオーバーフローします。
1 つの修正方法として、strncat で使用する前に、userstr のサイズをチェックして、文字列が必ず null で終了するようにします。この例では、補助関数 sansitize_str を使用して文字列を検証しています。欠陥はこの関数に集中しています。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SIZE128 128
#define MAX 40
extern void print_str(const char*);
int sanitize_str(char* s) {
int res = 0;
if (s && (strlen(s) > 0)) { // Noncompliant-TAINTED_STRING only flagged here //Noncompliant
// - string is not null
// - string has a positive and limited size
// - TAINTED_STRING on strlen used as a firewall
res = 1;
}
return res;
}
void warningMsg(void)
{
char userstr[MAX];
read(0,userstr,MAX);
char str[SIZE128] = "Warning: ";
if (sanitize_str(userstr))
strncat(str, userstr, SIZE128-(strlen(str)+1));
print_str(str);
}別の修正方法として、特定の文字列を含む関数 errorMsg および warningMsg を呼び出します。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE128 128
extern void print_str(const char*);
void warningMsg(char* userstr)
{
char str[SIZE128] = "Warning: ";
strncat(str, userstr, SIZE128-(strlen(str)+1));
print_str(str);
}
void errorMsg(char* userstr)
{
char str[SIZE128] = "Error: ";
strncat(str, userstr, SIZE128-(strlen(str)+1));
print_str(str);
}
int manageSensorValue(int sensorValue) {
int ret = sensorValue;
if ( sensorValue < 0 ) {
errorMsg("sensor value should be positive");
exit(1);
} else if ( sensorValue > 50 ) {
warningMsg("sensor value greater than 50 (applying threshold)...");
sensorValue = 50;
}
return sensorValue;
}この問題は、以下の場合に発生します。
汚染された NULL ポインター — セキュリティで保護されていないソースから取得したポインターが NULL に対し検証されていない。
汚染されたサイズ ポインター — セキュリティで保護されていないポインターが指しているメモリ ゾーンのサイズが検証されていない。
メモ
単一のポインターについて、コードに汚染されたポインターの使用、汚染されたオフセットによるポインターのデリファレンス、汚染された NULL 文字列または非 NULL 終端文字列の各インスタンスが含まれることがあります。Bug Finder では、最初に見つかった汚染されたポインターの欠陥のみが報告されます。
攻撃者は、予期しないメモリ位置を指すポインターをプログラムに与えることが可能です。ポインターのデリファレンスにより書き込みを行う場合、攻撃者は次のことができます。
重要なプログラムの状態変数を変更する。
プログラムをクラッシュさせる。
望ましくないコードを実行する。
ポインターのデリファレンスにより読み取りを行う場合、攻撃者は次のことができます。
機密データを読み取る。
プログラムをクラッシュさせる。
プログラム変数を予期しない値に変更する。
外部ソースに由来するポインターの使用を避けます。
または、外部ソースを信頼する場合、デリファレンスする前にポインターをサニタイズします。個別のサニタイズ関数で以下を実行します。
ポインターが NULL ではないことをチェック。
メモリ位置のサイズをチェック (可能な場合)。この 2 番目のチェックは、ポインターが指すデータのサイズがプログラムに必要なサイズと一致するかどうかを検証します。
サニタイズ関数の本体には、この欠陥がまだ表示されます。ただし、サニタイズ関数を使用する場合は、欠陥は複数回ではなく 1 回だけ表示されます。後のレビューでコード注釈を使用して、この欠陥を正当化し非表示にできます。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処 (Polyspace ユーザー インターフェイスで結果をレビューする場合)。
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access) (Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
既定では、Polyspace は外部ソースからのデータは汚染されていると仮定します。Polyspace 解析での汚染のソースを参照してください。Polyspace 解析の現在のスコープ以外から発生したすべてのデータを汚染されたものと見なすには、コマンド ライン オプション [-consider-analysis-perimeter-as-trust-boundary] を使用します。
#include<stdlib.h>
void taintedptr(void) {
char *p = getenv("ARG");
char x = *(p+10);//Noncompliant //Noncompliant
}
この例では、ポインター *p が不明なサイズの文字列を指しています。デリファレンス操作中に、ポインターが null になったり、不明なメモリを指したりすることがあり、これがセグメンテーション違反につながる可能性があります。
1 つの修正方法として、ポインターを使用する前にサニタイズします。この例では、デリファレンスする前にポインターが nullptr かどうかをチェックします。
#include<stdlib.h>
#include <string.h>
void taintedptr(void) {
char *p = getenv("ARG");
if(p!=NULL && strlen(p)>10)
{
char x = *(p+10);
}
}
チェック情報
| カテゴリ: Pointer Issues |
バージョン履歴
R2023b で導入
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)