メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C++: FIO32-C

Do not perform operations on devices that are only appropriate for files

説明

ルール定義

ファイルに対してのみ適切な操作をデバイスに実行しないようにします。1

Polyspace 実装

ルール チェッカーは、"デバイス ファイルの I/O 動作が不適切です" をチェックします。

すべて展開する

問題

デバイス ファイルの I/O 動作が不適切ですは、ファイル名パラメーターを以下の関数に渡す前に、そのファイル名パラメーターでデバイス ファイルが参照されるかどうかをチェックしていない場合に発生します。

  • fopen()

  • fopen_s()

  • freopen()

  • remove()

  • rename()

  • CreateFile()

  • CreateFileA()

  • CreateFileW()

  • _wfopen()

  • _wfopen_s()

デバイス ファイルは、デバイス ドライバーにインターフェイスを提供するファイル システムのファイルです。これらのファイルを使用してデバイスを操作することができます。

デバイス ファイルの I/O 動作が不適切ですは、以下の場合には欠陥を報告しません。

  • 上記にリストした関数を呼び出す前に、stat または lstat ファミリ関数を使用してファイル名パラメーターをチェックしている。

  • 文字列比較関数を使用して、ファイル名をデバイス ファイル名のリストに対して比較している。

リスク

通常のファイルに対してのみ適切な操作をデバイス ファイルに対して実行すると、サービス拒否攻撃、その他のセキュリティ脆弱性、またはシステム障害の原因になる可能性があります。

修正方法

ファイルに対して I/O 操作を実行する前に、以下を行います。

  • stat()lstat()、または同等の関数を使用して、ファイル名パラメーターが通常のファイルを参照しているかどうかをチェックする。

  • 文字列比較関数を使用して、ファイル名をデバイス ファイル名のリストに対して比較する。

例 - file_name のチェックなしでの fopen() の使用
#include <stdio.h>
#include <string.h>

#define SIZE1024 1024

FILE* func()
{

    FILE* f;
    const char file_name[SIZE1024] = "./tmp/file";
    
    if ((f = fopen(file_name, "w")) == NULL) { //Noncompliant
        /*handle error */
    };
    /*operate on file */
}

この例では、func() はファイル file_name に対して実行されますが、それが通常のファイルかどうかはチェックされません。file_name がデバイス ファイルである場合、アクセスを試みるとシステム障害が発生する可能性があります。

修正 — fopen() を呼び出す前に lstat() を使用してファイルをチェック

1 つの修正方法として、lstat()S_ISREG マクロを使用してファイルが通常のファイルなのかどうかをチェックします。この解決策は TOCTOU 競合状態を含みます。これによって、fopen() の呼び出し前に、ユーザーによってチェック済みのファイルが攻撃者によって改変される可能性があります。この脆弱性を防ぐために、file_name が安全なフォルダー内のファイルを参照することを確認してください。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#define SIZE1024 1024

FILE* func()
{

    FILE* f;
    const char file_name[SIZE1024] = "./tmp/file";
    struct stat orig_st;
    if ((lstat(file_name, &orig_st) != 0) ||
        (!S_ISREG(orig_st.st_mode))) {
        exit(0);
    }
    if ((f = fopen(file_name, "w")) == NULL) {
        /*handle error */
    };
    /*operate on file */
} 

チェック情報

グループ: 07.入出力 (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.