メインコンテンツ

CERT C: Rule FIO38-C

FILE オブジェクトをコピーしない

説明

ルール定義

FILE オブジェクトをコピーしないようにします。1

Polyspace 実装

ルール チェッカーは、"FILE オブジェクトの不適切な使用" をチェックします。

すべて展開する

問題

FILE オブジェクトの不適切な使用は、以下の場合に発生します。

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

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

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

リスク

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

修正方法

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

例 - fputs() における 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;   //Noncompliant
	
	/* Address of 'my_stdout' may not point to correct stream. */
    if (fputs("Hello, World!\n", &my_stdout) == EOF)   //Noncompliant
    {
        /* 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;
} 

チェック情報

グループ: Rule 09.入出力 (FIO)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.