メインコンテンツ

不確定文字列の使用

fgets ファミリ関数の未検証バッファーの使用

説明

この欠陥が発生するのは、下記に示すような fgets ファミリ関数を使用した書き込み操作が成功したかどうかをチェックせず、

char * fgets(char* buf, int n, FILE *stream)
書き込まれたバッファーに有効なコンテンツがあるかどうかをチェックしない場合、または失敗時にバッファーをリセットしない場合です。その後、バッファーに有効な内容が含まれていることを前提とする操作を実行します。たとえば、(上記に示すように) 不確定な内容が含まれている可能性があるバッファーが buf である場合、チェッカーは以下の場合に欠陥を報告します。

  • 文字列やワイド文字列を表示または操作する標準関数の引数として buf を渡す。

  • 関数から buf を返す。

  • パラメーターの型として const char * または const wchar_t * を使用する外部関数の引数として buf を渡す。

  • bufbuf[index] または *(buf + offset) として読み取る (ここで index または offset は、バッファーの先頭からの距離を表す数値です)。

リスク

fgets ファミリ関数が失敗した場合、出力バッファーの内容は不確定になります。このようなバッファーの使用には未定義の動作があり、プログラムによる処理の停止、他のセキュリティの脆弱性発生の原因になる可能性があります。

修正方法

fgets ファミリ関数が失敗した場合、関数の出力バッファーを既知の文字列値にリセットします。

すべて展開する

#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>

#define SIZE20 20

extern void display_text(const char *txt);

void func(void) {
    char buf[SIZE20];
	
	/* Check fgets() error */
    if (fgets (buf, sizeof (buf), stdin) == NULL)
    {
        /* 'buf' may contain an indeterminate string.  */
        ;
    }
	/* 'buf passed to external function */
    display_text(buf); 
}
        
      

この例では、出力 buf が外部関数 display_text() に渡されますが、fgets() が失敗しても出力値がリセットされません。

修正 — 失敗時に fgets() の出力をリセット

fgets() が失敗した場合、外部関数に渡す前に buf を既知の値にリセットします。

#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>

#define SIZE20 20

extern void display_text(const char *txt);

void func1(void) {
    char buf[SIZE20];
	/* Check fgets() error */
    if (fgets (buf, sizeof (buf), stdin) == NULL)
    {
		/* value of 'buf' reset after fgets() failure. */
        buf[0] = '\0';
    }
	/* 'buf' passed to external function */
    display_text(buf); 
} 

結果情報

グループ: プログラミング
言語: C | C++
既定値: オフ
コマンド ライン構文: INDETERMINATE_STRING
影響度: Medium

バージョン履歴

R2017b で導入