メインコンテンツ

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

CERT C: Rule POS34-C

引数として自動変数を指すポインターを使用して putenv() を呼び出さない

説明

ルール定義

引数として自動変数を指すポインターを使用して putenv() を呼び出さないようにします。1

Polyspace 実装

ルール チェッカーは、"putenv ファミリ関数の引数としての自動変数の使用" をチェックします。

すべて展開する

問題

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

リスク

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

修正方法

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

例 - 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);    //Noncompliant
    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 */
    }
}

チェック情報

グループ: Rule 50.POSIX (POS)

バージョン履歴

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.