メインコンテンツ

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

putenv ファミリ関数の引数としての自動変数の使用

putenv ファミリ関数の引数はスコープ外からアクセスできない

説明

この欠陥は、putenv ファミリ関数の引数が自動持続期間をもつローカル変数である場合に発生します。

リスク

関数 putenv(char *string) は、引数のコピーを作成するのではなく、指定された引数を指すポインターを環境配列に挿入します。引数が自動変数の場合、putenv() 呼び出しを含む関数から値が返された後、メモリが上書きされる可能性があります。その後、別の関数が getenv() を呼び出した場合、適切にデリファレンスできないスコープ外の変数のアドレスが返されます。このスコープ外の変数は、環境変数が予期しない値を取る、プログラムが応答を停止する、任意のコード実行を可能にする脆弱性を生むなどの原因になる可能性があります。

修正方法

環境変数の設定/設定解除に setenv()/unsetenv() を使用します。または、putenv ファミリ関数の引数と動的に割り当てられたメモリを使用するか、アプリケーションに再入要件がない場合は引数と静的存続期間を使用します。たとえば、再帰や割り込みのないシングルスレッド実行には再入は必要ありません。実行中の呼び出し (再入) はできません。

すべて展開する

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

#define SIZE1024 1024

void func(int var)
{
    char env[SIZE1024];
    int retval = sprintf(env, "TEST=%s", var ? "1" : "0");
    if (retval <= 0) {
        /* Handle error */
    }
	/* Environment variable TEST is set using putenv().
	The argument passed to putenv is an automatic variable. */
    retval = putenv(env);   
    if (retval != 0) {
        /* Handle error */
    }
}
              

この例では、sprintf() は文字列 TEST=varenv に格納します。その後、環境変数 TEST の値が putenv() を使用して var に設定されます。env は自動変数であるので、TEST の値は func() が値を返すときに変化する可能性があります。

修正 — putenv() の引数に static 変数を使用

env を静的存続期間の変数として宣言します。env のメモリ位置は、func() が値を返した後でも、プログラムの存続期間中は上書きされません。

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

#define SIZE1024 1024 
void func(int var)
{
	/* static duration variable */
    static char env[SIZE1024]; 
    int retval = sprintf(env,"TEST=%s", var ? "1" : "0");
    if (retval <= 0) {
        /* Handle error */
    }
	
	/* Environment variable TEST is set using putenv() */
    retval=putenv(env);   
	if (retval != 0) {
        /* Handle error */
    }
}
修正 — setenv() を使用して環境変数値を設定

TEST の値を var に設定するために、setenv() を使用します。

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

#define SIZE1024 1024 

void func(int var)
{
	/* Environment variable TEST is set using setenv() */
    int retval = setenv("TEST", var ? "1" : "0", 1); 
	
    if (retval != 0) {
        /* Handle error */
    }
}

結果情報

グループ: 静的メモリ
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: PUTENV_AUTO_VAR
影響度: High

バージョン履歴

R2017b で導入