メインコンテンツ

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

再呼び出し不可能な標準関数から返された内部バッファーが変更されています

再呼び出し不可能な標準関数から返された内部バッファーが関数により変更されようとしている

説明

この欠陥は、以下のタイミングで発生します。

  • 再呼び出し不可能な標準関数がポインターを返す。

  • ポインターが指すメモリ位置に書き込みを試みている。

const 修飾子付きでない内部バッファーへのポインターを返す再呼び出し不可能な標準関数には、getenvgetlogincryptsetlocalelocaleconvstrerror などがあります。

リスク

再呼び出し不可能な標準関数が返す内部バッファーの変更は、次の問題の原因となることがあります。

  • 変更が正常に終了しないか、他の内部データが変更される可能性がある。

    たとえば、getenv は環境変数値を指すポインターを返します。この値を変更すると、プロセスの環境が変更され、他の内部データが破損します。

  • 変更が正常に終了した場合でも、同じ標準関数をその後呼び出すと、変更された値が返されない可能性がある。

    たとえば、getenv によって返された環境変数の値が変更されたとします。別のプロセス、スレッドまたは信号ハンドラーが setenv を呼び出すと、変更された値は上書きされます。したがって、getenv をその後呼び出しても、変更された値は返されません。

修正方法

関数から返されるポインターを使用した内部バッファーの変更を回避します。

すべて展開する

#include <stdlib.h>
#include <string.h>

void printstr(const char*);

void func() {
    char* env = getenv("LANGUAGE");
    if (env != NULL) {
        strncpy(env, "C", 1);
        printstr(env);
    }
}

この例では、strncpy の最初の引数は、再呼び出し不可能な標準関数 getenv からの戻り値です。この引数が strncpy で変更されるため、動作は未定義となることがあります。

修正 - getenv の戻り値をコピーして、コピーを変更

1 つの解決策として、getenv の戻り値をコピーし、そのコピーを関数 strncpy に渡すことができます。

#include <stdlib.h>
#include <string.h>
enum {
    SIZE20 = 20
};

void printstr(const char*);

void func() {
    char* env = getenv("LANGUAGE");
    if (env != NULL) {
        char env_cp[SIZE20];
        strncpy(env_cp, env, SIZE20);  
        strncpy(env_cp, "C", 1);        
        printstr(env_cp);
    }
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: オフ
コマンド ライン構文: WRITE_INTERNAL_BUFFER_RETURNED_FROM_STD_FUNC
影響度: Low

バージョン履歴

R2015b で導入