バグ : パスが決まっているファイルを開く

Posted: 2012年04月04日

パスが決まっているファイルを開くプログラムでよく書いてしまうバグを紹介します。
パスが決まっているファイルとは、
Windowsのファイル(cmd.exe等)や、設定ファイル(???.ini等)

プログラムプログラム:

 #include  <stdio.h>

 int main(int argc, char *argv[])
 {
    char *pstrFilePath = ".setting.ini";
    std::ifstream istream(pstrFilePath, std::ios::in);
    if (istream.fail() == true) {
        // ファイルのオープンに失敗
        return -1;
    }

    // 読み込み処理

    istream.close();

    return 0;
 }

このプログラムにどのようなファイル操作関連のバグがあると思いますか?

  • 実行ファイルからの相対パスで記述しているが、カレントフォルダからの相対パスで処理がされるため
     カレントフォルダが変更された場合、違うファイルを処理してしまう

今回のサンプルコードとは使用する関数が違いますが
以前にはこのバグで以下の脆弱性が存在しました。
http://jvn.jp/cert/JVNVU707943/

改善版プログラム改善版プログラム:

 #include <fstream>

 int main(int argc, char *argv[])
 {
    char strPath[MAX_PATH+1];
    // 実行ファイルパスの取得
    if(GetModuleFileName( NULL, strPath, MAX_PATH ) == 0){
        // 取得エラー
        return -1;
    }
    char strDrive[_MAX_DRIVE+1]
    char strDir[_MAX_DIR+1]

    // パスをそれぞれの要素に分解します。
    _splitpath(strPath,strDrive, strDir, NULL, NULL);

    char strFilePath[MAX_PATH+1];
    strcat(strFilePath, strDrive);
    strcat(strFilePath, strDir);
    strcat(strFilePath, "setting.ini");

    std::ifstream ostream(strFilePath, std::ios::in);
    if (istream.fail() == true) {
        // ファイルのオープンに失敗
        return -1;
    }

    // 読み込み処理

    istream.close();

    return 0;
 }

解説解説:

GetModuleFileName関数は
実行ファイルパスを取得します。
この関数の詳細は、 http://msdn.microsoft.com/ja-jp/library/cc429127.aspx を参照してください。
取得できるパスは、 実行ファイル(exe)のファイルが 「C:WindowsSystem32cmd.exe」の場合
「C:WindowsSystem32cmd.exe」が取得できます。

_splitpathe関数は
パスをそれぞれの要素に分解します。
この関数の詳細は、 http://msdn.microsoft.com/ja-jp/library/e737s6tf.aspx を参照してください。
この関数は、ドライブ名、フォルダパス、ファイル名、拡張子に分割することができます。
取得する必要がない要素は、引数にNULLを入れることで取得せずにすみます。

カテゴリー: バグ, プログラム | タグ: , , , | コメント無し »

コメント