メインコンテンツ

CWE Rule 67

Improper Handling of Windows Device Names

R2024a 以降

説明

ルールの説明

The product constructs pathnames from user input, but it does not handle or incorrectly handles a pathname containing a Windows device name such as AUX or CON.This typically leads to denial of service or an information exposure when the application attempts to process the pathname as a regular file.

Polyspace 実装

ルール チェッカーは、"デバイス ファイルの 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 */
} 

チェック情報

カテゴリ: その他

バージョン履歴

R2024a で導入