メインコンテンツ

FILE オブジェクトの不適切な使用

FILE オブジェクトのコピーの使用

説明

この欠陥は、以下の場合に発生します。

  • FILE オブジェクトへのポインターをデリファレンスする (memcmp() を使用した間接デリファレンスを含む)。

  • FILE オブジェクト全体またはコンポーネントの 1 つをポインターによって変更する。

  • fopen ファミリ関数の呼び出しから返されたのではない FILE オブジェクトのアドレスを取得する。#define ptr (&__stdout) などのようにマクロがポインターを組み込み FILE オブジェクトのアドレスとして定義している場合、欠陥は報告されません。

リスク

一部の実装では、ストリームの制御に使用される FILE オブジェクトへのポインターのアドレスが重要です。FILE オブジェクトのコピーを指すポインターは、元のオブジェクトを指すポインターとは異なった解釈をされます。また、誤ったストリームに対して操作を実行する可能性があります。したがって、FILE オブジェクトのコピーを使用すると、ソフトウェアが応答を停止する可能性があります。これを攻撃者がサービス拒否攻撃に悪用するおそれがあります。

修正方法

FILE オブジェクトのコピーを作成しないようにします。fopen ファミリ関数の正常な呼び出しから返されたのではない FILE オブジェクトのアドレスを使用しないようにします。

すべて展開する

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

void fatal_error(void);

int func(void)
{
	/*'stdout' dereferenced and contents
        copied to 'my_stdout'. */
    FILE my_stdout = *stdout;  
	
	/* Address of 'my_stdout' may not point to correct stream. */
    if (fputs("Hello, World!\n", &my_stdout) == EOF)  
    {
        /* Handler error */
        fatal_error();
    }
    return 0;
}
        
      

この例では、FILE オブジェクト stdout がデリファレンスされており、その内容が my_stdout にコピーされています。stdout の内容は重要ではない可能性があります。その後、fputs()my_stdout のアドレスを引数として使用して呼び出されます。fopen() や類似の関数の呼び出しは行われなかったので、my_stdout のアドレスは適切なストリームを指していない可能性があります。

修正 — FILE オブジェクトのポインターをコピー

stdout と同じアドレスを指すように my_stdout を宣言して、fputs() を呼び出したときに正しいストリームに書き込むようにします。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

void fatal_error(void);

int func(void)
{
	/* 'my_stdout' and 'stdout' point to the same object. */
    FILE *my_stdout = stdout;  
    if (fputs("Hello, World!\n", my_stdout) == EOF)
    {
        /* Handler error */
        fatal_error();
    }
    return 0;
} 

結果情報

グループ: プログラミング
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: FILE_OBJECT_MISUSE
影響度: Low

バージョン履歴

R2017b で導入